Lecture thumbnail 0:00 / 0:00 One of the examples of the flyweight pattern that actually appeared in the original Gang of Four book
was to do with text editing.
So now we’re going to replicate that example and we’re going to take a look at how editing text can
be done with a memory saving technique.
So let’s suppose that we want to output formatted text.
I’m going to make a class called formatted text and we’re going to have plain text, but we’re also
going to have formatting.
So I’ll make a constructor constructor like so, and I’m going to take the plain text in the constructor
and we’re going to save plain text.
So have a read only variable here.
But in addition, I’m going to have a way of capitalizing certain characters in the text.
Now, you might be thinking, Well, how can we actually capitalize?
How can we specify what to capitalize?
Now one of the approaches is to take every single character in the plain text string and give it an
additional boolean value indicating whether or not you want to capitalize that particular letter.
So here what we can do is we can make another array.
So I’ll have a private bool capitalize and when we initialize the text, we also initialize this array.
So we say capitalize equals new bool with plain text dot length like so.
And then if you want to capitalize a particular range of letters, you can call a method.
So you can call a method called capitalize and you can provide this method with the start and end positions
that you want to capitalize.
So int start, int end.
And all this will do is it will set the boolean values in that array so it will have a for loop for
I starting at start I being less than or equal to end.
And you would say capitalize at index I equals true.
All right.
So when it comes to rendering the capitalized text, we can override to string.
So here is the two string override.
And here we have to rebuild the string, taking into account the capitalization settings.
So we’ll make a string builder, new string builder like so, and then we’ll go through each of the
characters.
So the way I do it typically is I say for each var see in plain text, but then I use Resharper to change
it from for each to just an ordinary for with an index I for example.
So what we do is we say SB dot append and we decide whether or not we want to capitalize the character.
So we have the character.
C So depending on whether we want to capitalize it.
So we check, capitalize, capitalize at I If it’s true, then we want to say char dot to upper on C,
otherwise we just append C so you have the string builder and then you return SB to string and that’s
pretty much it.
So let’s see how we can leverage this approach.
So we’ve implemented capitalization.
So I can say var feet equals new formatted text and we’re going to have a string here.
This is a brave new world.
There we go.
And then I will say that I want to capitalize the world brave.
So I’m going to say feet capitalize.
The starting index is ten, the ending index is 15, which corresponds to this word.
And then I will write line the word right line feet.
And there we go.
So we execute this and hopefully get our result.
There we go.
So this is a brave new world, and the word brave is capitalized.
Now, the problem with this approach is that we’re spending a lot of memory for flags which don’t need
to be there.
Essentially, instead of specifying every letter, whether it’s capitalized or not, and you can think
of bold and italic taking up even more memory, what we might want to do is we might want to just specify
that we have a bunch of ranges and those ranges are capitalized.
So a range is just an indication of the starting value and ending value.
And when we go into to string, we can check those ranges and apply capitalization if that is what is
required.
So let’s implement a kind of better formatted text.
So let’s make a new class called Better formatted text here.
So it’s going to be very similar to the previous example.
We’re going to have plain text as a field initialized in the constructor.
But in addition, what we’re going to have is we’re going to have an inner class.
So make an inner class called text range.
Now the text range is going to tell us about the start and end positions of the range it applies to.
So we’ll have something like public int start and end and in addition we can have the settings here
so we can have public bool capitalize and then you can have other formatting options like bold italic,
whatever.
Okay.
So the only thing you want from a text range apart from this information is to figure out whether this
text range covers a particular position, a particular index.
So you say public bool covers int position and the position has to be greater than or equal to start
and less than or equal to N So we return exactly that return position greater than or equal to start
and position less than or equal to end.
There we go.
So that’s what we want from it range.
And now we can return these ranges in better formatted text.
So now we can give the user a range to work with.
So that would be the flyweight object.
So we say public text range, get range int start at int end.
But in addition to returning the range, we might also want to keep the range so that we know it’s part
of the formatting.
So if the user customizes it, we apply the formatting later on.
So for this we’ll have a private list of text ranges and we’re going to call this one formatting.
So we’ll make a new list of text ranges.
And what we do when somebody requests for a range is we make the range first of all.
So var range equals new text range and we specify start, start equals start and end equals end like
So let’s not forget the comma here.
And then we do two things.
First, we add it to the set of formatting options.
So formatting dot add, we add the range, but we also return the range.
So we do two things at the same time.
And what this allows us to do is it allows us to get the range from a chunk of text and then customize
this range.
So here is the new approach.
We say var BFT equals new better formatted text, and here I will just copy the string over here like
so.
And then I will say better formatted text dot get range.
So I’ll get the range from 10 to 15.
So that will be my flyweight object.
And then I will say please capitalize it.
So capitalize equals true.
There we go.
And then once again we can write line BFT.
But before we do, we have to implement a string because now the capitalization is done differently.
So coming back to our better formatted string, we now need to do a two string override and we’re going
to do once again SB equals new Stringbuilder.
But this time around things are going to be different because we’re going to be going through all of
the ranges, checking whether this particular point is covered by that range.
If it is, then we apply all the customizations in that range.
So once again, I’ll do let’s do A for each var C in a plain text string.
There we go.
So I’ll change from for each to for once again, very convenient, quick action here.
So we will have for each var range in formatting.
So we check whether this particular letter, the letter will run right now when the index I is actually
covered by the range.
So if range covers this particular index at I and somebody wants capitalization, then we capitalize
the string.
So we change C to char dot to upper C and then of course we append the letter, we append the letter
C, So that’s the implementation.
And let’s see what’s going on here.
We have to return obviously SB to string.
So we’ve implemented the same approach using the flyweight pattern by operating on these text ranges.
And now we can actually try this out because we’ve got everything in place.
So let’s execute the program and.
As you can see, we’re getting exactly the same result.
But now we’re not wasting memory on these huge arrays of formatting for every individual character.
Instead, we’re being specific.
We’re saying that this particular range should be capitalized, and then we check against the ranges
to make sure that the right letter is in fact capitalized.
And that’s the essence of the flyweight pattern.
Play Play Stop Start Play information alert