Design patterns : Adapter pattern

If you have ever travelled to United States from countries like England or India, you face a very common problem. Sockets. In US of A, electric sockets are rectangular in shape where in India or England, it cylindrical in  shape and so are the plugs being put into them. So how to connect? Easy, we carry an adapter, which allows us to work with two incompatible things , and that is our topic of today that is adapter pattern.

Adapter pattern is structural design pattern and works as a bridge between two incompatible interfaces. Intent of adapter pattern is to convert a class or interface into one which is required by client. This lets classes which are independent or incompatible to work together. There are four parts into adapter pattern: Target : this is the interface which is used by client, Adapter : Adapts the interface which needs to be used by client but not compatible, Adaptee : the incompatible interface, Client : Our beloved client.

Adapter-2

There are two ways to implement adapter pattern:

Class Adapter: uses java inheritance to extend source interface

In this method, the class which needs to be used by client and has incompatible methods is extended and a child class is created. This new class which is created contains compatible methods. These compatible methods will eventually call incompatible methods of base class. This method can be implemented in languages which support multiple inheritance (Java, C# don’t support multiple inheritance and hence this cannot be used in these languages). This is because adapter needs to inherit both target and adaptee. However, if we make target as interface, then this problem goes away as class can implement as many interface as possible.

To illustrate, we will take example which we discussed above, the rectangular socket (returning 120V) and cylindrical plug (may take only 40V, 12V, 3V). First let’s create a class to represent rectangular socket returning 120V:

Volts class

RectangularSocket class returning 120V volts

Now, we have cylindrical plug and which needs to get power from socket. However, the socket available takes on rectangular plug. What we will do is to inherit rectangular socket class and create an adapter class which will also take cylindrical plug too which can take 3V, 40V or 120V.

Cool now we have a client (cylindrical plug), Adaptee (rectangular socket) and adapter (class derived from rectangular socket). We have to make target interface which will be implemented by adapter and will be used by client, lets call it as IRectangularSocketAdapter.

Client using above interface:

Object Method: It uses java composition and adapter contains object of Adaptee class.

This is very simple way to implement adapter pattern, just add base class as an attribute to adapter class and use that attribute to call incompatible methods. This method has its own advantages: first, it adapts the base class and all inherited class of that base class which is not case in  class base method. This comes with a caveat that if subclasses add new methods, adapter needs to change in order to expose those methods to clients.

Everything from above example of socket and plug still remains, only change is in adapter class which now contains Adaptee class (rectangular socket) as an attribute. Code below shows how adapter pattern using object method is used.

There are some pertinent questions : What amount of work should be done in adapter. That is simple to answer, the amount you require to make communication between two incompatible classes. If target and adaptee are more or less compatible, then adapter just needs to delegate calls to adaptee. If target and adaptee are incompatible, we may have to do a good heavy lifting, like data structure conversions etc.

Other question, when should we use adapter pattern?  Again simple question, most of the times we face it. When you want to use a class which cannot be changed and you already have implemented logic to use that class, but taking some assumptions which are not correct or you are replacing the class which was supporting your earlier implementation and replacing with new class which cannot be changed. This case is best suited for adaption. You write an adapter which provides a way to use new class using your existing code.

Today, we learned something about a method which is heavily used to use legacy codes and this is called as adapter pattern.Please leave comments/suggestions if you like explanation or if there is something which can be improved or corrected.

Design Patterns : Strategy pattern

In last post on design patterns, we learned about builder pattern, in this post we will be discussing strategy pattern.  Before going into details, first understand basic intent of strategy pattern. Intent is to define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary without any change in clients that use it.

It is a common solution for representing a family of algorithms and letting you choose among them at runtime.

Strategy pattern
Strategy pattern core

Strategy pattern consist of following components:

  • An interface to represent some algorithm (the interface Strategy)
  • One or more concrete implementations of that interface to represent multiple algorithms (the concrete classes ConcreteClassA, ConcreteClassB)
  • One or more clients that use the strategy objects

Example of family of algorithms can be sorting algorithms  (insert sort, quick sort, merge sort and so on), hashing algorithms (MD5, SHA), mathematical operation (addition, subtraction,multiplication),payment methods (credit card, Paypal, wallet). In strategy pattern, we try to define each member of the family and encapsulate implementation via an interface. Basic tenet of this pattern is: encapsulate anything which can change.

Lets talk about some problems and see how strategy pattern solves our maintenance nightmares.

Sorting algorithm using strategy pattern

First example is very simple, easy to understand and make the concept very clear. Example is about sorting algorithm. We want to implement a sorting algorithm, which works on given input and return output in sorted order. There are more sorting algorithms than I have underpants. Which one should we use? Let’s say we deliberate and come up with one sorting algorithm which satisfies our current requirements, let it be insert sort.

We will implement a function insert(List<Integer> input) and use it in clients which needs input to be sorted.
Going down, we want to change sorting algorithm to quick  sort instead of insertion sort. And the hell will break lose. How many place you need to update the code because there will be thousands of clients who will be using it? There is a way out. We implement quick sort and a function fun() which calls insertion sort or quick sort  based on input.

Well, now if we want to implement merge sort, our dear function fun() will have another if and else block. And if in future, a new algorithm is discovered, we need to add additional block for that. So, it is quite evident that code is not extensible and open for the change.

So, let’s get back to tenet of strategy pattern, which says, code which can be changed needs to be encapsulated. Best way to encapsulate things is interface. We will define an interface say ISortingAlgorithm, which declares a function called sort().

Now, we will define three different classes one each for insertion sort, merge sort, quick sort. Each of these classes implement ISortingAlgorithm. 
Any client who wants to use, will send its choice of sorting algorithm. With this approach, any new sorting algorithm discovered can be easily be accommodated. Let’s see the code.

Hashing algorithm using strategy pattern

Second example is classic example which is used to explain strategy pattern and the example is of hashing. Let’s say, we are writing a hash function. At the time of design, we zeroed in on MD5 as our hashing function and we neatly defined and released function. Our function is so good that it is being used in so thousands of clients. Definition of our hash function is something like this:

Things go wrong when one fine day we find that MD5 hashing function has a flaw or MD5 hashing is not what we want. We deliberate and come up with another algorithm to be used say SHA256. And this leads to change to our hash function which we neatly written early. Now, our hashing function becomes:

Problem with above solution is that we still need to support MD5 implementation because, as I said, code has been already released and there are thousands of clients using that. We cannot afford to change all those clients, hence need to support the older API too. Well, we salvaged the situation. But thing to ponder is what if there comes another hashing algorithm which is more efficient than Md5 and SHA256 and we want to change our function and support all legacy implementation and usages. With the golden rule, that if code can change, encapsulate it, and what better way than interface to encapsulate things. We defined an interface let’s say IHasher with one function named hash().
Our earlier Hashing function now takes two parameters, one input to be hashed and other IHasher object. Implementation becomes:
We now create a class for each of the hashing algorithm and class implements IHasher interface.
And now, we call hash(“test String”, new MD5Hasher()) instead of hash(“test string”). However, if need to change MD5 to SHA256, we still need to replace all call with MD5Hasher() with SHA256Hasher(). Again maintenance nightmare. To avoid that we will create and pass objects as IHasher and not of actual class as shown in code below and there is no problem no matter how many times our algorithm changes. We don’t need to change our code. We add another class for that algorithm which implements IHasher interface and we are done. We that is principle is called as open for extension but not for modification. Our core logic remains same, still we can extend it to as many hashing algorithms we can thing of.

Payment Method using strategy pattern

Last example is related payment method. We have a shopping cart and then we have to associate a payment method to that cart. Payment method can be credit card or net banking or Cash on Delivery. To encapsulation of payment method, we will define an interface IPaymentMethod. 

Now we implement class one each for payment method and then a test class to verify that correct payment method is used.


I think no need to explain this example,as it is quite self-explanatory.

As per Gang of Four Strategy patterns book, use strategy pattern when:

  1. Many related classes differ only in behaviour. Strategies provide a way to configure a class with one of many behaviour.
  2. You want different variants of same algorithm, like MD5 and SHA256 variants of hashing algorithm.
  3. Algorithm uses some data which should not be exposed to client. Pattern provides a way to hide complex and algorithm specific data to clients.
  4. A class define many behaviour and that appears as if-else block.                        To conclude, we today understood what is strategy design pattern and when to apply it. We also discussed some examples which are good candidates for application  of strategy pattern.

Design patterns : builder pattern

Today we will discussing a very important pattern in design pattern called as builder pattern, there are class of problem which can be solved using this pattern effectively and efficiently without cluttering the client code which uses those classes.

First of all let’s understand why we need builder pattern and what pattern they solve.

Typical way to instantiate a class is to use its constructor. A constructor is set of instructions which sets up the object for you with a specific state to start with. As we all know, a constructor can take parameters to it. If no constructor is defined for class, instantiate using default constructor which does not take any input parameter. Constructors with parameter set values for the member variables of class. However, many a times only a few member variables of class are mandatory at the time of object creation. Rest all are optional.  So, how do we create an object of such class?  We cannot have constructor with only parameters corresponding to mandatory member variables, as in some cases optional variables are also required to create object correctly.

Example of such a class which has some mandatory and rest optional member variables is FoodItem. It can have some mandatory members like MRP, Manufacturing date, Batch number, and some optional members like nutrients like total fat, saturated fat, trans fat, cholesterol, sodium, MSG, proteins and so on. Not every FoodItem object should have values for total fat, saturated fat, trans fat, cholesterol, sodium or MSG or proteins.

There are two ways to solve this problem part from builder pattern. Let’s look at them  before we move to builder patterns.

Telescoping constructor

First one is to create telescoping constructors. In this we create a default constructor, a constructor with all mandatory member variables and then create a constructor adding each optional variable to it. First constructor with one optional parameter, second with two, third with three and so on. So there are four mandatory and 20 optional, we would end up creating 1 + 20 constructor for the class. While creating object, one need to call constructor with minimum parameters matching the requirement. Many times the constructor with more number of parameters needs to be used because you want to set optional parameter which is after non required parameter in constructor parameter list. In that case, all non required optional parameters are set to zero. This makes code very unmanageable on the client side who needs to create objects of you class.

Telescopic constructor pattern solves problem where one need to send parameters which are not required for object creation. However, it comes with a caveat, if two parameters next to each other are same type, then putting values for one parameter in other is a common mistake and will not result in compile time warning, but may not create desired object. This method is not scalable.

Setter method

Second method is to have a constructor with mandatory members and the a setter function for each parameter. At the time of object creation, only mandatory parameters are passed and setter methods are used to set values for required optional parameters.

There are some problems with this approach. One, use of setter, makes your class mutable. So beware of using this kind of objects in multi-threaded applications. Second, during creation of object, there are intermediate states of object before the final object is created. However, the object can be used by other threads before setters of optional values are executed and a incomplete object is seen by the new thread.

Builder pattern

There is third way which comes with best of above two and deals with disadvantages of them too. This pattern is called as build pattern. In this pattern, we create a static member class of our class called as builder. First we create a builder class with all the mandatory parameters and the using that object set values of optional fields and then finally call build function which creates the object of our class. Let’s take the same example as above and use builder pattern to create an object.

Client Code :There are two advantages of this approach : First we are not putting setter function on member variables of class but on builder class which makes our class as immutable. Second advantage is our final object is created in on instruction, and not in series of instructions like in second method, so there is no risk of inconsistent copies object in different threads.

This is not the only use of builder pattern. Many a times we need to create an object but the contents of those object can be different. For example, one wants to create a Menu for a fast food restaurant which offer meals. Now,meals can be veg and no-veg. Based on request either meal object contains veg dishes or non-veg dishes. Here we have to create an same object but with slight difference. This cannot be achieved by using constructor as in constructor we need to pass all the member variable and in this case one of the variable will be not use either veg or non-veg item.

This is where builder comes into play. We create a builder which returns us a meal based on inputs we have given. It combines items into meal and return that back. Let’s take an example and see.

We have veg meal which contain a veg burger and a cold drink. Non veg meal has chicken burger and ice tea.

First of all, we will create an interface which will be implemented by the solid food and drink as well.
Create a class burger which implements above interface and extend it to create veg burger and chicken burger. Cool that is first part! Similarly we can create a class drink and based on type of meal we can create object with appropriate values.

Veg burger class
Chicken Burger class

Now, create a cold drink class which implements FoodItem interface and extend it to create classes Pepsi and Ice Tea.
Pepsi class

Ice Tea class
Now we create a builder which creates meals for us using these objects.

To use this build, we write a client code which creates veg meal and non-veg meal based on requirement.

There are some disadvantages with builder pattern, first being lot of extraneous code, it may be possible that developer skips adding any of new field into builder and problems occur. However, the best advantage that it keeps class as immutable given multi-threaded world we live in, overcomes the extra lines of code which is being written.