What is the difference between purchasing and assembling DIY IKEA furniture vis-a-vis hiring a carpenter to build your furniture for you? In the second case, you are using the builder pattern. Continue reading “Design patterns: Builder pattern”
You probably know that a pressure cooker cannot be opened when it is very hot with plenty of steam built up inside. If you yank at the weight, it will protest with a loud hiss. But there are no problems opening the same cooker either before cooking or after it has completely cooled down. How can the same apparatus behave differently under different conditions for the same procedure: opening the lid? Software engineers will say that the cooker is using the state design pattern. Continue reading “Design patterns: State pattern”
After treating Adil, his doctor prescribes medicines in a complicated dosage. There are two medicinal tablets, one green and one red. The green medicine is to be taken 3 times in the coming week: Monday, Thursday and Saturday and the red one, 4 times: Monday, Wednesday, Friday and Sunday.
As Adil leaves, the doctor hands him two strips of medicine: 7 green tablets and 7 red ones. Adil is confused. He asks, “7 each? But doesn’t it call for 3 of these and 4 of those with a schedule?”. To which, the doctor replies. “How can I be sure that you won’t forget the complicated schedule? That’s why I have given you 7. Have one of each every day.” Adil is aghast. “But… isn’t that over-dosage?” “No, it’s not. 4 of the green tablets are simply mint candies. 3 of the red ones are strawberry candies. Inside the strips, the real tablets are interspersed with identical looking candies as per your dosage schedule. You don’t have to worry. Just habitually have one tablet of each colour every day. Start from the top of each strip.”
Brilliant! The doctor took a complex decision-making process away from Adil and just let him build a simple habit: one green tablet and one red tablet every day. The real tablets will fight against the illness that Adil approached the doctor with. The candies are there to simply … do nothing! In design pattern parlance, the doctor just used the Null Object pattern. Continue reading “Design patterns: Null object”
If you have ever visited a government office, you are probably directed from one counter to another to get tasks done. Why doesn’t the same person do everything? This is because the work is divided into small tasks and each government official is given the responsibility of only one task. Once done, that official will direct you to the next one. You are seeing the chain of responsibility design pattern in action. Continue reading “Design pattern: Chain of responsibility”
Have you ever noticed? If you say “Hi” to Jay, he replies the same. However Jyoti always replies, “What’s up!”. When you get angry and say “Shut up!”, the reactions are different too. Jay is calm, but firm. His reply is, “Hey, watch your word, buddy!”. But Jyoti loses it and says, “Shut up yourself, dumbo!”
How can two persons interpret the same words differently and react so diversely? Well, chances are that nature has used visitor pattern to program their behaviours that way! Continue reading “Design patterns: Visitor pattern”
What do car rentals and libraries have in common? They temporarily lend resources only as long as someone needs to use them and then take it back so that someone else can use them. In object-oriented programming, such as system is called the ‘object pool’.
Object pooling in real life
Let’s explore the philosophy of a library with regards to a book named ‘The Art of Computer Programming’.
- No one needs to read this book 24 hours a day for 7 days a week all his/her life. People need books only for three purposes: learning, reference, review. A person most likely needs a book only for 40 hours in his/her entire life. He/she may need it for 20-25 hours during the learning phase, upto 8-9 hours per day. During reference/review phases, the book is needed for at most half an hour to skim over topics that are forgotten.
- Instead of buying his/her own copy of the book, a person might as well borrow the book for the duration needed and return it.
- A good library solves exactly this need. They stock up multiple copies of the most popular books and some more. Let’s call our library, the ‘Friend of Readers’.
- ‘Friends of Readers’ library estimates that they should stock up 5 copies of ‘The Art of Computer Programming’ on their shelves to start with. This is what they will call the ‘initial’ or ‘default’ level. If no one has borrowed this book right now, you will see 5 books on their shelves.
- As readers start borrowing this book, the library waits and watches. However, they have set themselves a minimum. At any point of time, readers need to see at least 2 copies of the book on the shelf. So as soon as the number of copies goes down to 1, they will take action. They may either have more copies stored in a basement warehouse or they may get in touch with the publisher. Either way, new copies are arranged. How much should they replenish? Well, the library always strives to revert to their ‘default’ level.
Here is a scenario for clarity. The library has 5 books right now. One person borrows and the number of copies goes down to 4. The library simply waits. As more readers borrow, the number goes down to 3 and 2. The library still waits. Now if one more book is borrowed, the number of copies goes down to 1. The minimum level is breached and the library has to take action. They will arrange for 4 more books, so that they return to their default level of 5.
- But about peak season? Perhaps there is an upcoming graduation examination for computer programming majors. Or some leading companies have announced a huge hiring camps. Candidates need to prepare for interviews. In such cases, the library will up the ante and stock more than 5 books. However, a library is a physical space and the number of shelves are limited. They have to take a call and set a ‘maximum’. At no point will they have more than 15 copies of the book in circulation. This include both the borrowed and in-shelf books put together.
- As the peak season fades, the library will remove the extra books to free up space and scale back to their default level of 5.
So what exactly is object pooling?
Let’s use the library example to describe an ‘object pool’ system. In the object pool, there is a pool of objects that clients want to use. These objects are called ‘resource objects’. This is similar to the book ‘The Art of Programming’.
A pool manager object overseas the pool. The ‘Friends of Readers’ library is the pool manager. Just like readers do not buy their own copy of the book, the clients objects do not directly create a copy of the resource object. Similar to the readers approaching the library, the client object approaches the pool manager.
The pool manager maintains the default, minimum and maximum levels. The pool manager starts by creating the default level of resource objects. It does not allow the level to fall below the minimum. If the level is breached, the pool manager quickly scales back to the default level. During peak usage, the pool manager has to create more objects, but it never creates more than the maximum. At any point of time, there can be no more resource objects in circulation than the level mandated by the maximum.
Object pooling in software
Database connections take time to set up. Once set up, they consume memory and processor to stay put. In other words, database connections are expensive resources. Hence, in a big application, it does not make sense for every corner of the program to set up its own database connection and maintain it. Instead, there is a database connection pool. The pool manager sets up a fixed number of connections and allows other parts of the application to borrow a connection for use whenever the database needs to be used. There is a default number of connections to start with, a minimum below which the number of unoccupied connections cannot fall and a maximum number of connections to the database, both occupied and unoccupied combined.
On one hand, the effort and time required to set up database connections is taken away from the client and managed by the connection pool. On the other hand, the client doesn’t have to worry about disconnecting when done. The pool takes back the returned connection and gives it to another part of the application that needs it.
Pooling resources and the system of borrowing and lending them is an efficient way to own and use resources. The ones who want to use it do not have to worry about how to get it in the first place. They just need to walk into a place they trust will have it available for them. Also, since the users do not own the resources and keep them permanently, the pool gets back the resources and others can use them. This way, a less number of resources, consuming less space and requiring lower maintenance, can make the world a less crowded place for everyone.
What is common between a washing machine that has just completed washing and your secretary who tells you that she is done creating the annual reports? They are both using the observer pattern.
The observer pattern in real life
Using a washing machine plays out the following story. The user tells the machine to do the laundry. The machine performs the long, chugging task. When done, the machine tells you with a buzz. This is true of other appliances like the microwave oven or a toaster. Your smartphone does the same thing…. only it notifies you too much!
Not only appliances. Delegation of work to people works the same way. Efficient delegates will come back to you after they have done your work for you. Without them coming back, you would never know when the work is done.
Let’s imagine what would happen if your washing machine didn’t ping or if your delegate didn’t call you up to say that she’s done.
Without communication, you’d never know if the work is done or when it will be done. So you have two ways to know about the status of work.
One way is to be there while the work is being done and observe it all the time. No need to tell you how much a waste of time this is. Might as well do the work yourself. This is what happens when you fill your water bottle from an electronic water dispenser. The dispenser takes ages to start. Then the dispenser has such a thin spout that it takes at least 90 whole seconds before a 1-litre water bottle is full. If you have a 2-litre bottle, then God help you. The problem is that 90 to 180 seconds is too long to wait for water to fill, but too short to start any meaningful work. The other problem is that you have to turn off the water flow yourself when the bottle is full. If you don’t, then the bottle will overflow and water will be wasted. Not a good use of resources or your time.
Alternatively, you have to initiate the communication. That means interrupting whatever you are doing to frequently check up on the task’s status. This keeps wasting your time and resources. And you cannot focus on whatever is actually important to you. This happens when pasteurising milk on a gas stove. If you overheat the milk, it will overflow from its vessel and spill over. Hence the need to constantly check. But since it takes nearly 10 minutes for milk to boil, you can work on your important task for at least the first five minutes.
I have seen devices which solve both the problems effectively. I have seen water dispensers which have a dedicated 1-litre button, that dispenses exactly a litre of water and pings when done. You just keep your empty bottle under the dispenser’s spout and go back to your work. Likewise, I have an electric stove that slowly boils milk for 20 minutes at a certain temperature and then turns itself off with a beep. The milk is perfectly boiled at the end and there’s no spillage.
So, what’s the observer pattern?
Let’s use a domestic bread toaster as an example as we describe the observer pattern. Your spouse and you want to eat toast for breakfast. Your spouse puts slices of bread into the slot on the toaster while you switch on the button that starts the toasting process. Your spouse and you are the delegators. The toaster is the observee or delegate. The process of toasting has been delegated to the toaster.
Next, someone wants to know when the toaster is done. This is the Observer. One one hand, you yourself can be the observer, responding to the toaster’s ping. Otherwise you can tell another person, say your parents or children, to attend to the toaster’s ping. This person is the observer. Thus, the delegator may not always be the observer.
The Observee and Observer have a set of events which are agreed upon. This agreement is represented by an interface in object-oriented programming. See this post to learn what interfaces are. In our case, the observer wants to know when the toast is done. Let’s call this the onToastDone method. By terms of the agreement, the Observee (toaster) promises to call the onToastDone method on the observer (toaster sounds a ping) as soon as the toast is done. The Observer promises to receive the call and act upon it (removing the finished toast from the toaster).
Observer pattern in software
It is common knowledge that the speed at which data is read from a hard disk or from the Internet are much slower than the speed of a computer’s processor itself. The observer pattern is used to good effect here.
In almost any modern programming language, you will notice that calls to load files from the hard disk and Internet are based on the observer pattern. Your program will request the hard disk to load a file, but then move on to do the next thing. Internet requests are handled similarly. The hard disk or the network operation will later let the app know that the requested resource is loaded and ready for use. What would happen if the app were to wait for the hard disk or Internet to finish its job before moving on? You would have an ugly, irresponsive app that fails to respond to your clicks and taps. Happily, the observer pattern keeps your app responsive.
Delegation and observation help us focus on tasks that are important to us. They help us move on from time-consuming tasks and start the next one, keeping our day active. Please let me know interesting examples of observer pattern that you have witnessed.
Here’s an interesting question. If your children are identical twins and you are just introducing them to someone, how do you help your guests distinguish between your twins?
You use the factory design pattern of course!
Let’s use this post to learn one of the most commonly used design patterns in the world of object-oriented programming. Instead of compelling you remember the names of classes, the factory pattern gives you a class based on something you know about that class. Let’s dive in to see what I mean. Continue reading “Design patterns: Factory pattern”
In the last post, we saw the basics of objected-oriented sofware. We saw a simple example about cleaning a room and how to approach it either as a process or as an interaction between things. We saw various terminologies in the world of object-oriented software, such as classes, objects, methods, attributes, inheritance and interface. If you do not remember them, I encourage you to learn those from that post.
We are moving on from those basics in this post. We will be talking about design patterns. Using design patterns, objected-oriented programming solves some common patterns of problems that occur in the world of computers. As Tech 101 always promises, you will also see equivalent examples from the real world to make things simpler to understand. We start with a commonly occurring pattern called the singleton pattern.
Analogy for singleton pattern
Let’s imagine a country named ‘My Native Land’. ‘My Native Land’ is ruled by a single person at the helm. The citizens call him the President. He is the most accountable person and other countries approach this country through him. With such responsibility, it is to be ensured that there is only ONE person with the designation called president. The president is chosen by a public election.
The entire country goes through a unified election process. After much deliberation, candidates are chosen and the citizens get to vote their favourite. The candidates too need to go through a process of qualification to be eligible. E.g. certain education degree, certain work experience, etc. At the end of the process, one person gets to sit at the helm of the country.
This also means that citizens cannot simply proclaim themselves to be the president at their own free will. Nor can they simply appoint their dog, their neighbour, their grocery store owner or their village headman as their president. The only way to choose a President is with a nation-wide election.
Also note that there can be only ONE actively serving president at any point of time. The current president gets to remain at the helm until the next election, after which only a victory will get him re-appointed. Otherwise he will have to relinquish his seat to the newly elected candidate.
The designation named ‘president’ did not exist forever. The role was created at some point of time. Probably when My Native Land embraced democracy. There was NO serving president before that. Someone was appointed for the first time, either through policy or through an inaugural election.
So, what’s the singleton pattern?
Drawing parallels from the president example, we should now define the singleton pattern. Here are the features of a singleton pattern.
- There is a class (blueprint) named President. Only one object from the class can be present in the system at a time (similar to the ‘one president only’ analogy). If you need a refresher about classes and instances, please check this post.
- Only one point in the system (nation-wide election for a president) can create an object from the class. This point must ensure that only one object created at a time. If there are no objects of the class, then one is created (like the first president when democracy was embraced). Thereafter, if an object needs to be created, it should replace the old one. All references to the old object are lost (the old president stepping down for a new one).
- Barring this single point (election for president), there should be no other way to create an object from the class (e.g. citizens informally crowning themselves or choosing their unqualified neighbour as their president).
- Referring to the class automatically refers to the single object made out of it. For instance, if a person named Jose Capitan is the current president, then he is simply referred to as ‘The President’ or ‘Mr. President’. This saves the effort of remembering and calling every president by his/her name every time the person in charge changes.
Example of singletons in computer programming
Singletons are commonly used to access your computer’s hardware efficiently. Your phone camera is a good example. What would happen if every app were to create an object of the Camera class and try to access the camera simultaneously, not knowing that other apps also want it? It would be chaos.
Instead, your phone’s operating system dictates the creation of just one Camera object using the Camera class. This object speaks directly to the camera hardware. None of the apps are allowed to create their own Camera objects. They can only refer to the Camera object created by the operating system.
When the phone boots up, there is no Camera object. As soon as the operating system detects your camera hardware, it creates the singleton Camera object for the first time. A new Camera object is only created if \ the existing camera object crashes or if the user is given a way to switch off the camera hardware and switch it on again. The old Camera object will be deleted.
Singleton pattern allows you to safeguard important resources for which a single point must be responsible. It protects you from the chaos that would happen if multiple points for the same responsibility are created. Can you think of good examples where you can apply the singleton pattern? Let me know in your comments.