Is <em>facade</em> a class which contains a lot of other classes?
Is facade a class which contains a lot of other classes?
What makes it a design pattern? To me, it is like a normal class.
Can you explain to me this Facade pattern?
A Design Pattern for Flutter
A closer look at a design pattern for Flutter apps
In my last article, I took a look at the example app first introduced Weather App with “flutter_bloc”, and moved it from using Bloc to using a more MVC approach. Below is that article for your reference.
Now in this article, I’m going to take a deeper dive into the MVC approach. This will be like ‘looking under the hood’ of BloC and Redux. In this case, we’re going to be getting into the weeds of the MVC framework as I’ve implemented it. As it would, it’s going to get a little complicated. For some, your eyes may glaze over, but it’s hoped using the same sample app will help us move right along. It‘s going to be long read — make a coffee first.
The MVC design pattern is an explicit effort to separate three aspects of a software application. In this case, Model-View-Controller describes the separation of the app’s Data (Model) from the app’s Interface (View) from the app’s Logic (Controller). If you haven’t already, there’s an article explaining my interpretation of MVC as it was implemented in the Flutter package, mvc_pattern:
Now in this article, the three aspects of the ‘sample app’ are separated even further — incorporating and integrating even further Flutter’s own API and framework. This sample app has its own Github repository called, Weathercast, and is also available on Google Play.
AAs always, I prefer using screenshots over gists in my articles to show code. I find them easier to work with, and easier to read. Click/Tap on the screenshots themselves or on their captions to see the code.
Design patterns provide structure. They provide a means to organize your code. Doing so, it’s hoped, allows developers familiar with the design pattern to ‘hit the ground running’ when assigned to a project. We’re going to see how a design pattern can help organize your code, your files and even your directories that make up your project.
This article will not only suggest a structure, but will also suggest specific programming practices to perform while developing a Flutter app. Note, all suggested here is far from canon. They’re something I do — you may find it useful to do too. In the end, you do what you do.
In this sample app, the MVC design pattern is even conveyed in its directory structure. Looking at the three screenshots below, you’re looking at the directory structure that stores the sample app. Each screenshot is the previous one but with sub directories opened further. Notice there’s some files and even directories named, model, view and controller. Therefore, even at a glance, you know what ‘type’ of code is in what file and in what directory. Nice, no?
Note, in the last two screenshots above, the three library files, model.dart, view.dart and controller.dart are highlighted with little red arrows. They’re now listed below, and you’ll discover each contains a list of export statements. Each represents the ‘three aspects’ of the MVC design pattern. With that, guess what’s contained in the library file, controller.dart. Look closely.
The library file, controller.dart, contains all the ‘controller’ code for the app. So what’s the idea behind all this, you ask. This approach was inspired by the Dart documentation itself when organizing a library package and serves to help expedite the developing phase. I’ll explain.
So, all the source code located under a ‘controller’ directory is listed in the library file, controller.dart. All the source code considered part of ‘the View’ in this app are found in the library file, view.dart. Finally, the file, model.dart, contains references to all the code concerning the app’s data. It’s all part of the practice of organizing the code in such a way in the effort to expedite the development process. Time is money after all.
As an example, you see those three files listed above now referenced in the import statements highlighted by three red arrows in the screenshots below. While developing, the practice of automatically supplying these three import statements right away after you create a ‘new Dart file’ ensures you as a developer that you’ll have all dependencies necessary to get on with your work. Near the end of development, I would then include the ‘show’ directive for future reference (the second screenshot). With that, weeks, months, years from now, I or another developer can then return to this library file, and readily see the dependencies involved. Nice, no?
Admittedly, for larger apps, this practice proves impractical to maintain, but, for simple apps, the idea is to use these three import files to quickly gather the dependencies needed. Time is money.
Notice there’s a directory called, home, in the app’s directory structure. This tells you, at a glance, where the code for the ‘Home’ widget is located. The ‘Home’ widget, as you may know, is usually the main screen for the mobile app in most cases. It’s named after the property found in the class, MaterialApp.
Notice in the last screenshot, under the home directory, there’s another set of directories named, model, view and controller respectively. They’re all pertaining to the ‘Home’ widget. Guess what’s under each directory? See where I’m going with this? At a glance, you can see what code does what.
At a glance, you can see there’s a drawer widget accessed in the ‘Home’ widget. Look at the last screenshot above. See where the drawer code is located? Pretty logical place for it, right? So where’s the data accessed by the ‘Home’ widget, I wonder? Under the directory, model, of course.
So let’s step back a bit, and ask where is this ‘Home’ Widget called in this app? Like with most Flutter apps, you can guess it’s being passed to the ‘home’ property of some MaterialApp widget somewhere. But where? Look below, and you’ll see where.
So there’s the home property being passed the class object, Weather. Where is this class, Weather? Where is this class, WeatherApp? What’s this AppView class that extends WeatherApp? What’s this method, onTheme()? And finally, what’s this con.WeatherApp passed to the property, con? A lot is going on here, uh. We’ll walk through this one step at a time.
First of all, where is this class, Weather? Well, you already have a good idea where that is. It’s the ‘Home’ widget after all. More specifically, it’s the screen or interface for the ‘Home’ widget. You know where the ‘Home’ widget code lives, and you know the ‘interface stuff’ for the ‘Home’ widget is under the directory called, view. Looking there, you’ll see a library file called, of all things, home.dart. Bet it’s in there.
I was right! And unlike Java, you don’t have to name the file after the name of the ‘main’ class in the file. You can have any number of classes, variables and high-level functions in that file! Huge. And so, in the file home.dart, we find the class, Weather. The first part of this class is listed below.
By the way, note the last three import statements above. You’ve seen those three files before. Notice, at a glance, you can determine the dependencies involved in this particular library file. Nice, no?
So where is this class, WeatherApp? It appears to be the start of this app. Note, the class name, WeatherApp, has the word, ‘App’, appended on the end. That should give you a clue as to where this code could be found. Let’s take a look at the sample app’s directory structure again. Notice there’s a directory called, app. Bet, you can guess what’s in there. Yup, three dire…Oops, two directories! Guess the app doesn’t need to access any data. That’s fine.
So, where is this class, WeatherApp? Let’s look at the three screenshots below. Ok, we can figure this out. It’s part of the interface. Hence, it should be under a directory called, view. Looking in the directory, view, we see a library file called, weatherapp.dart. Look’s promising. Let’s open that one up.
This is too easy. We’re getting to know this app pretty fast, aren’t we? Like it’s by design! Take a look below at the class, WeatherApp. Look at the last two import statements. It’s our old friends again — minus the Model. At a glance, you can see what’s being used in this library file and where they live.
Note, the ‘as’ directive is being used on the last import statement. That’s Dart’s way of handling the case when two classes have the same name.
So is this the start of the app? How about we look at the library file, main.dart. By convention, this is the start of most Flutter applications because it contains the function, main().
So, what do you see? You see a class called, App, being instantiated from the library package, mvc_application. Those familiar with my past articles may recognize this as part of my up and coming package release to develop Flutter apps.
You also see our class, WeatherApp, is referenced in one of the three ‘export’ files, view.dart. So, what is the method, runApp(), taking in to start this app? We know the function, runApp(), takes in a Widget, and so we must assume the App object is a Widget. Below is a screenshot of the class, App, and then a screenshot of it’s parent, AppMVC.
Yup, turns out it’s a StatefulWidget. In short, this ‘App’ object starts things using the the following composition: App(View(Controller(Model()))). Note, the last two red arrows in the second screenshot. Those functions, initApp() and init() are going to come up in this article a little shortly.
And so, following this composition, the parameter supplied to the App object must be a ‘View’ of this MVC approach applied to the application. In this case, the ‘View’ is the class, WeatherApp, which extends the class, AppView. We’re peeking ‘looking under the hood’ at this point by the way.
Note, in turn, a Controller is then supplied to the ‘View’ class in the form of con.WeatherApp(). Again, following the composition, App(View(Controller(Model()))).
Notice, I don’t bother passing the Controller as a parameter inside the file, main.dart. Way bother. Make your code more modular, and instantiate the Controller class inside the View in the form of con.WeatherApp(). See below. It happens to have the same class name as the View, WeatherApp, and so the ‘as’ directive to used to make the distinction. That’s fine. Some consistency.
The purpose of this ‘App layer’, by the way, is to set up the ‘environment’ for the app to run on. What you see below is the Controller for the app first instantiated above in the form of, con.WeatherApp().
You can see there’s a lot going on here. As it should, it’s ‘initializing’ the app at startup after all. You can see it extends the class, AppController. Remember those two functions I mentioned earlier, initApp() and init()? Well, they’ve such come into play. See them? We’ll get into specifics on them in a little bit.
Let’s return to the app’s View, also called WeatherApp, for a moment. It extends the class, AppView, and is first instantiated in the file, main.dart. Remember?
Looking at a truncated screenshot of the class, AppView. Here, you can see its build() function. And look! There’s that MaterialApp we’ve been looking for!
In there, we see the MaterialApp class object being supplied an long list of parameters in the form of class variables and or functions. What’s that all about? Well, as you may have already guessed, you’re able to ‘pass in’ all the properties that make up the MaterialApp class with either those variables or functions. And with those functions, you can then dynamically ‘rebuild’ the Widget Tree with new property values if you wish. This feature will, in fact, be demonstrated in the sample app.
By the way, I noted while writing this article that I made a misstep. It’s always good programming practice to keep your code static and immutable if you can. Since there should only be ‘one instance’ of these two classes at the ‘app level,’ the use of static factories make sense, and so the two classes we just covering were changed accordingly:
It’s beyond the scope with this article, but to accentuate the case, here are some reference to Joshua Bloch’s now famous publication: Effective Java. Of course, it doesn’t just apply to Java, but is good practice for any Object-Oriented Programming Language.
Ok, back to it. Now, there’s a drawer used in this app. Remember? How do know? Again, we saw it in the directory structure under the directory, view. See below. Nice.
So further, with this naming convention imposed on the directory structure, you can readily see what makes up the drawer for this particular sample app. Under the directory, drawer, there’s another directory named, weather_locations. Looking inside that directory, we see our old friends again: the directories, controller, model and view. We also see something new. A library file called, mvc.dart.
Looking at the last screenshot above, we can induce weather_locations is another screen displayed inside the drawer. It’s a screen because there’s a directory called, view. There’s a directory called, controller, and there’s even a directory called, model?! There must be data specific to this screen, weather_locations?! Great! Now, what’s this library file, mvc.dart? Let’s take a look at it below.
Well, will you look at that. It contains a list of export statements. A closer look reveals that it’s all the code that makes up the ‘weather location’ screen. The first line contains the model, the second line contains the view and the third contains the controller: M-V-C. All in a file named, mvc.dart. Fun! Look below and you can see the library files it refers to and an example of the ‘weather location’ screen displayed in the drawer.
The files all have the same name — again, adds some consistency, don’t it. Let’s see what’s inside those files. First, we’ll look at the first bit of the Controller:
Note the name of the Controller class. It’s has the abbreviation, Con, append on the end. Developers will then recognize this class as a Controller. (Of course, you could call it anything you want, but there it is.) Note the import statements. They’re using the ‘show’ directive so the next developer who happens to open up this file can readily see what is used and where it lives. Notice the last import statement is that mvc.dart file. All this is an attempt to impose a standard, a conformity, a means to help the next developer ‘hit the ground running’ when this project is handed off to them next.
Let’s take a look that the first bit of the Model class. As always, you can click on the screenshot below and view its full code in Github.
The import statements, at a glance, tells you what classes are involved. The name of the class tells you this is a Model class. Note, like the Controller, it too uses a static factory and not a traditional constructor to instantiate the class. You only need ‘one instance’ of these classes after all. Now, to keep this moving along, what does the View look like?
Looking at the View, you see it’s not even a class but a high-level function?! It returns the variable, _demoItems, of type List<DemoItems>. Looking at the imports you see this View does indeed ‘talk to’ the Controller, LocationCon, and as well as reference the ‘MVC Pattern’ library package’s StateMVC class. So where is this high-level function called in the app?
Because of the way the directory structure is arranged, we can ‘walk this back’ and take a educated guess as to where this high-level function is called. Neat!
Stepping back out of the View, weather_loctions.dart, with the high-level function, we’re still in the drawer directory. Now, going up one level in the directory structure but still in the drawer directory, what do you see? If you guessed it’s called in the file, settings_drawer.dart, you‘d be right.
The first screen shot below is the file, settings_drawer.dart. You can see the function call, LocationCon().listLocations(). This function, in turn, is found in the Controller class, LocationCon. Now that makes sense since, in this MVC arrangement, the View doesn’t directly ‘talk to’ the Model. Instead, your access the high-level function is through the Controller. Looking at the second screenshot, you can see the high-level function we’ve been looking for, weatherLocations, is indeed accessed in the Controller.
Let’s step back, now and look at one particular feature of this sample app. With every weather condition reported, a ‘color theme’ is presented to represent a particular ‘type’ of weather. Gives a little splash to the app.
To be able to ‘dynamically’ change the app’s color theme, you need to be able to call the setState() function on the State object that contains the theme. In other words, the State object that has the class, MaterialApp, in its build() function.
In this sample app, the ‘Theme’ class is a Controller named, ThemeCon, and explicitly changes the color of the app depending on the weather conditions assigned to a location. It controls the color if not the weather.
So where is this ‘Theme Controller?’ It’s located under the ‘Home’ directory. Why? Because it’s called by the ‘Home’ Controller. Where’s the ‘Home’ Controller? It’s found in the file, home.dart. With me so far?
Below, is the stretch of code in the ‘Theme Controller’ responsible for the changing the color theme, and a screenshot of where this file is located.
Now, this ‘Theme Controller’ may be called in the ‘home’ widget, but it’s changing the ‘theme’ property of the MaterialApp class, and we already know that’s back in the ‘App level’ in the State object, AppView. And so, how do you access the app’s State object?— through the app’s Controller of course.
Let’s go back to the app’s Controller, WeatherApp, running at the ‘App Level.’ At last, I’ll be talking about those two functions, initApp() and init().
You can see below the app’s Controller gets access to a lot of things. Make sense — it’s the app’s Controller! In one of those two ‘init’ functions, initApp(), the app’s State object, stateMVC, adds the Controller, ThemeCon. Look below.
In other words, this other Controller called, ThemeCon, is given access to the app’s State object — found in the app’s View, AppView. ThemeCon is now able to call the setState() function in the State object that contains the theme. Are you lost? We’ll step back a little…well actually a lot!
Let’s step back all the way to the beginning. Remember the ‘App’ object that’s passed to the function, runApp()? It’s a StatefulWidget, remember? That means it creates a State object. It creates the app’s State object. Both that StatefulWidget, and its State object, call those two ‘init’ functions respectively. It’s all part of the process in setting up the environment to run your app. Let’s take a peek.
Below are screenshots of my IDE where the execution of the sample app was paused at specific breakpoints. The first screenshot is stopped in the app’s State object’s initState() function. Look at the name of the StatefulWidget function being called there. It too is called, initApp(). Consistency.
The second screenshot has gone into that function up in the Statefulwidget — which you now see is the ‘App’ object passed to the function, runApp(). The breakpoint has stopped on the initApp() belonging to the controller that was assigned to the app’s View. The property, _vw, is the app’s View which is the WeatherApp class in main.dart. Are things coming together for you yet?
Don’t worry if you’re getting lost. I mean, if you’re not the sort who walks through code, for example, trying to get to know how the other design patterns work like Redux, Scoped Model or BLOC, then your probably wasting your time here. Guess, you’re just one of those wants to get it done, right? Although, I will suggest there is less boilerplate in this one. How about reading further? You got this far.
So now we’re back in the initApp() function, where the ‘Theme Controller’ is given access to the app’s State object, stateMVC, highlighted in blue. See?
And so, it turns out, it’s the app’s State object’s initState() function that, in turn, calls the initApp() function in the app’s Controller. It’s all by design.
It’s where synchronous operations are to be performed. Now how about asynchronous?
With any computer program, a lot of things have got to happen before it’s ready for the user to…well, use. There’s a lot of ‘initializing’ to be done first. This is a simple little sample app, but it too has to ‘get ready’ first before it’s, well…ready. Let’s take a further peek at how this Flutter app gets ready.
After the initApp() is called in the app’s State object’s initState() function, the ‘App’ object fires its own build() function. In the first screenshot above, notice the ‘App’ object takes advantage of the FutureBuilder class. The property, future, is given the a function called, init(). Recognize the name?
This is how asynchronous operations are handled. However, it such a way, that the user may have to wait until they’re done. What will the user see til then? The little spinning circle in the center of the screen of course.
In the second screenshot above, you see what’s inside that init() function. It’s stopped at the app’s View own init() function. Let’s look below and see what’s in that init() function. Notice we’re moving up the layers of the framework.
So now, in the first screenshot, we see we’re in the app’s View where some ‘internal’ stuff is done before it stops at the init() function for the parent class, AppViewState. The second screenshot above has us in that init() function where we’re about to now go into the app’s Controller and run its init() function. A lot happening here under the hood — like a framework should.
And now we’re back in the app’s Controller. For our simple little sample app, it’s called, WeatherApp and it’s there, in its init() function, where it actually calls the ‘Location Controller’ — the one we were first introduced to back in the directory, weather_locations. Remember? Here, it’s opening the database that lists the locations on that drawer that’s in the ‘Home’ widget. Remember the drawer? Opening database may take a couple of microseconds, and so the app ‘waits’ for that to get done before it’s ready for the user. Peachy.
There’s another thing called, LocationTimer, listed there as well it would seem, but I’ll let you find out what that is when you download the sample app.
Let’s get back now to how this app changes its color theme on command. The app’s View has a function called, onTheme(). Remember, using such functions allows the MaterialApp to dynamically change its properties the next time it ‘rebuilds’ its Widget tree (i.e. the next time the setState() function is called.) It’s all coming together!
Looking at the ‘Theme Controller’ listed below, you see that the property, theme, is in fact a getter. And, in fact, it’s the function further down below called, weatherChanged(), that ‘reassigns’ a value to the variable, _theme.
And so, going back to the app’s View class, inside the framework, there’s the MaterialApp that takes in either a variable or (if that variable is null) a function. In our sample app, we utilize the function to dynamically assign a new theme. I’d suggest ‘stepping’ through the sample app to see what I mean.
This article is turning into a novel, I know. However, there’s a two more things I want to cover here. Firstly, how does the framework work in performing the main function of this small simple sample app: Get the weather for a city. Let’s do a quick ‘walk-through’ of that. If you’ve read Felix Angelov’s story, Weather App with “flutter_bloc”, you know how it goes. You type in the city’s name, it gets the weather.
Ok, here we go. In the ‘Home’ widget file, home.dart, there’s a State object there that allows you to click on a magnifying glass and type in a city name to get its current weather. Below (just above the little red arrow) there is an IconButton widget that, when pressed, returns a city in a variable called, city. That variable is passed to the ‘Weather Controller.’ See below.
Note, the ‘Weather Controller’ has a function named, onPressed(). I try to follow the practice of mimicking the API used in the View’s code to be also used in the Controller’s code. That consistency thing again. Let’s see where that takes us.
In the onPressed() function listed below, we see the variable, city, is passed along to another function called, getWeather(). We see inside the function, getWeather(), there’s a ‘then’ method. It’s in that ‘then’ method where the function, rebuild(), is called. Finally, the ‘Theme Controller’ comes into the picture to call it’s function, weatherChanged(). Remember that function?
Now, if you guessed that the two functions, refresh(), eventually get to actually calling a State object’s setState() function, you’d be right. Congratulations, you’re starting to see the whole picture.
The ‘Theme Controller’s refresh() function calls the AppView’s State object with its MarterialApp object. This will change the app’s AppBar color. While the second refresh() function you see above calls the ‘Home’ Widget’s State object. This will change the screen’s background color. Magic.
The last thing I want to cover quickly is app preferences. If and when you try out this sample app, you’ll notice it’ll ‘remember’ the last city you picked, and will, in fact, bring up it’s current weather conditions the next time you start up the app. That’s because the ‘last city’ entered is recorded in the app’s preferences — with help from the framework.
The ‘Weather Controller’, WeatherCon, will go and fetch the last city if any in the its initState() function. There, it calls the function, initFetch(). Below is a truncated screenshot of the controller, WeatherCon. The red arrow show you where the app’s preferences is accessed.
You see in the screenshot above where the ‘last city’ is retrieved and, in fact, where the ‘last city’ is recorded — in the function, fetchWeather(). Remember, the function, fetchWeather(), iseventually called every time the user clicks the magnifying glass, and the function, onPressed(), is executed in the View’s code and then in the Controller’s code.
That Prefs class you see in the screenshot above is a library I wrote a few months after first discovering Flutter. I had a need for such a library in my projects, and I talk about that in an article I would then write soon after:
The Prefs library is actually part of the framework I’m working on, and you’ve already seen in being initialized above, in the class AppController, when the app was setting up its environment.
Oh! To heck with it! I decided to publish Prefs as a library package! I just did it! Just now! Here your go: prefs 1.0.2
It’s proven useful in my projects. Might as well as share, right?! Try it out. If you like it, use it. If not, then don’t, right?! Again, read the article above to get the load down on how to use it. It’ll still be a part of the framework when it too gets published. Whenever that’s going to happen?! Just not enough time in the day, is there. Anyway!
Ok, that was bit of a read. I’m sure you’re hungry, and or want to get on with your Life. However, I will be following up on this article as there is much more one has to consider when developing software as you know. It just happens, this framework will allow you to do so, and I’ll show you how in other articles.
Originally published by Greg Perry at https://medium.com
In this article, we provide an introduction to the world of design patterns. For each pattern, we further understand the pattern and the context in which it is applicable, with real-world examples.
In this article, we provide an introduction to the world of design patterns. For each pattern, we further understand the pattern and the context in which it is applicable, with real-world examples.
In this post, you will learn:
We have been building object-oriented software for over 40 years now, starting with Smalltalk, which was the first object-oriented language.
The programming world has encountered a large number of problems, and a variety of solution have been proposed to tackle them.
An attempt was made by a group of four people, famously called the “Gang-Of-Four” or GoF, to come up with a set of common problems and solutions for them, in the given context.
This catalog of common problems and their solutions is labeled as GOF (Gang of Four) Design Patterns.## Why Design Patterns?
The advantages of design patterns are:
The design patterns we talk about here, are from the perspective of an object-oriented world. There are mainly three different kinds of design patterns:
Creational patterns deal with the creation of objects.
Structural patterns deal with the composition of objects.
It deals with questions such as:
Behavioral patterns focus more on the behavior of objects, or more precisely, interactions between objects.
Exploring Creational Design Patterns
How does an object communicate with another object?
We explore the following creational design patterns:
A prototype represents a fully initialized instance, to be copied or cloned.
Let’s take an example:
Let’s consider the design of a chess game. Every game of chess has the same initial setup — the king, queen, rook, bishop, knight, and the pawns all have their specific places. Let’s say we want to build software to model a chess game.
Every time a new Chess game is played, we need to create the initial board layout.
Instead of repeating the creation of chess board each time,
The object with the initial setup of the chess board is the prototype. And, we are using the prototype pattern.
Isn’t it simple?
In the prototype pattern, you have a fully initialized instance. Here, the initial board layout is readily available.
Whenever a new chess game is started, for example, in any of the numerous online Chess portals, this initialized instance is merely copied or cloned.
The Builder Pattern separates object construction from its representation. What does that mean?
Assume that you go out for a multi-course dinner to a restaurant. Such a dinner would have many options, such as starters, main course, and desserts. You would probably choose two or three out of the presented options. A particular client may want to have dinner with the first two options only, leaving out the desserts option. Yet, another would prefer the main course and desserts, skipping the starters entirely.
Similar situations might arise in designing software. You may need to build an object using a subset of the options that are available. Or, you may need to create the object in multiple ways. This is where the builder pattern comes in handy.
To understand it further, let’s look at a small piece of code.
Let’s say you’re writing software for a machine that prepares coffee. The main ingredients of coffee are coffee, milk, and sugar.
Depending on which part of the world you are from, you choose whether or not you have sugar and milk.
The builder pattern steps in to provide these coffee options for you.
Have a look at the code inside
What we have inside the
Coffee is a
Builder, to which we pass the mandatory
type of the coffee. Chained to that call, we make other calls adding in our preferences of the other ingredients.
Someone else who wants a different coffee can easily build it. This leads to a huge amount of flexibility in building objects.
Other approaches to solving this problem, such as the use of setters, have many inherent problems. These solution lead to code that is difficult to read, and also behave erratically in multithreaded programs. The builder pattern solves all those problems.
The advantages of using the builder pattern are:
The singleton pattern is the most famous among all the design patterns. What this pattern does is very clear from its name — it allows only one instance of a class per JVM at any point in time.
A good real-world comparison would probably be the leader of a nation.
However, there is a disclaimer here — there can only be one instance of that class, per JVM. If you have a Java application that runs as part of a cluster of application servers, each server runs a separate JVM instance. Therefore, you are allowed to have one instance of the singleton created on each application server, at any given point of time.
There are a few things to remember whenever you create a singleton class.
private, to prevent the possibility of other objects creating instances of your class.
@Singleton, along with other related annotations.
The intent of the factory method pattern is to create a family of object types. Let’s look at a code example.
This code implements a
PersonFactory. This class has a static method named
getPerson() that accepts a person’s name and gender as parameters. Depending on the gender
String passed in, it either returns a
Male or a
If somebody wants to create a male person, they invoke the
getPerson() method on the
PersonFactory with a gender argument of
"M". Similarly, you can create a female person by invoking the
getPerson() method on the
PersonFactory with a gender argument of
We are passing in an identifier of the type of object we need, at the time of creation, while still referring to the generic type,
Female classes are hidden behind the
The advantage of using the abstract method pattern is that you can add additional types to the factory, without much change in the other classes using this class. In our example, you can add more types of gender, without affecting the existing code that deals with other genders, which all use
What about the complexity involved in creating an object?
It greatly simplifies the task of object creation. The
PersonFactory makes the decision of what object to create, and delivers it to us.
Let us now have a look at the structural design patterns we want to explore.
A proxy is an object that represents another object.
Let’s look at a real-world example.
Your debit card is a proxy for your bank account. Whenever you make a transaction using a debit card, the corresponding money is deducted from the bank account.
The debit card is a proxy for your bank account, which is the actual object.
Similar to that, in programming, you might have to program interactions with remote objects. In such situations, you create a proxy object that takes care of all external communications. You would communicate with the proxy as if it were residing on your local machine.
A good example is the EJB Home and Remote interfaces.
A proxy hides the complexity involved in communicating with the real object.
The decorator pattern allows us to add responsibilities to objects, dynamically.
In object-oriented programming, we typically use a lot of inheritance.
Let’s say a particular pizza place has 10 types of pizza. Our implementation has 10 classes for these types of pizza.
Now, there is a requirement to make these pizzas available with three types of toppings. If we would want to create individual classes for each pizza and topping combination, we have a total of 30 classes to manage.
Instead of doing this, can we make the pizza-topping relationship dynamic? Can we add a topping on top of an existing pizza?
We need to use a topping as a decorator on top of any pizza.
Another example would be adding a discount on a pizza order.
Let’s say that you have an order, and based on some criteria, you want to offer a discount to the customer. There might be a variety of discounts that might be applicable at different times. If you add a different type of a discount to each type of order, then in a static relationship, you need to maintain hundreds of classes.
Treating a discount as a decorator on an order makes the relationship dynamic.
A very good example where the decorator pattern is implemented in Java is the Java I/O packages. This is reflected in the way we create an input stream in an I/O program:
You have a
FileInputStream. If you want to make it buffered, then add a decorator to it in the form of a
BufferedInputStream. If you want the buffered
FileInputStream to have line numbers in addition, then add a decorator for a
Decorator pattern enables you to add behavior to existing objects at run time. This allows the user of the interface to decide how they want to create objects.
The drawback of this approach is the complexity involved in creating objects. The user needs to understand a lot of classes and their relationships before being able to use the power of the decorator.
A facade is a single class that represents an entire subsystem.
Let’s take the example of an event manager. An event manager is a go-to person when you want to organize an event. They handle several aspects of an event such as the decorations, food, sending out invitations to guests, music arrangements, and other similar things. The event manager acts as the facade of the event organization subsystem.
Consider the case of a distributed system. You typically have the need for multiple calls across layers.
Take, for instance, a system that offers the service for online book orders. Whenever an order comes in, several things need to be taken care of, such as checking for the stock, reserving the order, accepting the payment, updating the stock, and generating the invoice.
We can create a single facade, such as the order interface, which would manage all incoming orders and provide an interface to the customer.
The advantage of using the facade pattern is that it reduces the number of network calls, as well as reduces coupling among classes.
It succeeds in establishing a transaction boundary between communicating objects. Facades, like services, are good hubs to implement transactions.
As long as the interface of the facade remains the same, the implementation details of the subsystem can change.
An adapter is used to match interfaces of different classes.
Let’s take a real-world example of power adapters.
Problem: If you buy a mobile phone in India, it comes with a charger that only works with power sockets used in India. If you take the same charger to the US, for example, it will not work, as it will not fit into sockets there.
Solution: The solution is to use a travel adapter that you can use with your charger when you travel. You can plug in your charger into the travel adapter, and the travel adapter is used to connect to the socket in a particular country.
Similarly, when you try to talk to a system that uses a different message format or a language, you need an adapter to translate messages.
An interesting example is the communication between a Java program and a web service. Before sending out the data to the service, we need to convert the object into XML or JSON format. We are implementing the adapter pattern!
Let’s consider a few scenarios
In these scenarios, you might not want to create a new instance every time it is needed.
How about caching an instance and reusing it when needed?
A flyweight represents creating a fine-grained instance that is being used for efficient sharing.
A really good real-world example is the public switched telephone network (PSTN).
In the PSTN, there are always a limited number of lines, and for simplicity, let’s assume this number is 10. However, there are thousands of customers that use these lines. Since all 1000 customers would not make calls at about the same time, it is possible to efficiently switch calls coming in, among the existing 10 lines.
In the software world, a good example of a Flyweight pattern is JDBC connections.
A connection pool is a set of connections to the database. The application may be firing a lot of queries, but we don’t create a new connection whenever a new query comes in. As soon as a query comes in, we match it to an available connection, and the query gets fired. Once query execution is done, the connection is released back into the pool.
Using such a tool allows us to avoid the cost involved in creating and closing a connection.Behavioral Design Patterns
Let us now have a look at the behavioral design patterns.
The Chain of Responsibility Pattern represents a way of passing a request between a chain of objects.#### Example 1
The best example of this pattern can be seen in the exception handling mechanism of most programming languages.
Suppose you have a
method2(), in turn, calls
method3(). Assume that
method3() throws an exception.
method3() has no exception handling, then the exception is passed on to
method2()to handle it. If again
method2() has no exception handling inside it, then the exception is passed on to
method1(). If even
method1() cannot handle it, it gets thrown out of
method1() as well.
Consider a real-world example of a loan approval process.
A bank clerk has permissions to approve loans within a certain amount. If the amount goes above that, then it goes to the supervisor. The supervisor has a similar, albeit larger loan approval limit set for him. If the loan amount exceeds that limit, then it goes to his supervisor, and so on.
With the Chain Of Responsibility pattern, we have a chain of objects that are ready and wait to process requests. When a new request enters the system, it goes to the first object in the chain to attempt processing. Depending on the processing condition, the request travels up the chain and gets fully processed at some level, or maybe not processed at all.
The Iterator pattern is one of the most simple design patterns. You have a set of elements arranged in a collection, and you want to sequentially access those elements. A good example of an Iterator is a TV remote, which has the “next” and “previous” buttons to surf TV channels. Pressing the “next” button takes me one channel in the forward direction, and pressing the “previous” button takes me one channel in the backward direction.
In the programming works, examples of the
Iterator class and the enhanced
for loop in Java are examples of the Iterator pattern.
The state pattern is used to alter an object’s behavior when its state changes.
Take a look at this Java example:
Let’s take the example of a fan wall control. The fan wall control controls the speed with a fan rotates. It has speed levels ranging from 0 to 5. When it is at level 0, the fan does not rotate, and it rotates the fastest at level 5.
When you rotate the knob of the fan control, the level changes, and this causes the speed of the fan to change as well. This is a classic case of a change in state (level) causing a change in behavior (speed).
FanwallControl object is composed of a
SpeedLevel is an interface that has four different implementations. Initially, the level is at
Off, and when you click rotate at that time, the new speed is at
SpeedLevel1. The happens successively, and if you rotate at
SpeedLevel3, the level returns to
In case you need to define an additional speed level, just add in a new class that implements the
SpeedLevel interface and implement its rotate method.
This is an excellent example that highlights the advantages of an extensible class.
The strategy has the task of encapsulating an algorithm inside a class. Let’s look at a Java code example:
ComplexClass intends to perform a lot of complex logic within it. One part of that logic is to sort a set of values. One direct way would be to implement the entire sorting logic within
ComplexClass. This would make it very inflexible since, if you wanted to change the sorting logic tomorrow, that entire code needs to change.
When we use the strategy pattern, we separate the algorithm of how the sorting is done from
We define an interface named
Sortable, which has a method named
sort(). Any actual sort algorithm is an implementation of
Sortable, and needs to override
ComplexClass is given a particular
Sortable implementation as a constructor argument.
ComplexAlgorithm does not care what exact sorting algorithm is being used; it is happy that that object implements the
sort() method of
A lot of flexibility results due to the use of the strategy pattern. You can dynamically change the strategy and pass in the right one according to the context.
The observer pattern is a way of notifying a change to a number of classes.
If you are a fan of cricket, you may want to know whenever Sachin Tendulkar scores a century so that you can celebrate.
All such similar people would register themselves to the event of Sachin scoring a century. Each of these people is now an observer for that event. Whenever Sachin does score a century, a centralized program will notify each observer.
Another example is that of online bidding. A group of bidders at an auction register themselves to receive notifications when a higher bid is placed. As soon as a bid higher than the current one is placed, all the registered bidders get to know about it.
There are two main parts to implementing the Observer design pattern.
Here is a simple implementation of the Observer pattern:
We have created an instance of
SachinCenturyNotifier and registered three fans with it.
Whenever Sachin scores a century, the call
notifier.sachinScoredACentury() would be made and all three fans would be notified.
The visitor pattern allows us to add a new operation to a class without changing the class.
There are a lot of scenarios when designing frameworks, where we don’t want other people to modify the code in the framework. We want others to extend the functionality without touching the framework code. They are allowed to add new operations, but not to change the existing operations.
The visitor pattern allows you to do this.
A good real-world example of the visitor pattern is the operation of a taxi company.
As soon as a person calls a taxi company, and a cab is dispatched, the company accepts a visitor. Once the visitor, or customer enters the taxi, he is no longer in control of where he is going. The cab driver is now in control.
If we look at it as object-oriented code, the driver class is in control of the customer class. The driver class can add new operations on top of the customer/visitor.
The template method pattern is used to defer the exact steps of an algorithm to a subclass.
A good real-world example of this pattern is how we go about creating a house plan. Any good house plan consists of a floor plan, the foundation, plumbing, framing, and wiring. Such a plan is almost identical for each house.
If you were to model this in software, you could create a template class with this standard behavior defined. A subclass could extend this and give actual implementations. Such details could include the wooden flooring type, the wall paint colors, and any added wings as required.
A good example of the template method pattern is within the Spring framework, in the form of
handleRequest() merely takes care of the basic things. However, it leaves the lions' share for the implementation of the method
handleRequestInternal(). This method is defined by subclasses, where more specific logic can be implemented.
The template method pattern is all about doing the high-level steps and leaving the low-level details to the subclasses. The subclasses can override the low steps and provide their own implementation.
The command pattern encapsulates a command request as an object.
Let’s take a real-world example.
Consider the scenario when a customer goes to a restaurant and wants to place an order for a meal. The writer merely writes the order he gets on a piece of paper and passes it on to the chef. The chef executes the order and then prepares the meal. He passes the piece of paper to the manager.
The verbal order from the customer has now become a paper object. This piece of paper is the command object. The command object contains all the details needed to execute the request.
Similarly, in object-oriented programming, we can encapsulate all the details of a request into an object and pass that object to execute it.
In web applications, when a user types in the details on a form, these details are captured in a single request object, which is then passed across.
java.lang.Runnable is also a good example of how this pattern is implemented. We create threads in Java by extending the
Runnable interface, which has all the logic for execution in its
start() method. When we want to create and start a thread, we pass this class to the
The memento pattern captures and later restores an object’s internal state.
A lot of games that we play offer the option of performing an intermediate save. At a certain point in the game, you can save it and later come back to it.
To implement this, we need to save the internal states of the game objects and restore them at a certain point in time.
This save-revert functionality can be implemented by using serialization in a language such as Java.
The memento pattern is very useful in implementing undo/redo operations.
For example, if you are working on a text document in a word processor. If at a certain point, you decide to undo changes, you can see each undo until you reach a point where you are satisfied. You have now reverted to an earlier saved state of the document.
The mediator pattern is used to define simplified communication between classes.
Take the example of an Air Traffic Controller (ATC). Let’s say that at any point of time in India, we have about 500 flights in air. We need to decide the routes that each of these flights needs to take. This also includes deciding the times at which each of these flights takes off and lands. It would be a highly complex situation if each of these 500 flights needs to talk with each other and arrive at an acceptable schedule of routes.
That’s why we have the concept of an ATC. The flights communicate with the ATC, and having assimilated the information from all the flights, the ATC makes the decisions and communicates them back the flights.
In the software world, a good example of the Mediator pattern is the ESB (Enterprise Service Bus). In a distributed system, instead of letting the applications talk to each other, an application drops in a message to the ESB. The ESB routes the request to the application that needs to handle the request. It acts as the Mediator.Summary
In this article, we had a quick look over a variety of design patterns.
A design pattern is an approach to solve a problem in a given context. We focused on understanding the context in which a particular pattern may be applicable to real-world examples.