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”
Adam is a cunning lad. He has been double-dating Elina and Carina. However he has identified himself with different names to each of them. Elina knows him as Adrian and Carina knows him as Boris. Is Adam cheating? Well, Adam begs to differ. He says life is short and he is a limited resource, only one person. Why not have fun with two girls at a time? Inside himself, he is always the same Adam. But he switches to two different personalities for the sake of Elina and Carina, by changing his external behaviour. Morally questionable, no doubt. But he is a fine specimen of the flyweight pattern. Continue reading “Design pattern: Flyweight”
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.
A really common jargon that gets thrown around in the world of software is ‘OOPS’. This does not refer to a mistake, as in ‘oops!’. On the contrary, OOPS in software in mostly a right decision. OOPS is an acronym for Object Oriented Programming System. It is one of the ways to think about software, design its architecture and use an appropriate programming language to write it. In this post, I will explain to you some concepts of object oriented software. If you are a future software developer, this post will make it easy for you to understand. Even if you never intend to be a software developer, this post will make you look at software from a different perspective. Continue reading “Introduction to object-oriented software”