Lecture thumbnail 0:00 / 0:00 Now that we’ve looked at how to build a decorator using dynamic composition, I am going to show you
how to build it using static composition.
Unfortunately, C-sharp is not a great language for doing this.
I mean, this is the kind of thing you will typically do in a language like C plus plus.
And you might be wondering why.
Well, one of the tricks which Cplusplus has, which unfortunately C-sharp doesn’t support, is being
able to inherit from a template argument or in this case, a generic parameter.
So what you really want to do is you really want to write something like the following.
You want to make a decorator, which is a public class colored shape of T, which actually inherits
from T.
Now, unfortunately, in the C-sharp programming language, you cannot do this.
This is actually something called the curiously recurring template pattern.
It’s a very common thing in C plus plus, but in C sharp you simply cannot do it.
So the question is, well, if you want some sort of composition on the static side of things.
So if you want something like a transparent shape of a colored shape of a square, for example, and
if you want to initialize it with something or other, then you have to do it differently.
You have to jump through a lot more hoops.
And one of those hoops is unfortunately, that you cannot stick with interfaces, you cannot stick with
interfaces anymore.
So we’re going to refactor our code to have an abstract class.
Instead of an interface.
So here I will say abstract string.
Like this.
I will try to rename I shape to simply shape because it’s no longer an interface really.
But we need to do a few more things.
So we have to make this public obviously.
And then of course, on each of the actual invocations, we have to mark it as override.
So let’s go and mark it as override in all of those locations.
So we’re now using an abstract base class and you might be wondering why we are doing this.
Well, let me show you how you can actually get some sort of static decorator composition in your code.
So I’m going to build a colored shape of T, so I’m going to have a class called Colored Shape and I’m
going to have a type argument T here.
Now T is going to be a shape and it’s going to also support the construction.
So it’s going to support a default constructor, which at the moment we don’t have in any of the shapes
unfortunately.
So colored shape of t is going to be inheriting from the shape class.
So it’s going to implement the shape class.
But in addition, it’s also going to require that T is a shape and has a default constructor.
Okay.
So having made all of this, you can see it’s kind of wavy on the line here.
We can alt enter, we can implement the missing members which is as string.
And now of course we get to see how this kind of static composition actually works.
Because remember, the reason why we took a type argument here is so that we would instantiate it.
Unfortunately, since we cannot use the curiously recurring template pattern, we cannot use inheritance.
Generally we have to use aggregation.
So what you would do here is if this is a colored shape, you would have string color like this, but
you would also have whoever this you are decorating.
So you would have an instance of t called shape and you would make a new T, And this is why we put
the requirement here for the new constructor call, which like I said, we don’t have those yet.
We don’t have those in square or circle or colored shape or anywhere else, to be honest.
So now the idea is as follows We have the two string or as string override in fact, and we can continue
using it like before.
So here we can we can actually copy what we have from the ordinary colored shape.
So here I’m just going to copy this override over and we’ll see whether it fits or not.
It should fit just fine because we’re still doing roughly the same thing.
And then of course we need a default constructor for the color as well as a constructor, which actually
takes the color.
So first of all, I’ll generate a constructor which initializes the color, but we also need an empty
constructor.
And you might be wondering, well, why do we need an empty constructor if it’s a colored shape?
And the answer is this requirement.
This requirement is going to be everywhere in the transparent shape class, for example.
So we need a default constructor.
So we’re going to stick one in here.
See tour.
There we go.
And then of course, we need to initialize it with some color.
So I’m just going to say this black.
So the shape is going to be black by default.
Now, you might once again be thinking, well, why don’t we just let the user set the color using a
property?
Yeah, that’s certainly possible.
But I want some sort of default here.
So here is color shape of T and then of course we can start using it and failing badly because we cannot
use it yet.
So var red square for example, equals new colored shape of square.
And here is the first problem.
So Square doesn’t have a default constructor.
We have a constraint.
So let’s jump into square.
And then of course we make a constructor where we initialize the side to maybe zero like so.
And then of course we would do the same for Circle.
So you would make a constructor where you would initialize maybe the radius to zero as well.
So with all of this, this line is now valid and we can actually try outputting it without any changes.
So I’m going to write line red square dot as string.
There we go.
Okay.
So if I execute this.
All right, you can see that it’s now working more or less correctly.
We have a square with side zero and the color black now in C sharp.
Unlike C plus plus, you cannot set up constructor forwarding, so you cannot proxy the constructor
argument of colored shape into a square.
That’s quite simply not possible.
So I cannot specify an argument here apart from maybe a color, so I can certainly specify the color
red.
And this way we have a square with side zero and the color red, but I cannot specify the side in the
constructor.
Unfortunately for that you would need to use properties.
Now let’s take a look at composition.
So I’m going to make a transparent shape of T in much the same way as I’ve made this class.
In actual fact, I’m just going to duplicate it and then we’re going to make a few changes.
So this is going to be a transparent shape of.
And it’s going to have the constructor called Transparent Shape.
And then of course, we’ll have transparency.
So transparency here.
And then I would initialize this with a zero and we will generate the constructor using Resharper in
this case.
So I’m just going to delete all of this and we’ll go and make a constructor which initializes the transparency
like so.
Okay, so we now have shape and it has transparency of a certain amount.
So I’m going to put this in here.
Notice we’re kind of running out of space.
I’m going to do a line break.
Okay.
So the shape has let’s have transparency multiplied by 100% percent transparency.
Okay?
And we can now start using it once again.
So here what I can do is I can say var circle equals new transparent shape of colored, shape of circle
like so.
And here all I can do is specify the transparency.
Like 0.4, for example, I cannot specify other things like the color or the radius of the circle because
unfortunately constructor forwarding doesn’t exist in C sharp.
So at the very least we can write line circle dot as string and we should get something.
We should get a couple of defaults.
So a circle with radius zero has the color black and has 40% transparency.
So as you can see, it is possible to perform a kind of static composition.
But one thing you have to realize is that the number of instantiations of shapes is more than one.
Because we’re not using inheritance, we’re using aggregation.
We basically have a transparent shape which contains an instance of colored shape, which contains an
instance of circle.
So it’s not as simple as just having this one variable.
And then of course, what ends up happening is you really don’t know how to expose the different members.
So for example, let me give you an example.
Let’s suppose that we have the circle, and the circle actually needs to expose its radius so we decide
that the radius is a settable thing.
So let’s say radius, so I’ll say radius here and I will have the getter and the setter.
So now we have this API, but we cannot use it in the sense that down here when we have a circle, I
cannot just go ahead and say circle dot and set the radius.
And the reason for this is that we’re not using inheritance.
Once again, we cannot use the curiously recurring template pattern, so we cannot use inheritance and
therefore we cannot expose the actual radius.
And this isn’t something that can be handled in a nice way.
And this is why the static approach to composition of decorators does not work in C sharp.
It simply isn’t good enough, unfortunately.
Play Play Play Play Play Play Play Stop Play Start Play information alert