Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 并行继承层次结构真的是一种代码气味吗?_Java_Swing_Oop_Inheritance - Fatal编程技术网

Java 并行继承层次结构真的是一种代码气味吗?

Java 并行继承层次结构真的是一种代码气味吗?,java,swing,oop,inheritance,Java,Swing,Oop,Inheritance,我不知道如何在实践中避免并行层次结构。例如,考虑在不同级别上创建/保存/编辑注释的应用程序,它是基于java Swing的应用程序。 域层次结构: AbstractNote < MonthNote < DayNote < ProductNote AbstractNote

我不知道如何在实践中避免并行层次结构。例如,考虑在不同级别上创建/保存/编辑注释的应用程序,它是基于java Swing的应用程序。 域层次结构:

AbstractNote < MonthNote
             < DayNote
             < ProductNote
AbstractNote
只读视图层次结构(显示在JTabPane上,每个都有JTable以显示特定的注释详细信息)

AbstractNotePanel
注释编辑器层次结构(当用户单击表行中的特定注释时显示)

AbstractNoteEditorDialog  < MonthNoteEditorDialog
                          < DayNoteEditorDialog
                          < ProductNoteEditorDialog  
AbstractNoteEditorDialog
我读到一种避免这种情况的方法是使用访问者模式。 但这似乎不适用于我的情况

我对我的上述设计非常满意,因为大多数常见代码都在抽象类中(在抽象类中应用模板方法模式)。如果我必须创建一种新类型的便笺,例如Dreamote,那么我必须并行创建DreamotePanel和DreamoteEditorDialog,这对我来说是可以接受的,因为我不必由于模板化而编写太多代码。最重要的是,我希望在我的设计中避免代码味道。请建议我在上述场景中进行替代设计,以便我的代码能够被使用仍然是模块化的。 感谢您说“首先,我希望在设计中避免代码气味”,这是一个值得称赞的目标,但请始终记住这一点

在我的应用程序中,我通常有模型类和配置。配置可以在模型中(注释、内省方法)或作为额外文件

UI层读取此配置,然后从中构建UI。这意味着我的设计如下所示:

AbstractNote < MonthNote
             < DayNote
             < ProductNote

NotePanel
NoteEditorDialog
AbstractNote
这通常是有效的,因为对话框和面板是非常通用的。当然,我的通用UI层非常复杂,因为它必须处理每个角落的情况。因此,如果只看文件数量或继承层次结构,这看起来可能比你的设计好得多,但我的UI层中的代码要复杂得多x比你的多

此外,如果我在UI层中添加了一个功能/修复了一个bug,那么我在其他地方破坏某些东西的可能性就要大得多(因此更改代码以使编辑
DayNote
更舒适可以破坏
MonthNote


因此,除非您觉得有很多代码重复可以轻松避免,或者维护成本很高,或者您只有一些模型类型(而不是500),否则您的设计本身并没有问题。

这里可以使用的一个重要API是。熟悉它。在任何java类(bean)上您可以定义一个元级别的BeanInfo类


一种用法是,通过这种方式,您可以创建一个新的Swing组件,并在IDE中使用BeanInfo提供一个表组件属性。(在NetBeans IDE中,您可以将自己的组件添加到组件选项板中,并以这种方式操作。)这与属性编辑器(用于选择颜色/数据/)有关.

从开始,MonthNote、DayNote和ProductNote之间的区别是什么?它们彼此相差不大,将来可能会有很大的不同。每个便笺都绑定到一个用户并有一个长文本。MonthNote和DayNote分别有joda MonthYear和LocalDAte。Product note没有日期信息,而是有Product in实例(另一个域对象),我们只是在ui上显示产品名称。通过不扩展JSomething来摆脱它们,永远-它们是用来作为一个工具的。感谢Aaron的回复,我同意平衡成本效益和易于维护的矛盾目标。基于注释配置之类的通用记事本和记事本编辑器t引入开关语句代码气味或圈复杂度,这将很难维护。如果我错了,请纠正我。我更喜欢多态性。我不使用开关语句。我的UI是一个网格。当我阅读配置时,我创建了不同的编辑器元素,每个编辑器都知道在没有任何开关的情况下该怎么做g loaded然后在每个网格单元中放置一个编辑器(一些编辑器只是标签)。谢谢Joop。坦率地说,我从未使用过BeanInfo API。而且我总是希望我的解决方案不与任何IDE绑定。有没有一种方法可以在没有任何IDE的情况下使用BeanInfo?BeanInfo是描述“beans”属性的标准,类。因此,它是为几个IDE设计并被采用的。但它与任何用例都是完全独立的。在您的情况下,字段的通用描述可能更容易。通过注释,通过XML,…或BeanInfo。
AbstractNote < MonthNote
             < DayNote
             < ProductNote

NotePanel
NoteEditorDialog