Bad OO设计问题 - 我需要Java中的一些通用功能,但不知道如何实现它

时间:2008-09-24 04:47:56

标签: oop interface uml

我正在使用Java开发一个小型UML类编辑器,主要是个人项目,如果我找到时间在其上创建一个项目,它可能会最终出现在SourceForge上。

该项目非常先进:我可以创建类,移动它们,创建接口,创建链接等。

我正在处理的是用于设置类/接口属性和创建新类/接口的对话框。

例如,我有一个扩展JDialog的类。这是编辑类和接口的主要“窗口”(好吧,每个都有一个类)。它包含一个JTabbedPane,后者又包含JPanel。

这个JPanel实际上是自定义的。我创建了一个扩展JPanel的抽象类。该类使用组件(由其子类定义)并将其值添加到JTable(也包含在JPanel中)。

例如,如果我想编辑类的属性,JPanel将包含一个JTextField用于输入属性的名称以及另一个用于输入其类型的属性。还有一组按钮用于处理在这些字段中输入的数据。当我单击“保存”时,我在JTextFields中输入的数据被添加到JTable(àlaEnterprise Architect)中。扩展抽象类的具体类负责定义控制并决定在从JTable添加或删除行时如何处理数据。但是,JTable管理是抽象类的责任。

这是我的问题:在OO中,类有方法,接口也有方法。我告诉自己:我可以使用相同的具体自定义JPanel(AttributesPanel(扩展我创建的抽象JPanel类))来存储类或接口的方法。

但是,该类需要保留我正在处理的类或接口的副本(作为属性)。这样,当一个方法添加到它时,我可以调用editedClass.addMethod()(或editedInterface.addMethod())。问题是我无法判断我是在Class还是Interface上工作。

我发现的解决方案很难看:在AttributesPanel类中保留属性editedClass和属性editedInterface。根据我是在编辑类还是接口,其中一个属性将为null,而其他属性则不为。

如果你问我,这很难看。事实上,我可以听到我的软件工程老师在第九个地狱圈内燃烧(好吧,实际上是冷冻)时,在痛苦中尖叫着。

解决此设计问题的快速方法是创建一个名为“ObjectWithMethods”的接口,我的类和接口类将实现该接口。这样,我只需要在AttributesPanel类中放置一个ObjectWithMethods参数。

但这是否意味着我应该创建一个名为“ObjectWithAttributes”或“ObjectWithBlahBlah”的类?我在这里看到一些好的“TheDailyWTF”潜力...此外,我认为我不应该修改我的域对象(类,接口,注释,关系(对于我的UML编辑器))或者为了这个目的而创建一个新的接口一些用户界面考虑......

您怎么看?

我需要更多的澄清(因为我现在非常疲倦而且我倾向于非常糟糕(尤其是英语 - 我的母语是法语),而在这种心态......),只是问我,我我会编辑这个问题。

干杯,

纪尧姆。

3 个答案:

答案 0 :(得分:3)

当我阅读您的问题时,您似乎正在描述使用visitor pattern的地方。

访问者模式应该在这里工作的原因是一种称为双重调度的想法。您的UI代码将进行调用并将引用传递给自身,然后类或接口最终调用原始调用者。由于类或接口是进行方法调用的类,因此它知道自己的类型以及如何执行特定于其类型的工作。

当然,我的描述不足以实现这种技术,因此您需要阅读它。我认为这是有据可查的。例如,我在java中发现了这个问题,可以让你开始:http://www.javaworld.com/javaworld/javatips/jw-javatip98.html

答案 1 :(得分:0)

通常,我只是做了最简单的事情,并开始考虑分解接口,当我开始在我的代码中看到太多if( .. instanceof ..) - 类似的构造。现代IDE代码重构功能不会让我付出太多代价。

在您的具体情况下,我会考虑实现UML specification中提供的图表,因为他们非常友好地使用UML符号来指定UML!

答案 2 :(得分:0)

你有一个申请。在那个应用程序。你代表并编辑一些数据。

该数据代表编程语言类或编程语言接口。

当您为某些数据创建编辑器时,有时您必须添加其他/补充信息,例如,每个类图表可能具有不同的线条颜色,并且与您的属性或方法无关。类。

表示您正在编辑类或接口的字段或属性也是如此。

我建议做一些事情。

将代表的数据与程序的代码或逻辑分开:

如果你有类似的东西:

// 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

干杯。