您是否根据用户界面部件构建了源代码?例如,如果您的UI包含:
,然后按以下方式或多或少地命名和分组变量和函数:
class Application
{
string PropertiesPanel_dataFile;
DataSet PropertiesPanel_dataSet;
string[] PropertiesPanel_dataIdColumn;
void PropertiesPanel_OpenXml();
void PropertiesPanel_UpdateGridView();
string ThreeDView_modelFile;
Panel ThreeDView_panel;
PointF[] ThreeDView_objectLocations;
void ThreeDView_RenderView();
string ToolPanel_configurationFile;
Button[] ToolPanel_buttons;
void ToolPanel_CreateButtons();
}
您对此有何看法?这个架构可以长期运作吗?
PS。即使这个解决方案可能会让你想起前面设计愚人节的笑话http://thedailywtf.com/Articles/FrontAhead-Design.aspx我的问题是严肃的。
修改
现在已经维护和扩展这种代码半年了。应用程序已经扩展到主.cs文件中的超过3000行,并且大约2000行扩展到较小的文件(包含通用的辅助函数和类)。代码的许多部分应该被概括并从主文件中取出,我一直在努力,但最终它并不重要。代码的结构和细分非常简单,通过它很容易导航。由于UI包含少于7个主要组件,因此将整个设计立即安装在您的头上是没有问题的。回到这段代码(经过一段时间的休息)并立即知道从哪里开始,这总是令人愉快的。
我猜这个巨大的程序式结构在我的案例中起作用的原因之一是c#中UI编程的事件性质。在大多数情况下,所有这些代码都是实现不同类型的事件,这些事件确实特定于此项目。尽管一些事件函数会立即变成几页长怪物,但事件处理程序之间的耦合并不紧密,因此以后更容易重构和压缩它们。这就是为什么当其他项目开始需要与该项目使用的实现相同的部分时,Iam故意留下泛化和重构。
PS可以浏览3000行代码,我在visual studio中使用FindNextSelection-和FindPrevSelection-macros。左键单击某个变量后,我按F4跳转到它的下一个实例,F2到前一个实例。也可以选择变量名称的某些部分并在部分名称匹配之间跳转。如果没有这些捷径,我很久以前就会失去理智:)
答案 0 :(得分:1)
这在概念上看起来非常程序化,完全绕过了OOD的价值。明智的做法是为每个元素创建对象,并且您给出的值将是这些对象的属性,即
class PropertiesPanel
{
public string DataFile { get; set; }
public DataSet DataSet { get; set; }
public string[] DataIDColumn { get; set; }
etc...
我认为你得到了这个想法,所以我不打算输出所有的东西。这是第一阶段,您可以做进一步的工作来适当地构建您的应用程序。
我收到的OOD最好的建议是查看应用程序的每个逻辑分支可以被提取到的最小对象,它可能具有属性的本机类型(使用.NET,重新发明Framework对象没有意义)所以它们可以在你的基类中)然后使用继承,多态和封装来扩展这些基类,直到你有一个封装逻辑分支的对象。
当时我正在编写一个将数据推送到I2C设备的应用程序,所以我开始使用一个类,它将一个位放在一个I2C总线上,该类由一个将字节放入总线的类继承,由一个继承将一个字节数组放到总线上的类,最后是一个放置地址和字节数组的类。这是相当极端的OOD,但它产生了非常干净的代码,每个类都非常小并且非常容易调试。
在思考这个问题时可能会有更多的工作,但从长远来看,它可以节省太多时间,但这并不好笑。
答案 1 :(得分:0)
可以根据UI部分构建用户界面代码,但程序的非UI相关逻辑应该保持独立。
但是在UI部分的事件中,你不应该把所有东西都粉碎成一个类。相反,你应该将你的UI代码分成几个类,这样每个类只处理一个UI组件,而不处理它不需要知道的其他类:
class Application { PropertiesPanel ThreeDView ToolPanel } class PropertiesPanel { string dataFile; DataSet dataSet; string[] dataIdColumn; void OpenXml(); void UpdateGridView(); } class ThreeDView { string modelFile; Panel panel; PointF[] objectLocations; void RenderView(); } class ToolPanel { string configurationFile; Button[] buttons; void CreateButtons(); }
答案 2 :(得分:0)
您对此有何看法?
这是一团糟。
这种架构能否长期运作? 运行
没有。 (至少没有大量的汗水。)
这些名字非常冗长。如果您考虑一下,长名称前缀就会创建一种独立的“命名空间”,将相关的事物组合在一起。对于这种类型的东西,已经有了更好的语言构造 - 它是类。但主要问题在于其他地方。
用户界面经常变化,概念很少变化。如果您的代码结构镜像用户界面,则会锁定此特定界面。这使得重用和重构代码非常困难。如果围绕问题域的基本概念构建代码,则在软件开发时,您有更好的机会重用已有的代码 - 设计将适应变化。 更改总是发生在软件中。
(我希望“问题领域的基本概念”部分是清楚的。例如,如果您为本地影院创建系统,您应该将您的设计基于电影,访客,席位和所以,而不是围绕MovieList,SeatMap,TheaterPlan等构建它。)
大多数情况下,尽可能将核心代码与GUI分离是个好主意(这正是Model–View–Controller设计系统的全部内容。)这不是学术练习,也不是只有在界面要改变时才需要它。将GUI与其余代码分离的一个很好的例子是Mac OS X上的GUI编程,界面设计器,绑定等。不幸的是,它需要一段时间才能进入,你不能简单地浏览网络上的文档并开悟。