Bad OO设计问题 - 我需要Java中的一些通用功能,但不知道如何实现它
题
我正在使用Java开发一个小型UML类编辑器,主要是个人项目,如果我找到时间在其上创建一个项目,它可能会最终出现在SourceForge上。
该项目非常先进:我可以创建类,移动它们,创建接口,创建链接等。
我正在处理的是用于设置类/接口属性和创建新类/接口的对话框。
例如,我有一个扩展JDialog的类。这是主要的“窗口”。用于编辑类和接口(好吧,每个都有一个类)。它包含一个JTabbedPane,后者又包含JPanel。
这个JPanel实际上是自定义的。我创建了一个扩展JPanel的抽象类。该类使用组件(由其子类定义)并将其值添加到JTable(也包含在JPanel中)。
例如,如果我想编辑类的属性,JPanel将包含一个JTextField用于输入属性的名称以及另一个用于输入其类型的属性。还有一组按钮用于处理在这些字段中输入的数据。当我单击“保存”时,我在JTextField中输入的数据被添加到JTable(à la Enterprise Architect)中。扩展抽象类的具体类负责定义控制并决定在从JTable添加或删除行时如何处理数据。但是,JTable管理是抽象类的责任。
这是我的问题:在OO中,类有方法,接口也有方法。我告诉自己:我可以使用相同的具体自定义JPanel(AttributesPanel(扩展我创建的抽象JPanel类))来存储类或接口的方法。
但是,该类需要保留我正在处理的类或接口的副本(作为属性)。这样,当一个方法添加到它时,我可以调用editedClass.addMethod()(或editedInterface.addMethod())。问题是我无法判断我是在Class还是Interface上工作。
我发现的解决方案很难看:在AttributesPanel类中保留属性editedClass和属性editedInterface。根据我是在编辑类还是接口,其中一个属性将为null,而其他属性则不为。
如果你问我,这很难看。事实上,我可以听到我的软件工程老师在第九个地狱圈内燃烧(好吧,实际上是冷冻)时,在痛苦中尖叫着。
解决此设计问题的快速方法是创建一个名为“ObjectWithMethods”的接口,我的类和接口类将实现该接口。这样,我只需要在AttributesPanel类中放置一个ObjectWithMethods参数。
但这是否意味着我应该创建一个名为“ObjectWithAttributes”或“ObjectWithBlahBlah”的类。 ?我看到一些好的“TheDailyWTF”潜在的...此外,我不认为我应该修改我的域对象(类,接口,注释,关系(对于我的UML编辑器))或创建一个新的接口只是为了一些UI考虑...
您怎么看?
我需要更多的澄清(因为我现在非常疲倦而且我倾向于非常糟糕(尤其是英语 - 我的母语是法语),而在这种心态......),只是问我,我我会编辑这个问题。
干杯,
纪尧姆。
解决方案
当我阅读您的问题时,您似乎正在描述一个使用访客模式的地方一>
访问者模式应该在这里工作的原因是一种称为双重调度的想法。您的UI代码将进行调用并将引用传递给自身,然后类或接口最终调用原始调用者。由于类或接口是进行方法调用的类,因此它知道自己的类型以及如何执行特定于其类型的工作。
当然,我的描述不足以实现这种技术,因此您需要阅读它。我认为这是有据可查的。例如,我在Java中发现这个问题大约需要2秒才能开始: http://www.javaworld.com/javaworld/javatips/jw-javatip98.html
其他提示
通常,我只是做最直接的事情,并开始考虑分解接口,当我开始在我的代码中看到太多 if(.. instanceof ..)
-like构造时。现代IDE代码重构功能不会让我付出太多代价。
在您的具体情况下,我会考虑实施 UML规范中提供的图表,因为它们是非常友好地使用UML-notation来指定UML!
你有一个申请。在那个应用程序。你代表并编辑一些数据。
该数据代表编程语言类或编程语言接口。
当您为某些数据创建编辑器时,有时您必须添加其他/补充信息,例如,每个类图表可能具有不同的线条颜色,并且与您的属性或方法无关。类。
表示您正在编辑类或接口的字段或属性也是如此。
我建议做一些事情。
将代表的数据与程序的代码或逻辑分开:
如果你有类似的东西:
// all code, classes, mixed up
public class JCustomPanel: {
protected ChartClass Charts;
protected ArrayList<String> MyClassAttributes;
protected ArrayList<String> MyClassMethods;
void PanelDoSomeThing();
void ClassDoSomeThing();
void InterfaceDoSomeThing();
// ...
} // class JCustomPanel
更改为:
// things related to a single class or interface,
// nothing to do with the chart
public class JClassRepresentation: {
ArrayList<String> Attributes;
ArrayList<String> Methods;
bool IsInterface;
void ClassDoSomeThing();
void InterfaceDoSomeThing();
// ...
} // class JCustomPanel
// things related to the editor,
// contains the classes and interfaces,
// but, as separate stuff
public class JCustomPanel: {
ArrayList<JClassRepresentation> Classes;
int PagesCount;
void InterfaceDoSomeThing();
// ...
} // class JCustomPanel
干杯。