2

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

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

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

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

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

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

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

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

我找到的解决方案很丑:在 AttributesPanel 类中保留一个属性editedClass 和一个属性editedInterface。根据我是在编辑类还是接口,其中一个属性将为空,而另一个则不会。

如果你问我,这很丑陋。事实上,我可以听到我的软件工程老师在地狱的第九圈燃烧(实际上,冻结)时痛苦地尖叫。

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

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

你怎么看?

我你需要更多的澄清(因为我现在很累,而且在这种心态下我往往做得很糟糕(尤其是英语 - 我的母语是法语)......),请问我会编辑这个问题。

干杯,

纪尧姆。

4

3 回答 3

3

当我阅读您的问题时,您似乎真的在描述一个使用访问者模式的地方。

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

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

于 2008-09-24T05:01:23.043 回答
0

if( .. instanceof ..)通常,当我开始在我的代码中看到太多类似结构时,我只会做最直接的事情,并开始考虑分解接口。使用现代 IDE 代码重构功能并不会花费我太多。

在您的特定情况下,我会考虑实现UML 规范中提供的图表,因为它们非常友好地使用 UML 表示法指定 UML!

于 2011-07-01T14:07:47.027 回答
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

干杯。

于 2011-07-01T17:03:52.803 回答