Lecture thumbnail 0:00 / 0:00 Let’s take a look at the implementation of the build or design pattern in a more functional way.
So what we’re going to be doing is we’re going to be attempting to do this in a functional way while
still adhering to things like the open closed principle.
So let me show you the kind of builder that you could come up with if you went this way instead of the
other way.
So you would have some sort of sealed class, let’s say, person builder, and this is going to be building
up a person.
So once again, I’ll have a class called person, and for this person will have a bunch of fields that
have a person’s name as well as their position with a company like so.
So we’re going to have a person builder and notice that this class is sealed.
This means you cannot inherit from it.
And as a result, if you want to extend this somehow you don’t have the ability to use inheritance.
You do have an ability to use extension methods instead, which is also going to work.
Now, the reason why it’s going to work is because instead of actually modifying the person in place
right inside this builder, what I’m going to do is I’m going to preserve a list of mutating functions
which affect this person.
So here I will have a private read-only list of funk of person.
And this is going to be what actually is make it flew in person Colma person.
So we’re going to affect the person somehow and we’re going to return a reference to that person.
So I’m going to call this one actions.
And this is just going to be an empty list to begin with.
And then we will have some sort of ability for adding an action, let’s say a private method called
add action.
I’ll make it fluent as well.
So person, builder and action.
So you add an action to a person, but this action gets turned into a funk.
So that’s a bit of a trick.
When you take an action and you turn it into a funk.
And the reason why you would do this is to preserve a fluent interface.
And the reason why you would preserve a fluent interface is because at some point we want to use the
aggregate link method in order to apply all the functions one after another.
So here, when we say actions don’t add, we create the new action where you take some product in this
case and you perform some action on that product.
And instead of a product, you can have virtually anything and then you return that product as well.
So you would have a set up similar to the following.
So we take an action, but we store it as a function which takes a product, returns a product, and
then that is pretty much it.
Then we can also make this method flowing by returning this.
OK, so as you can see, this method is private.
That means that we have to build some sort of wrappers around it to perform some actually useful work.
So what I’m going to have is I’m going to have a public fluent method.
So person builder returning once again called do so do is where you provide some action and this action
gets added to the list of actions.
So coming back here and action, action like so, so do is something that’s going to be publicly exposed
where as an action is something that’s going to be hidden.
Now this is a person Boler, so at the very least we want to give the person a name.
So we’re going to have a method for calling a person something.
So public person builder called String Name and hear what you will do is you would reuse the do method
so you would call do providing the following lambda.
So goes to name equals name.
We go.
So this is how you would specify a person’s name.
And now remember, we want to stick to the open close principle, which means that instead of inheriting,
because inheriting here would be difficult, it’s actually something that isn’t going to work in this
example.
And so we can use the extension method.
So if you imagine somebody is using this API, so they are doing things like PR person equals new person
builder.
They maybe have called Sara and then they call some sort of build method.
By the way, we haven’t done the build method yet.
So that’s another thing that I want to show you before we talk about extending this.
So a public person build like so.
So this is the method that’s going to actually build the whole thing.
And here what we’re going to do is we’re going to take all the actions.
Remember, we are storing a list of actions to apply to that person and we’re going to aggregate them.
So aggregate is something that is going to compact a list into a single application, starting with
an empty person.
So that’s the starting point.
And for every step you have a pair, you have a pair where you have a person as well as a function to
apply to this person.
Remember, this is a fluent interface.
So here we call the function F on person P.
So this is how you would actually apply every single action to a person and now this entire demo is
actually going to work.
Now, of course, what I want to show you and what is critical here is how you would go about extending
person builder while adhering to the open closed principle.
So remember, the open closed principle doesn’t allow us to go into this.
And to modify it and also, you know, I made it sealed here just to illustrate a particular point,
the fact that we can do without inheritance here, we can use extension methods instead.
So here I would make a class called, let’s say person builder, extension’s alike.
So let’s make it a static class.
And I would simply have an extension method.
The public static person builder works as and just provide here the extension on person builder, which
takes a position and simply adds it to the builder.
So here we say builder.
Do remember we have this new method and here I would provide the land the way you take a person and
you set the person’s position to position simple enough and you can now plug this into the invocation
down here.
So you would say works as a developer, for example.
So this is a functional approach.
Now, you’re probably seeing already that a lot of the stuff that we have inside person builder is actually
reusable.
A lot of this stuff is reusable, like it’s a common theme to have a list of actions and then some sort
of way of enlisting in action into the overall list and then applying everything and building up an
object so we can generalize it.
We can basically take all of this code, common this out and we can make it more general.
We can make it more interesting, shall we say.
So we’re going to have an abstract class called Functional Builder, which you’ll be able to inherit
from another functional builder, actually needs two pieces of information.
So we certainly need to know about the type of subject that we are building this subject.
But we also need to know about the concrete implementation of the builder that inherits from this class.
Why do we need this?
Well, because we we need to use it in certain locations.
So, for example, when you have a cold method like cold method here, you need a return type.
That return type has to be the most derived type.
And as a result, you have a situation which is similar to recursive generics, except there is only
one level of inheritance.
So it’s not exactly because of generics, it’s just the use of generics.
And here we would say to yourself, we’ve seen this situation before, so we have to put some constraints
here.
So what is the constraint on T cell if it has to inherit from this holding?
Just copy and paste.
And we also need to put a constraint on this subject because we need a default constructor at the very
least so that we can actually constructed in place.
OK, so now that we have this, what we can do is we can take some of the code that we have down here
and we can sort of adapt it to the new reality.
So I’m going to take all of this code that’s currently commented out.
I’m going to uncommented hopefully somehow,
OK, this has to be done through the idea.
I guess I’ll just bear with me.
Hang on, comment.
There we go.
Finally, there we go.
OK, so instead of person building here, we have to put T cells everywhere.
So put yourself here, put yourself here, put yourself here, because we want this fluent.
Obviously, when you have this reference, you have to cast it to T.
S, because the computer itself doesn’t know that it’s the situation is being used this way and now
coming back to making a person build there, what you do is you simply make a person builder has a public
sealed class person builder which extends functional builder where you build up a person and person.
Builder is the drive type.
So you do it like this.
And here all you have to do is have a fluent interface, public person builder called String Name.
And here you can call do where you provide the lamda where that name goes to name like.
So that’s p that name equals name rather.
That’s pretty much it.
That’s all that you need to do.
And of course the person other extensions are exactly the same.
You don’t have to have any other modification here and that’s pretty much it.
So, so essentially this entire demo is done and these methods all continue to work as before.
But what we’ve done is we’ve kind of shrink-wrapped the functional builder.
We made it into a reusable component that you can subsequently call wherever.
And of course, you know, if you don’t need called here, obviously, let’s get rid of that.
So that is only now down here.
That’s pretty much all that you need to do.
And ultimately, there is nothing else here that that needs to be done.
So just a reminder, the reason why we are passing T cell in here is because, look, when you have
to return person builder here, you call Caldo and of course do returns a T self, which in turn uses
and action, which also uses D.F. F I suppose you could get rid of it, you could just cast just cast
the base class to the derived right here so you would caldo and then you would perform the cast.
But this is slightly neater and there is no real harm in passing in an additional generic parameter
here.
So this is how you would shrink wrap a functional builder to be reused inside different settings.
Play Play Play Play Play Play Play Stop Play Start Play