Thursday, August 7, 2014

Design Patterns - Series I

Was going through the book ‘Head First Design Patterns’, came up with my own examples to understand them further. Try downloading the code and see if it helps you in comprehending these in a better way.

Observer Pattern [Sample Code]
Observer Pattern, as the name suggests, is used in scenarios when updates need to be done at multiple points (Observers) depending on changes in state at another place (Subject). Each of the Observers has to register themselves with the Subject, individually. The Subject should also provide method which allows the Observers to remove themselves. Registered Observers are informed of changes in state through a notify method, usually.

The provided example is that of a StockBroker application, which involves maintenance of various types of financial information. Subject is the interface in the application which provides a template for the Observed class. StockData is the concrete implementation of Subject and provided implementation of addObserver(), removeObserver() and notifyObservers(). Additionally, it maintains a list of registered observers. IncomeHandler, InvestmentHandler and PortfolioHandler are the various observers used to maintain income, investment and portfolio of a specific StockBroker. All these depend on the constantly fluctuating values of stocks. They are specifically interested in the stockSymbol, stockValue and stockUnits of each individual stock. Each of the observers implements the interface Observer. The Observer interface provide the update() method, which is implemented by each of these concrete classes.

Use to run the application, Try adding your own observer to this application. Also, you can try picking up these values from a live web service and then writing a custom observer which depends on this.

Decorator Pattern [Sample Code]
Decorator Pattern provides an elegant way to use composition for enhancing functionality, where the result expected has direct dependency on the composed and composing class. A chain relation (via composition) or decoration can be finally used to achieve the desired output at runtime. In real-time, when the functionality of one particular product is expected to be built form a base product and various other related sub-products or fixtures, we can rely on the Decorator.

The attached example is that of a Pizza application. Here, the pizzas in the shop are made with various combinations of bases and topping combinations. This is a classical example for usage of the decorator pattern. Pizza is the abstract base class for each of the pizza bases to implement and ToppingDecorator is another abstract class that inherits from Pizza for each of the toppings to implement. Hawaiian, Italian and Mexican are the concrete implementation of Pizza whereas Mushroom, Onion and Chicken are the concrete implementations of ToppingDecorator. Each of these toppings encapsulates a Pizza instance. This instance, at runtime, will hold another topping or the pizza base instance. Finally, it is when the cost has to be calculated on the entire pizza that the real value of decorator pattern is seen and just one call suffices to calculate the entire bill value.

PizzaWorld is the main class. Try adding more decorators and pizza base classes to see if you can get a real taste of the Decorator!

Singleton Pattern
Singleton Pattern defines a way to maintain only single instance of a class in the entire execution of a program/application and to provide a uniform way to access it. There are numerous methods which exist in which this pattern can be implemented. I have explained three most common scenarios here:

1. Eager Singleton [Sample Code]
The simplest singleton is the one in which the instance is created at class-load time, and stored in a static instance variable. A static getter method is then used to get this instance, when required. The instantiation of an object earlier than its first use might not be a recommended approach.

In the given example, MediaContract (Main Thread) works on an instance of the ProductionHouse (Singleton). The Singleton is instantiated at class-load time and maintained in the private static instance variable. getInstance() in ProductionHouse helps in retrieving the instance.

2. Thread-Safe Singleton (Most Common) [Sample Code]
To overcome the above drawback, the recommended approach is to instantiate the object at the first access time and also to make it thread-safe to prevent concurrent thread instantiation. The disadvantage of this method is poorer performance, as the method is synchronized.

As in the earlier example, the classes are MediaContract (Main Thread) and ProductionHouse (Singleton). getInstance() method is synchronized and the instance is created only if it is null.

3. Double-checked Locking [Sample Code]
The disadvantage mentioned above can be critical for a highly accessed object in an application. To better this, the scope of the synchronized block is reduced to affect only the first access. This again has some disadvantages. I recommend reading on Initialization on Demand Holder Idiom.

The example remains the same, the difference being in the reduced scope of synchronisation within the getInstance() method and also that it affects only the first access and not subsequent accesses.

Command Pattern [Sample Code]
In scenarios, where we need to create a sequence of actions (or operations) and perform them at a specified (later) point in time, we have a candidate for usage of Command Pattern. Though it very closely resembles the Observer pattern in implementation, the usage is different and the command (actions) is invoked only on a single chosen receiver by an invoker, than on all observers.

The example is of an Auction House where there are various items for auction, the base abstract class of which is represented by AuctionItem. The abstract method to be implemented by implementing classes is sell(). AuctionVase, AuctionFurniture and AuctionJewel are all concrete implementations of AuctionItem. Instances of each of these are created and set (mapped by an itemKey) into the AuctionControl, which can be thought of as a remote control for presenting items in the AuctionStore. Whenever the presentItem() is invoked on the AuctionControl class, passing in an itemKey, the appropriate AuctionItem instance is selected and sell() is invoked on this instance.

Factory Pattern
Factory Pattern, I am made to believe, is the most widely used and implemented pattern in software projects after the Singleton Pattern. Since Singleton is only a creational pattern at single class level, the scale of the effect of usage of Factory should be much higher. Factory Pattern deals with creation of similar type of objects and production in a centralized manner, depending on the condition or type of object requested. There are variations of the usage of factory pattern, three of which I have enlisted below:

1. Simple Factory [Sample Code]
The simplest factory is the one that is used to create (instantiate) a specific type of product (object) depending on a condition. The specific types of objects that can be created in a single factory are all expected to implement a single interface.

In the attached example, the factory is used to instantiate a specific type of object depending on the operating system. All the specific systems implement the System interface, which defines the common methods that the concrete class of this type should implement. SystemFactory is the factory class which provides the create() method which takes a type argument. The type argument decides which concrete factory should be instantiated.

2. Factory Method [Sample Code]
When there can be various families of products (objects) that which can be instantiated, but each family of these product needs to be created by a specific type of factory, we define a factory method in the base factory class. The concrete implementations of the base factory then override this method to produce concrete type of products, depending on the condition.

In the example, you can notice the presence of two abstract classes, Mobile (Product) and MobileStore (Creator). One family of concrete product implementations are NokiaASeries, NokiaBSeries and NokiaCSeries to be created by the NokiaStore, which is the concrete implementation of the creator. In similar fashion another family of products such as SonyASeries, SonyBSeries and SonyCSeries are to be created by SonyStore, another concrete implementation of MobileStore. MobileStoreCentre is the main class to run this application. The createMobile() method is the abstract method (factory method) that is to be overridden by the creator implementations.

3. Abstract Factory [Sample Code]
AbstractFactory defines a template or interface for creation of similar types of objects or implementations. Usually, AbstractFactory will encapsulate a factory method or more within for actual creation of the product.

Taking the same example as above, MobileStoreFactory instantiates the concrete instance of the abstract factory (MobileStore) based upon the variable specified, either "Nokia" (NokiaStore) or "Sony"(SonyStore). The factory is then responsible for creating the objects of similar types based upon the choice - such as "ASeries" or "BSeries" or "CSeries". The mobile is then assembled based upon this by the MobileStore. You may use MobileStoreCentre to run this example and understand the design pattern based on the output.

No comments: