Faceted Builder

Dmitri Nesteruk
A free video tutorial from Dmitri Nesteruk
Software/Hardware Engineering • Quant Finance • Algotrading
4.4 instructor rating • 21 courses • 128,336 students

Lecture description

We look at a more complicated builder facade that exposes several sub-builders (builder facets) for building up parts of an object in a fluent manner.

Learn more from the full course

Design Patterns in C# and .NET

Discover the modern implementation of design patterns with C# and .NET

17:57:13 of on-demand video • Updated May 2020

  • Recognize and apply design patterns
  • Refactor existing designs to use design patterns
  • Reason about applicability and usability of design patterns
English [Auto] So in the example we've done so far we've been using just one builder to build up a particular object and we looked at how to implement this builder and even make it flew in. But sometimes a single builder isn't enough. And what you want is you want several builders which are responsible for building up several different aspects of a particular object and you also want some sort of facade and facade is another design pattern that we're going to take a look at later on. But we are going to encounter it in this demonstration. So let me explain to you why this is needed. Now I'm going to use a bit of a synthetic example but this example is simple enough to understand so let's suppose you have a person now a person has two different classes of information there is information regarding a person's address. So I might make a couple of public fields once again so I'll make public string street address and postcode and let City. So this is the information which pertains to the address. And you might want to have a builder just for building up the address in a fluent way. And then of course we'll have some employment information as well. So we'll have public string company name and position and I'll add another field public and annual income for example. So this is quite a bit of information on the person. And we want to well first of all we want to output this information so I'll add formatting members. I would just dump everything here. So we have a nice big two string implementation so that we can see how the person is actually initialized. Now what I want to have is some kind of Builder which actually builds up a person but really I want several buildings taking care of the process. I want a nice API for building up the address for building up the employment information and for jumping from building one to building another. And for this we make a builder facet or in fact we're going to have to build our facets of facet for a dress and a facet for employment. So let's take a look at how to implement this now we're going to start which might seem like an ordinary approach with a person builder but the person builder isn't really a builder in the full sense of the word. It's a facade. Have to have a Sadullah here but never mind. So the person builder is a facade for other builders so it doesn't actually build up person by itself but it keeps a reference to the person that's being built up that's one thing. And the second thing is it allows you access to those sub builders if you will. So here's what it looks like. We have a protected person person he calls new person. Now I have to stress that this is a reference it's a reference object this is very important because if you were building up a struct you would have a lot of problems with this approach. They can be mitigated but I'm just putting it out there so that you're aware of that. So we have a reference to the object that's being built up in this case it's a person and it's initialized here. Now in addition what we do is we expose the buildings but what builders we haven't caught yet so let's make the person job builder. So make a person job. So a person job builder is designed for building up job information on a person object. But in addition to just being standalone It also inherits from person builder. Now this is really weird. Why are we inheriting from it. You'll see why in a moment it all becomes clear in a while. But for now let's just focus on this object so we need as a construct argument to take a reference to the person that we're actually building. So I'm going to take a reference here. Actually let's go into the general and you make a constructor but I'm going to take a person person I'm going to assign this person he calls a person like so now what's happening here is that you're passing into the builder. The object that you're building up and you're storing it in the field that you inherited from person builder. So far so good. And now I can build that nice good looking fluent API so if I want to say that the person works at a particular place I say public person job builder at. I put the company name here as an argument and then what I do is I say person Daut company name he calls a company name and returned this because it's all going to be a big fluent interface. Then I have the same thing for the position. So as a so the person works at this company as a and then string position so I put that in here string position. So once again we simply assign a field and then we return this person position equals position and then return this. And finally we have that annual income. So public person job builder earning it amount and then we just say person Daut annual income equals amount and return this once again. Now why do we do all this what is the point. Well the point is that we can now start using this API. We can now make a person builder. So I'm going to see var P.B. was new person builder. And then of course I can try building UP a person. So we'll try doing var person equals and then I'm going to see person builder and I'll go to the next line and I'm going to put a dot in here. Now so far strangely enough we're not getting much. It doesn't look like a person builder even has an API for us to work with so let's make an API. Now we want to expose person job builder from person builder. And this is actually really easy because we can just return the new instance with the provided argument that we're building up. So here's what it looks like. Public person job builder works. So it's a public property called the works. And we're going to return a new person job builder which takes an argument of person the original person the person that is being built up. So I'm going to see person here. So essentially we now have a property called works and we can start using it so we can say person builder Daut works Daut at and you can provide the company name you can for example and then I can go to the next line and just indent it nicely as a. And I can say he works as an engineer and then earning let's say one hundred and twenty three thousand roubles for example. Notice as soon as I put the semi-colon and V-shape of reformats the whole thing so that kind of ruins the presentation I'm going to undo it for now. OK so this is one facet of person because employment information is a facet and there is another facet which is the person's address. So for that we simply make another builder. Hopefully you understand the process of what I'm going to do. I'm just going to paste in a person address bullier. So here we go. Personal address builder. Very simple. It also takes the person reference and I have to stress once again that this this thing with references is convenient. We're building up on that same reference we have a single reference to persons being passed through all these sub builders and that's fine. But if you have a value type you could be in trouble. Shall we say obviously not our case so now that we have a person address builder but I can say is I can see public person address builder lives and then return a new person or address builder passing and the person once again. OK so what does this give us. Because you can see that we once again have a fluent interface we have a method called at. So the person lives at the street address with postcode so and so in such and such and city and we can add this information anywhere in the person builder. So for example I can go in here and I can say lives Dauth out and I can say 123 London road. And then I can sort of manually indent here and say in London with postcode as w 1 to a C for example. So the reason why we can jump from building up the address to building up the employment information is because both the address builder as well as the employment builder inherit that they inherit from person builder. So both of them actually expose every other builder out there. And as a consequence of this yes you can you can write something like person dot lives dot lives dot lives forever. That's completely fine. But you know that's just a side effect of the fact that you're trying to make things convenient to use. So what we've done is we've used to some builders to present a fluent interface for building up a person but interestingly enough if we now right aligned this right line person we were obviously not getting in person at the ad because person is actually a person job builder. That's the last call. So the question is well how can we actually get a person without introducing another piece of API. And that is perhaps the icing on the cake in this case. So if we go to person builder what I often do which isn't really that correct of a programming approach but I do this I do public static Complicite operator person taking a person builder P.B. and I simply return PVD person OK small p. There we go. So what I'm doing is I introduce an implicit conversion operator to person. And this allows me to write the following. So I cannot keep using far but I can write person person and this will work just fine. So that's actually compile this and execute this. And as you can see we're getting the built up person so we have the address initialized correctly. We have the employment information initialized correctly as well. So this is a more complicated example I recommend that you actually download this code then jump into it and figure out what's going on here because there is a bit of a trickery in the way that where we've essentially built a facade so a facade is simply a component which hides a lot of information behind it. Now here we've made the classes of the suborders public but obviously as you can imagine you can make them in classes of person build or you can hide their internals from the consumer. That's also quite possible. So this is the faceted builder approach.