views:

47

answers:

1

For a design patterns class, the instructor asked my team to develop an application that supports drawing and persisting glyphs, very similar to the WYSIWYG editor from GoF.

My team decided to use a Layered architecture, with descending layers: Presentation, Controller, Logic, Persistence.

The Logic maintains a collection of glyph representations, their respective positions, and some shape-unique properties. The instructor suggested we use the Builder pattern to create uniform persistence mechanism, as CSV and XML are required persistence formats.

The problem comes about when we attempt to design the Builder within the Persistence layer. Because we're using Layers, the Persistence layer is not permitted to know about Glyph types explicitly, let alone cast them from their abstract form to their individual shapes. This has me scratching my head as for what to even pass each Builder as its constructor.

The next problem is that its hard to generalize the types that the Builder takes. Rectangles have properties that Lines don't.

I'm having a lot of trouble grasping how to do this. I understand the Builder pattern, but something just isn't clicking. Am I misusing the pattern, or am I not fitting it to the problem correctly?

Edit: The instructor didn't say we have to load the persisted formats back in. My ending solution should obviously make this easy, but for my current problem, I'm only focused on saving.

+1  A: 

Not sure you need a Builder for this. Factories / Registries and serializability are probably more to the point.

The way you make the persistence layer ignorant of explicit glyph types, while still giving it the ability to save and load specific glyph instances, is through some sort of reflection mechanism. Either something built into the language (like Reflection in .Net, or RTTI in Delphi / C++ Builder), or something you handcraft yourself.

To handcraft a solution yourself you will need to have all glyph types descend from a common "serializable" base type or have them all implement a "serialize" interface. The persistence layer only needs to know about this base type or interface - whichever you choose.

Using an interface means the glyphs do not all need a common base type, using a common base type means you can implement common behaviour in that base type and avoid some duplication.

The "serializable" base type or interface should provide the persistence layer with the means to identify the glyph type by a unique (string) ID, the means to iterate over properties to be persisted / loaded; and the means to instantiate a glyph polymorfically (virtual constructors and meta classes in Delphi speak).

Getting the glyph type id and iterating over the properties to be persisted should be enough for saving instances.

Iterating over properties should be simple and straightforward, but if you want to "design patternize" this you could consider using a Visitor. Which might make life a lot simpler when composed and aggregate glyph's (Grouping in drawing applications) get into the picture, no pun intended :-). With regard to that, you could also consider having a look at the Composite pattern, though that may be overkill for what you have been asked to do.

To load glyphs from a persistent store, you will need a registry somewhere where glyph types are linked with a unique name (string) so the persistence layer can look up the type to instantiate from a string in the persisted information. Each glyph type will need to register itself in the registry so it can be found and instantiated by the persistence layer. Look up Factory Method and Abstract Factory pattern for more information on this.

Marjan Venema
I ended up going in a different direction, but this indeed helped a lot. Excellent post, and thank you!
Mike