In this lesson we're actually going to take a look at an implementation of builder that's far more complicated
because instead of just using one builder to actually work on an object we're going to be using two
builders.
So it's this idea of an object being so complicated that you need separate builders for different aspects
of that particular object.
So what we'll be building is something that one might call a builder facade and facade is yet another
design pattern that we have as part of this course.
So let's get started shall we.
I'm going to set up a very simple scenario so I'm going to have a Person class.
Here we go.
We're going to have a Person class and that person is going to have two different aspects to it so a
person might have address information and deployment information.
So that's how those parts of the person define So first of all I'll have some address information so
I'm going to have to have a the string and here I'm going to have just a bunch of strings for the street
address and postcode and the city as well and we also have some employment information employment.
So we'll have let's say Wall Street has to have an SUV prefix.
So we'll have a company name as well as a position that will also have annual income as well annual
income with an initial value of zero.
OK.
So this is our Person class.
Notice all of these fields are actually private and we're going to make several builders to actually
work on the address and employment specifically but even though there are two aspects of the Person
class that we want to build up in separate builders the number of classes will make for the builder
infrastructure is actually for.
It's not even three it's four different builders.
So you're probably wondering well hold on.
Is this some kind of over engineering thing.
Well maybe to an extent it is but we want a nice fluent interface.
So let me just add a number of different classes in here so I'll have friend class person builder and
I'll also have French classes for a person job builder and person address builder.
So as you can see these are three out of the four classes that we're actually going to be involving
ourselves with.
Now there is also a fourth class that we'll see in just a moment but I want to start off somewhere I
want to start off at a point where you have the person providing a static method for actually the initialising
the builder.
So we'll have something like static person builder create.
So we've seen this before in the previous examples of course I will forward declare a person builder
itself like so and then we can provide an implementation for this function.
So in this case what we're going to do is we're going to simply return a person builder.
That's really all that is going to be happening here.
There is no additional magic involved.
OK.
So coming back to person though as you can see we have three different classes we may as well start
working on them and we're going to begin by starting our work on person builder now person builder is
going to be actually a file with two types in it.
So let's go and create a new class I'm going to call it person builder.
So it is a dedicated builder for objects of type person but there is a bit of a problem because we want
to be using this class as a base class for person job builder and person address builder.
But we cannot and the problem with this is that imagine if you have a person that which has a person
that's being built up because you have to have the person being built up stored somewhere.
Right.
And this is this seems like a nice place to actually do that.
So you have person here let me actually get the Include statement in here but the problem is if you
inherit from it you end up replicating the object that is being built up over and over and over because
it's just an ordinary member So what do you do.
I mean you use a pointer or.
Well one of the approaches really sly approach is to actually use two classes to use a base class which
doesn't have the object but just has a reference to it.
And to use a derived class which does in fact have the object so let's have person build here and then
I'll have a public constructor which actually well too early for that to.
For the constructor because essentially in addition to person builder We're also going to have a base
class we're going to have a class called Person builder base.
Now personally their base is different because it has a bunch of protected members specifically it has
a protected reference to the person being built up.
So here we have the actual value of the object being built up here it is.
But here we're going to have a reference to it.
So we're going to have a reference to person and we'll initialize it in the constructor as well.
OK.
So we now have a nice constructor where you initialize the reference.
So coming back to where we just were what we can do is we can use this constructor from the derived
class so person builder is going to derive from their base.
And it's going to have its own constructor as you can see we get red on the lines here or it's going
to have its own constructor which simply passes in the object that it has constructed so it's going
to be an empty constructor completely empty but it passes in that variable P as the reference that's
being worked up on essentially.
So here we go.
I think I've messed up things a little bit.
Well only in so far as I need to remove this argument here.
So person builder doesn't actually take any arguments in the constructor and it simply provides a reference.
So a reference to this particular object this object goes into this constructor here.
That's all that's happening.
And the reason why we're doing it this way is that we can inherit from person build their base instead
of inheriting from person builder.
And that's all there is to it.
So now that we have made this let's try to think about providing a fluent API for the different sub
builders.
So we're going to have a person address builder and a person job builder and they're all going to be
coming out of person build their base.
So here what we can do is we can have a person address builder function called Lives and we'll have
a person job builder person job builder function called works now again these classes don't exist yet
so I'm going to forward declare them all declare person job builder and a person address builders.
Well like so and we can now provide implementations of both of these will generate the implementation
here generate the implementation here.
But these implementations they're actually going to be slightly different because remember we have that
constructor parameter we have that parameter where you pass in the reference to whatever it is that
you are actually building up.
So this is where in both of these cases I'll get rid of the brackets.
I don't like them we pass in person.
So that's what we do here.
And that's certainly something that we do here as well.
Now of course we also need a couple more includes here.
We need a couple of more includes because we're missing some of that includes for some of the stuff
that we're doing so I'm going to include person address builder which we haven't made yet as well as
a person job build but don't worry we're going to make them in just a second.
Let's actually do this now so first of all or have our person address builder.
And this is going to be interesting.
So person address builder as you may have guessed it inherits from person builder base not from person
builder but from the actual base because we don't want the object being built to replicate.
I think I've said it a couple of times already.
So essentially the person addressed builder is going to be just a class so it's going to be a class
called Person address builder.
We're going to inherit from person builder base.
There we go.
OK.
I'm going to include a string in here include a string so that we would get this.
And we also need to have a matching constructor.
So here we just take a reference and pass it onto the base.
That's all there is to it.
And now what we want is we want a fluent interface now typing person address builder all over the place.
It's a bit too difficult for me so I'm going to do a typedef so I'll type person address builder to
be self.
Now we go.
And now I can provide a fluent API for building up the address.
So in this class we're building up the address part of the overall definition So here we're going to
return a reference to self and we'll have for example how a function called at which is going to take
a string specifying the street address.
It will set the street address of the object being built up.
So we see a person dot street address wall street address and then we return star this and this kind
of fulfills our requirement of a fluent interface.
Now what we can do is we can complete this entire class.
I'm going to add a few more functionality in here so you can specify that the person lives at the street
address with postcode such and such in such and such and city and in a similar fashion to the way we've
made the person address build or we can make a person job builder.
So let's do that so I'll go in here and make another header files is going to be a person job builder
and this time around what we can do is we can do roughly the same.
I'm actually going to just copy and paste stuff over so you can see once again we inherit from person
builder base.
We have a typedef for self.
We have a constructor which simply passes the reference over and we have a specification for the person
working at a particular company as a certain position earning a certain amount of money.
So the only thing that should be here is BP instead of age.
So this is how you make the actual sub builders.
And now we can go into the main and actually use all of this and you're going to hopefully appreciate
the way that things are panning out.
But before we do this one more thing that I really want to do and that is the ability to turn a person
a builder into an actual person by providing an implicit operator.
So this is something that allows you to write the following.
So our goal the kind of goal of this entire exercise is to write something like the following.
So person equals person creates So that's the static function that we made and then specify lives at
with post code in and then jump to the employment information later on.
So we need a couple of Hetter includes in here obviously it's not going to work without those so we'll
have person that hates BP and will also include person builder who will have the suborders as well.
So person address builder and P.J. B.
B come on that we go.
OK so maybe we don't need the last two but anyways we'll just have them in here as a person create basically
creates what it's inaccessible right now.
We better make it public so I'm going to stick a public section here so that we can actually use it
for something.
So we're going to make a person builder and we're going to use the person builder to jump from person
address builder to person job builder.
So as you can see these other functions lives and works which returned the appropriate Suborders.
That's how the whole thing works in tandem.
And remember personal address builder and person job builder they inherit from person builder based
not from person builder.
The only reason why we have person builder is so that we construct the object that's being created but
we constructed just once.
We don't do it for every inheritor because that would result in ludicrous amount of duplication.
So coming back to our scenario the final thing that we want to do is want to cast a builder to an actual
person and this is something that you can actually do in the builder.
So if we go into a person builder with BP what I can do is I can just define an operator.
So for example I can define something like the following operator person Konst.
And here we may as well just move the object so return as to the move person.
There we go.
OK.
So this definition is something that we can work with what is the complaint here.
Change the type of operator function.
No I don't know why the line is complaining about this party looks perfectly valid to me.
OK so having implemented this we can now go back to see pupae and this whole becomes valid.
And let me actually do a bit of lay out so that you can see just how beautiful the whole thing is.
So essentially you work with one builder because both builders share the common interface you can jump
from one to another with these and that's why you can specify the live information you jump to the other
builder and you specify the works information and in the end you end up with a person and you can actually
see out for example that person's information to wherever and now we don't have we don't have the operator
for actually printing in person so we can we can generate something.
Let's let's actually do that.
Let's go into Person HBP and I'm going to go and just just do a little bit of co-generation here.
So we have this tree map with operator to select everything and see what we get here.
So it's a large list of everything that's inside person basically.
So now that we've constructed this nice sort of faceted builder it's actually a builder facade so it
combines the builder and the facade design pattern the facade being that person builder class we can
actually start using all of this.
Let's actually see if this compiles and what the end result is.
All right.
So as you can see we're getting exactly what we expected so we have the street address 123 in London
Road with a postcode the city the company name the position and the annual income.
So it all works after I did a tiny fix.
Behind the scenes.
But essentially what I'm trying to illustrate here is that when you have objects which are too complicated
you can actually split the builder into several builders which are working in tandem and you can also
provide these fluent interfaces which allow you to jump from one building to another at any point in
time which is also particularly convenient but it does spawn a few extra classes.
In this case we need to builders.
So we have two separate buildings but we actually have a whole for different classes.
Obviously the number of classes doesn't doesn't just explode like this it's simply because we wanted
to have a base class where the object reference is being stored as well as a derived class where the
actual value is being stored.
That's all.
So this is a more convoluted demonstration but something that you might need in your development as
your objects get more complicated.