3

I can't figure out how to avoid parallel hierarchies in practice. e.g. Consider an application which has to create/save/edit notes on different levels, it's a java swing based application.

Domain Hierarchy:

AbstractNote < MonthNote
             < DayNote
             < ProductNote

read only View Hierarchy(shown on JTabPane each having JTable to show the specific note details)

AbstractNotePanel < MonthNotePanel
                  < DayNotePanel
                  < ProductNotePanel

notes editor hierarchy(shown when user clicks on on a particular note in a table row.

AbstractNoteEditorDialog  < MonthNoteEditorDialog
                          < DayNoteEditorDialog
                          < ProductNoteEditorDialog  

I read one way to avoid this is to use Visitor Pattern.here But this doesn't seem to be applicable to my situation.

I'm quite happy with my above design as most of the common code is in abstract class(applying template method pattern there). In case if I have to create a new type of note e.g. YearNote then I have to create YearNotePanel and YearNoteEditorDialog in parallel which is quite acceptable for me cause I don't have to code a lot due to templating. Above all I want to avoid code smell in my design. Please suggest me alternate design in above scenario so that my code would be still modular. Thanks

Community
  • 1
  • 1
Joe
  • 140
  • 1
  • 1
  • 9
  • Starting from begin what is the difference between MonthNote, DayNote and ProductNote ? – Damian Leszczyński - Vash Aug 26 '13 at 11:57
  • They are little different from each other and might be VERY different in future. Each note is bound to a user and has a long text. MonthNOte and DayNote have joda MonthYear and LocalDAte respectively. Product note has no date info instead it has Product instance(another domain object), we just show name of the product on ui. – Joe Aug 26 '13 at 23:51
  • get rid off them by **not** extending JSomething, ever - they are meant to be used as-are – kleopatra Aug 30 '13 at 08:18

2 Answers2

1

Saying "above all I want to avoid code smell in my design" is a commendable goal but always keep in mind that the core of design is to weigh costs.

In my applications, I usually have model classes and configuration. Configuration can be in the model (annotations, introspection methods) or as extra files.

The UI layer reads this config and then build the UI from it. That means my design looks like this:

AbstractNote < MonthNote
             < DayNote
             < ProductNote

NotePanel
NoteEditorDialog

This often works because the dialogs and panels are pretty generic. Of course, my generic UI layer is pretty complex because it has to handle each corner case. So while this may look like a much better design than yours if you just look at the number of files or the inheritance hierarchy, the code inside of my UI layer is much, much more complex than yours.

Additionally, if I add a feature / fix a bug in the UI layer, chances are much higher that I break something elsewhere (so a change in the code to make editing DayNote more comfortable can break MonthNote).

So unless you feel that you have a lot of code duplication that you could avoid easily or maintenance costs are high or you just have a few model types (and not 500), there is nothing wrong with your design as such.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • Thanks Aaron for your response and I'm agreed with balancing contradicting goals for cost effectiveness and easy maintainance. A generic NotePanel and NoteEditorDialog based on something like annotation configuration might introduce switch statement code smell or cyclomatic complexity which will be very difficult to maintain. Please correct me if I'm wrong. I would prefer polymorphism instead. – Joe Aug 26 '13 at 23:39
  • I'm not using switch statements. My UI is a grid. While I read the config, I create different editor elements and each editor knows what to do without any switches. The config loaded then puts an editor in each grid cell (some editors are just labels). – Aaron Digulla Aug 27 '13 at 08:08
0

An important API you can use here is the BeanInfo API. Get acquainted with it. On any java class (bean) you can define a meta-level BeanInfo class.

One usage is that in this way you might make a new Swing component, and in the IDE using the BeanInfo provide a table component properties. (In the NetBeans IDE you can add your own components to the component palettes, and operate in this way.) This goes with property editors (for picking a color / data / .. ).

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • Thanks Joop. Frankly I never used BeanInfo API. Also I always want my solutions not tied to any IDE. Is there a way to use BeanInfo without any IDE? – Joe Aug 26 '13 at 23:58
  • BeanInfo is a standard describing properties of "beans", classes. As such it was i.a. intended for and adopted by several IDEs. But it is quite independent of any use case. In your case a generic description of fields might be easier. Though by annotations, though by XML, ... or BeanInfo. – Joop Eggen Aug 28 '13 at 09:21