Sunday, November 29, 2015

A quick note on design patterns


This post is a digest of multiple sources in the reference list. Figures and texts are freely borrowed from the references. Modifications are made only when necessary.

Adapter. Convert the interface of a class into another interface that the clients expect. Adapter lets classes work together that could not otherwise because of incompatible interfaces. Basically, this is saying that we need a way to create a new interface for an object that does the right stuff but has the wrong interface.
In the above figure, the Adapter adapts the interface of an Adaptee to match that of Target, which is the class the Adapter derives from. This allows the Client to use the Adaptee as if it were a Target.

Facade. Provide a unified interface to a set of interfaces in a complex system. Basically, this is saying that we need to interact the system in a particular way (such as using a 3D drawing program in a 2D way). Facade defines a higher-level interface that makes the system easier to use.
Note that most of the work in a Facade still needs to be done by the underlying system. The Facade only provides a collection of easier-to-understand methods. These methods use the underlying system to implement the newly defined functions.

Adapter v.s Facade Both Adapter and Facade are wrapper patterns. However, there are at least two major differences between them: a) In most applications, Facade hides multiple classes behind it whereas Adapter only hides one. b) The motivation of Facade is to simplify an interface, while Adapter converts an interface into another without emphasizing on simplification.

Strategy. Define a family of algorithms, encapsulate each one, and make them interchangeable in the context. Being able to plug in different implementations for an operation is a common requirement in many situations. For example, being able to use different encryption and decryption algorithms, or different algorithms for breaking a stream of text into lines. Strategy pattern lets the implementations be selected as required, or vary independently from clients that use it.
In the above figure, Strategy specifies how the different algorithms are used. ConcreteStrategies implement these different algorithms. Context uses a specific ConcreteStrategy with a reference of type Strategy. Strategy and Context interact to implement the chosen algorithm. The Context forwards requests from its client to Strategy, and Strategy may query Context for information.

Bridge. Decouple an abstraction from its implementation so that the two can vary independently. "Implementations" here means the objects that the abstract class and its derivations use to implement themselves, not the derivations of the abstract class, which are called concrete classes.
In the above figure, Abstraction defines the interface for the objects being implemented. Implementation defines the interface for the specific implementation classes. Classes derived from Abstraction use classes derived from Implementation without knowing which particular concrete implementation is in use.

Abstract Factory. Provide an interface for creating families of related or dependent objects without specifying their concrete classes. This pattern isolates the rules of which objects to use from the logic of how to use these objects. The term "abstract" suggests that you define an abstract class that specifies which objects are to be made, and then implement one concrete class for each family.


Flyweights. Allow fine-grained objects to be shared, avoiding the expense of multiple instances. In many applications, a large number of small objects may be created, referenced briefly and then discarded at runtime. If these objects are essentially the same, and particularly if they share state information and are immutable, then it is beneficial to offer a mechanism to allow these objects to be easily shared and reused.
For example, Java strings are immutable objects that are treated as flyweights. Hence, one string “John” is shared between all the references to that string by the JVM (see also: string interning).

Proxy. Make use of a surrogate or placeholder for another object allowing controlled access to that object or for that object to be created lazily. Utilizing the Proxy pattern allows standardized access to the service ensuring that all client code accesses the service in the appropriate manner.

Command. Encapsulates behavior into an object so that it can be selected, sequenced, queued, done and undone, submitted to clients for execution (locally or remotely) and otherwise manipulated.
In the above diagram, the Command declares an interface for executing an operation. The ConcreteCommand defines a binding between a Receiver object and an action. The Client creates a ConcreteCommand object and sets its receiver, which should know how to perform an action associated with a request. Commands are executed by invoking the corresponding operations on the Receiver object.

Mediator. Define an object that represents a common communication mechanism, that allows a set of objects to interact, without those objects needing to maintain links to each other. It therefore promotes a loosely coupled, but high cohesive communication infrastructure without each object need to maintain a reference to all the other objects.
Object oriented design encourages the distribution of behaviour among objects. However, this can lead to a multiplicity of links between objects. In the worst case every object needs to know about/link to every other object. This can be a problem for maintenance and for the reusability of the individual classes. These problems can be overcome by using a mediator object. In this scheme, other objects are connected together via a central mediator object in a star like structure. The mediator is then responsible for controlling and coordinating the interactions of the group of objects.
Mediator vs. Proxy Both serves as an intermediate object between a client and a service. However, Proxy is a one-to-one mapping and thus the client has to maintain links to each of the proxies it is working with.
Mediator vs. Facade Both offer an abstraction over complex interactions. However, Mediator is multi-directional while Facade is unidirectional.

References

1. Design Patterns Explained, 2nd ed. by Alan Shalloway and James R. Trott.
2. Scala Design Patterns, 2013th ed. by John Hunt.
3. Design Patterns, 1st ed. by the GoF.
4. http://www.cs.mcgill.ca/~hv/classes/CS400/01.hchen/doc/
5. https://javaobsession.wordpress.com/design-patterns/