0

I am working on a piece of software designed to create a book like document. I have implemented it using using decorators to add various features. Here is an example of the initialization'

$this->chapter[i] = new ChapDecorator1(new ChapDecorator2(new Chapter(i)));

The challenge is that these decorators are hard coded and that there is the potential for many iterations of the sofware. Interesting changes made on new projects are often backported to the older ones (which isn't terrible now with decorators since all that is required is adding another decorator to the definition). However, this still requires me to edit the subclass code. The optimal situation being the actual content creators choosing what features they need without requiring a programmer to edit anything.

Clearly, the better thing to do in this case is for the Book to use an object implementing the Builder pattern to create the Chapter object and wrap it in the correct decorators for the project.

Finally, we arrive at my question which is how can I make the builder object handle the configuration order dynamically and correctly? The order in which decorators are wrapped with imply an order for how interface calls are resolved (LIFO). An example is that the document edit tracking is implemented as a decorator but for obvious reasons should always evaluate first to save state before changes are made (it should be the last wrapper). For future development assuming there will be many decorators, some which might need to resolve first should each decorator have something like a priority data member (integer?) which the Builder might sort on? It seems like a workable solution but I'm concerned that the implementation wouldn't be very robust if a large number of priority sensitive decorators/modules were created. Conflicting priorities might require renumbering many classes for example. Anyway, I would appreciate any thoughts people had on the matter.

The second issue is if two decorators change the same feature in some way. Should that situation even be possible? Should each decorator specify its domain and traverse the list of decorators looking for conflicts?

This is all assuming there will be many decorators and that some project editors will choose some but not others. Thanks!

Hath995
  • 821
  • 6
  • 12

1 Answers1

0

You can use a modified builder for this, where you return a different builder class for each invocation of a builder method, and that returned builder class only has a subset of all the methods to build the overall class.

This allows you to avoid having the same method called multiple times, and also allows you to control the overall build order. An example of this can be found here.

JRL
  • 76,767
  • 18
  • 98
  • 146
  • Thanks, i think that's a start but still not quite perfect for my situation. There are two issues redundancy and order. For the builder I'm primarily concerned with order. I can answer my question about which decorator will resolve first. The one last applied and then working inwards. That gives me an order but then how do get the builder to apply them in an order based on database settings without resorting to a static priority integer. The redundancy is with regards to the decorator. When an interface call is made on it should two decorators editing the same feature be allowed? – Hath995 Dec 20 '11 at 18:24
  • Sorry I think I didn't make that clear enough. I'll rephrase the question. – Hath995 Dec 20 '11 at 18:37