Saturday, July 27, 2019

Command Pattern

Command pattern is a behavioral pattern. This pattern allows us to encapsulate a request(receiver, methods, arguments) inside an object, and thus client code can be made free of specific implementations of receiver types, thus decoupling the code.

Suppose we have a class with a method, say performAction(). This method receives an object as argument and has a basic responsibility of interacting with object. Object belongs to a group of objects. These objects get some work done, but unfortunately they don't have a common interface. Instead they have different set of methods to be invoked from performAction(). A very naive implementation of performAction() can be like:


In this implementation, client code is strongly coupled with specific implementation types rather than interface and hence it reduces code flexibility. If there are new types of objects in the system in future for with to deal with, this code would undergo change. This violates 'O' of 'SOLID' principles, and is a source of possible bugs.

Command pattern enables us to get rid of such code implementation and instead we encapsulate requests in objects we call as Command and client code then parametrize invoker(performAction()) with a Command object. We can now dynamically set the Command object, making performAction() interact with different types of object without having this sort of strongly coupled code.

Basically, when we want to decouple an object from making requests to objects which actually perform those requests, we use Command pattern.

Code structure



Command is an interface which has a single method, execute(). Client creates ConcreteCommand which is a specific implementation of Command, and sets Receiver in it. Receiver is the object which contains the actual actions. Invoker has a method setCommand() which Client uses to set Command. It also contains method performAction() which Client calls later on as needed. It is this method which invokes execute() on Command object.
ConcreteCommand basically represents the encapsulation of the request, as it contains the Receiver object and in its execute() it invokes all the required methods of Receiver needed to compete the command.
We can have different concrete Command implementations containing same type of Receiver. They would differ in their invocation of methods on Receiver.

Making use of Command pattern ensures that conditional code from invoker method is no more there and that logic is now expressed in form of different concrete command implementations.

Another way of looking at Command pattern is that it allows us to package a computation(receiver object and actions on it) in an object and pass it around as first class object. Hence, we can invoke computations away from its original point of creation, both in terms of time and space. For example, we can create it in one thread, move it around and then invoke it in another thread. This idea can be applied to many useful use cases like schedulers, thread pools, job queues.

For example, we can implement a queue to which we can add Command objects at one end, and on other end Threads can remove those objects one by one and call execute() method on them. Queue implementation in itself is totally decoupled from the computation aspects. It just acts as a conduit. Thread object just needs to invoke execute() on receiver and it has no other coupling with it. So as long as objects added to queue implement Command interface, we can be sure that execute() method would be invoked on them whenever a Thread is available to remove them from the queue.

Undoing

If our use case is to also support undoing what execute did, then we can add undo() method to Command interface, and in concrete implementation we can then call appropriate method on receiver object in undo().

Example


Runnable interface is a perfect example of Command pattern. Runnable interface corresponds to Command interface in UML diagram above. It has method run() which maps to execute(). We provide concrete implementation for Runnable which corresponds to ConcreteCommand in diagram.



Client code instantiates the concrete Runnable and handover it to a Thread which becomes the Invoker. Client can either set a Receiver explicitly in concrete Runnable or we can have the logic embedded inside run() itself. Thread's start method maps to performAction() in UML diagram above.



What we may not like


If there are many commands in the application, it would lead to too many command classes, and naturally more maintenance efforts.

Saturday, July 20, 2019

Factory Method Pattern

Factory Method Pattern is a creational pattern.

In a framework, we generally have classes representing abstractions and framework needs to manage relationships between objects of these classes, and also creation of these objects. Clients extend these abstract classes for specific implementations. Problem here is that framework only knows abstract classes and not their concrete implementations.

Factory Method Pattern provides a solution to this problem. This pattern allows us to define an interface to create an object, but lets subclasses decide how to implement the interface, thus deferring instantiation to subclasses.
It encapsulates the knowledge of which specific implementations needs to be instantiated and moves this knowledge out of the framework.

Factory Method approach


An abstract method is defined in the abstract creator class. This method is supposed to have the responsibility of creating instances of appropriate product classes. Subclasses of abstract creator class then implement this method to implement creation of  instances of specific products.

We use Factory Method pattern when:
  • A class don't know about specific implementations it need to instantiate
  • A class wants its subclasses to decide which type of objects to be instantiated

Code structure


Code structure we need to implement Factory Method pattern is as follows:

We define an abstract class Creator which contains an abstract factory method. This factory method has contract of returning an instance of type Product, which is another abstract class.
In subclass of  Creator, like CreaotrA and CreatorB, we implement the factory method. Specific implementation creates instance of specific implementation of Product, like ProductA or ProductB.

Consequence of this code structure is that client code(like 'someOperation' method in Creator) is decoupled from concrete implementations of Product as well as creation logic, and it has to deal only with Product interface. Subclasses of Creator are in full control of which type of Product to create without client code being impacted if there are any changes in creation logic.

Basically what we achieve here is to separate object creation logic from the code which uses that object. So down the line object creation knowledge may undergo a change but client code is decoupled from this change. This makes client code adhere to 'O' of SOLID principles.

Also, factory method pattern is one of the way we can implement 'D' of SOLID principles. As now high level component('someOperation' in Creator) does not depend on low level component(different implementations of Product), instead both now depend on abstraction(Product), and thus it introduces 'Dependency Inversion' in our code.

We can have factory method parametrized. This means that method would take an input parameter and use it to decide which product to create. It's a good practice to use enums as parameters to make sure that parameters are type safe.


Parallel class hierarchies


Another way of looking at it is that we encapsulate creation knowledge of a certain type of products into their respective creator. This helps in maintaining parallel class hierarchies. For example, in above UML diagram CreatorA is responsible for creating instances of ProductA, while CreatorB is reposnsible for creating instances of ProductB. Both creators are subclasses of Creator while both products are subclasses of Product. So we have two parallel class hierarchies evolving here and factory method is the connection between them.

What we may not like about Factory Method?


If a new type of Product has to be instantiated and existing Creator implementations are not a good fit to create it, then we may have to create a new Creator subclass for it. This is a bit of overhead just to instantiate a new type of Product.


Saturday, July 13, 2019

Decorator pattern

Decorator pattern falls under category of structural patterns. Purpose of Decorator pattern is to enable us to add additional features to an object dynamically at run time.

Why not subclassing?


One may argue to make use of subclassing an existing class to add additional features/functionalities to our class, and hence to its objects. This is in fact a well practiced approach, but it has some disadvantages apart from strong coupling between parent and child class.
First, parent class behaviour is added to all objects of the child class which may not be desired. Second, a behavior inherited from a parent class is locked into child class at compile time, and hence we can't influence the time at which we actually want object to have a particular behaviour.
Another major disadvantage can be that if there is scope for a large number of combinations of these behaviours in our system and we make classes for all possible combinations, then it may lead to class explosion, leading to huge maintenance problem.

Decorator pattern


Decorator pattern enables us to add additional features/responsibilities to the objects at run time in a very flexible manner. We can decide which behaviour to be added, when to be added, how to be added.

Decorator approach


Target object which we want to have a specific feature is wrapped inside another object having that feature. Enclosing object is called decorator, and importantly it has same interface as target object so that client code can invoke same interface. When client sends a request, decorator object forwards that request to target object and additionally add its own action(decoration) before or after it. Multiple decorators can be applied recursively, hence allowing to add as many features as we want.
We define the interface of the target object/class. And we define an abstract Decorator class which implements this interface, so now it has same interface as target object and client can invoke calls on it transparently.This abstract class also contains the reference to target object. We implement concrete classes for Decorator,wherein we direct client requests to target object.And while it does so,it also performs the 'decoration'.

Please keep in mind that all class based inheritance done here is just to make sure that a common interface is maintained across all objects involved in the process. Hence, we don't suffer from the disadvantages we discussed above in context of subclassing.

Code structure


Lets look into code structure we need to have to implement Decorator pattern.

UML diagram is as follows:



First, we have a class to define a common interface to be used by clients transparently:


We implement functionality in a class:

Our aim is to add additional features to objects of  SimpleComponent at run time.

So we define an abstract decorator class:


Now we add specific decorators:

Lets now put it all together and see how it works:

Running this program would give following output:
Core functionality implemented here
Decoration done by DecoratorB
Decoration done by DecoratorA

So, we are able to add behaviours to target object dynamically. If needed, we can add additional features as and when we want, thus handing lots of flexibility to our system.

Example


java.io package can be looked into to see working example of Decorator pattern.

InputStream is an abstract class and is super class for all classes representing an input stream of bytes. It has an abstract method read() which every subclass needs to implement. This class can be mapped to Component class in UML diagram above.

There are several concrete implementations of InputStream, like FileInputStream which reads bytes from a file in the file system. FileInputStream can be mapped to SimpleComponent in our UML diagram.

There is another class, FilterInputStream. This class extends InputStream and contains some other input stream, which it uses as basic source of bytes, and possibly transforms the data or provides additional functionality. It can be mapped to Decorator class in UML diagram.

Finally, there are classes which extend FilterInputStream, like BufferedInputStream. This class adds functionality of buffering the input data.

So, if we need to read data from a file one character at a time:


What we may not like about Decorator?


A quite obvious downside of Decorator pattern is that sometimes it leads to too many small classes in the system which makes it easy to understand and debug.