3

There is an object which is very complicated to build and many algorithms needed to figure out how it should be created (for your curiosity it is an object that represents and draws the beaming of notes in music notation).

The object has a rats nest of internal logic which I want to, at least partially, externalize in some sort of builder object.

However I found that the builder object needed too much access to the internals of the object it is constructing. So I came up with a different approach. The 'builder' object will instead be a representation of the complex real-world thing that the 'constructed' object will represent, but the 'constructed' object will still build itself taking the 'builder' object as input to the constructor.

I don't think this is exactly a GOF Builder Pattern. Is there a design pattern which more closely matches my proposal? I would like to search on it if there is.

In case the above description isn't clear, here is snippet that shows what I mean.

class ComplexBuildingInstructionsIntf
{
public:
    virtual ~ComplexBuildingInstructionsIntf() {}
    virtual int getLots() const = 0;
    virtual int getComplicated() const = 0;
    virtual int getStuff() const = 0;
};

class ComplexObject
{
    ComplexObject(const ComplexBuildingInstructionsIntf& inInstructions);
};
  • 1
    This is called "Joshua Bloch's Builder pattern", see rwhansen.blogspot.de/2007/07/… – Doc Brown Nov 15 '16 at 17:02
  • 1
    @DocBrown Actually no. What the op calls a 'builder object' is the parameter object pattern. – candied_orange Nov 15 '16 at 17:28
  • 1
    @CandiedOrange: ok, "Joshua Bloch's Builder pattern" is surely not an official pattern name, but the core idea described in that article is the same. – Doc Brown Nov 15 '16 at 19:51
  • 3
    @DocBrown "Joshua Bloch's Builder Pattern is official enough for me. Call it the Builder Pattern in Effective Java if you like. That builder might solve the problem the OP presented. But the OP wasn't asking for just any solution that would work. He was asking: "Is there a design pattern which more closely matches my proposal?" His proposal is a self building parameter object. – candied_orange Nov 16 '16 at 2:48
1

The builder may not be what you think

The builder pattern is IMHO one of the least understood GoF patterns and there is a lot of confusion about it out there. To make it worth, another pattern is also called a builder, and has nothing to do (except its name) with the GoF builder.

The intent of the GoF builder is:

separate the construction of complex objects from its representation, so that the same construction process can create different representations.

So the GoF builder, by design, cannot know about the internals of the constructed object:

  • It shall only know the general construction process, i.e. what (abstract) parts it needs and how to assemble them, but nothing about their internals.
  • Specialisations of the builder allow to apply the same general building process, based on the same input, to build completely different representations (i.e. concrete classes). So you could have a ComplexObjectBuilder, and then implement a SecializedComplexObjectBuilder if needed to.
  • A concrete builder shall know the concrete type of the objects in that process, but it should still use their public interface.

Your pattern

Your pattern uses requires the complex object to build itself. It gets access to the data it needs via the building instructions:

  • It is similar to the GoF builder in that the ComplexBuildingInstructionInterface is related to the construction steps. The constructor of the ComplexObject is dependent on this interface, but this is not a problem, since it's a dependency on an abstraction.
  • It is similar to the Joshua Bloch's builder, in that it encapsulates in one object all the elements that ComplexObject's constructor needs to know. However your pattern is more flexible, since it's not just a bag of concrete properties, but it's an abstraction.
  • It could have something in common with the adapter pattern, since it helps to adapt the ComplexObject construction process to the real world. Different specialisation of the "instructions" could for example use different sources of data.

This appears an acceptable approach. There are however some limitations with your design:

  • There might be a hidden coupling between ComplexObject and the BuildingInstruction from a design perspective
  • For instance, the BuildingInstructions cannot evolve as they want: the constructor will not be able to read new extended instructions but would be hard-wired to use the known instructions and existing data structures. This limits flexibility and evolution.
  • As another case, suppose you'd have a SpecialisedComplexObject derived from ComplexObject, that would use SpecializedPart: would you keep the same BuildingInstructions interface, but rewrite the constructor ? Or would you go for a SpecializedBuidlingInstruction decorator to add additional responsibilities, and rewrite part of the constructor?
  • In other words, while you could reuse the building instructions as a source of information, you cannot reuse the generic construction process.

For all these reasons I'd still advise to consider the GoF builder.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.