So one of the big questions to the decorator is whether decorators are composable, whether you can
have a decorator on a decorator on a particular class.
So let’s take a look at how this is done.
Now, there are actually two ways of doing it.
There is the dynamic way and there is the static way.
The static way isn’t so great in the.
Net framework.
It’s great in other languages like C plus plus in the.
Net framework, not so good.
So we’re going to start with the dynamic decorator.
Now I’m going to show you a very simple example.
Now let’s suppose that I have some sort of interface for defining a geometric shape.
Let’s go with I shape.
There we go.
So this shape might have a string representation that we want to print.
Now, I’m not going to call it two string, I’ll call it as string so that we get to see a difference
between what’s inherited from objects.
So we’ll have as string as a method which is supposed to return a string.
Now I’m going to have a bunch of classes.
So for example, I have a circle and a circle might have a radius.
So we’ll have a radius here.
And then of course we can initialize this.
So C or F will initialize this correctly for us and then we can maybe resize the circle.
So resize and we’ll have some sort of factor of resizing.
And then we just say radius multiply equals factor, something like this.
And then of course we implement the eye shape interface.
So here we have the eye shape interface and we can implement the missing members.
And here in the as string, we may as well return something like, let’s say a circle with radius and
then write the radius.
There we go.
And let’s reformat this to not to verbatim interpolation.
I want to use an expression body that looks nicer.
Okay, so now we might also have a square, for example.
So a class called Square, which has the implementation of eye shape, of course.
So it has that as string and we’ll have the size of the side here.
So I’ll call this side.
And once again I’ll initialize it in the constructor.
So this should be f like so.
And then of course when it comes to printing, I would just say that we have a square with side and
specify the side here.
Once again, I want this as an expression body.
Okay, so we have the circle in the square.
They have both shapes and now we want to maybe color them.
Well, actually, before we do that, let’s actually show you the output.
So we’re going to start using maybe var square equals new square.
Let’s have its size, let’s say 1.2, three F, and then I will write line square dot as string.
There we go.
So first of all, we’ll take a look at this actually operating.
So a square with side 1.2, three.
Okay, that’s good.
Now we’re going to have colored squares and we’re going to have squares with transparency.
And we also want the circles to be colored or with transparency.
So what we end up building once again is we end up building a decorator.
And I have to stress that this is what’s called a dynamic decorator in the sense that you can make these
decorators at runtime rather than compile time.
So let me show you how you would typically implement this.
So you would say something like, Oh, I’m going to have a class called Colored Shape.
Now, colored shape is obviously going to be an eye shape.
It’s going to implement the interface and it will have that as a string.
Now what color shape is going to do is it’s going to refer to some shape.
So that would be shape, shape like so with the eye in front, since it’s an interface, we’ll change
that in a moment and it will also have a color.
Okay.
So the idea is we now do a initializing constructor once again, which initializes both the shape as
well as the color.
Let me get rid of these since we now have C sharp seven.
So join both of those together.
So now as string can be customized to display not just the shape but also the color of the shape as
well.
So here we can say, for example, that I have a shape as string has the color and then specify the
actual color.
And once again, I’ll turn this into an expression body to look nicer.
So this is a colored shape.
This is a decorator that we can now attach onto the object.
So, for example, if I sort of go down here, what I can do is I can make a red square, var red square
equals new colored shape.
And notice in the constructor it takes a shape so I can feed it the square we have already and specify
the color as red.
And now of course I can write line and I can write line red square dot as string and we can see what
the end result is.
So here we have a square with side 1.23 and it has the color red as well.
So this decorator is working just fine.
Now we can make another decorator just to show the composition of decorator.
So we’re going to have a kind of transparent shape where you can specify the transparency.
So, for example, we’re going to have a class called.
Transparent shape.
It’s also going to be an eye shape, obviously.
So we have to implement this.
Interface.
But in addition, we’re going to have transparency as a float value.
So we’ll have the shape that we’re decorating here is the actual shape with the eye in front and we’ll
have some sort of transparency value.
We’ll make a constructor which actually initializes all of them.
Once again, I’ll use the join check null and assignment thing and then of course we’ll implement as
a string.
So let’s go down here.
And here I’m going to return let’s have first of all the shape as string.
So that’s the description of the shape has transparency and we may as well put it in percentage points.
So we’ll calculate transparency multiplied by 100.0 and we’ll say it in percentages.
Okay.
So once again, I’ll turn this into an expression body.
Hopefully.
There we go.
And now that we have this, let’s try using it.
So we have a red square.
We may as well now make a kind of half transparent red square.
So I’m going to say var red, half transparent square equals new transparent shape.
So now we’re going to apply the transparent shape decorator to a red square, to a red square with transparency
0.5.
And we can this has to be float, by the way, and we can write line the result.
So red half transparent square dot as string and let’s see what we actually get.
So as you can see, we’re now getting a square with side 1.23, which has the color red and has 50%
transparency.
So we’re applying decorators on top of one another.
Now, the only thing that I want to note is that nothing prevents you from applying the same decorator
twice, which means you can have a colored shape of a colored shape, which doesn’t make much sense
unless we’re talking about mixing colors, for example.
But generally, this isn’t something that you can prevent.
You can’t prevent making a decorator from your own already existing type unless, of course, inside
this whole decorator chain, you keep a list of all the types that have been decorated.
And certainly this is possible.
You can make a list of types and make sure that there are no repetitions in them.
But generally this approach works.
And the great thing about this is that it works at runtime.
So at runtime you can make a new shape decorated with like colored shape or transparent shape, and
everything works fine.
Play Play Play Play Play Stop Play Play Play Start Play information alert