Behavioral Patterns

Behavioral patterns are those which are concerned with interactions between the objects. The interactions between the objects should be such that they are talking to each other and still are loosely coupled. The loose coupling is the key to n-tier architectures. In this, the implementation and the client should be loosely coupled in order to avoid hard-coding and dependencies.

In software engineering, behavioral design patterns are design patterns that identify common communication patterns between objects and realize these patterns. By doing so, these patterns increase flexibility in carrying out this communication.

  • Chain of responsibility
    A way of passing a request between a chain of objects
  • Command
    Encapsulate a command request as an object
  • Interpreter
    A way to include language elements in a program
  • Iterator
    Sequentially access the elements of a collection
  • Mediator
    Defines simplified communication between classes
  • Memento
    Capture and restore an object’s internal state
  • Null Object
    Designed to act as a default value of an object
  • Observer
    A way of notifying change to a number of classes
  • State
    Alter an object’s behavior when its state changes

  • Strategy
    Encapsulates an algorithm inside a class
  • Template method
    Defer the exact steps of an algorithm to a subclass
  • Visitor
    Defines a new operation to a class without change

Rules of thumb

  1. Behavioral patterns are concerned with the assignment of responsibilities between objects, or, encapsulating behavior in an object and delegating requests to it.
  2. Chain of responsibility, Command, Mediator, and Observer, address how you can decouple senders and receivers, but with different trade-offs. Chain of responsibility passes a sender request along a chain of potential receivers. Command normally specifies a sender-receiver connection with a subclass. Mediator has senders and receivers reference each other indirectly. Observer defines a very decoupled interface that allows for multiple receivers to be configured at run-time.
  3. Chain of responsibility can use Command to represent requests as objects.
  4. Chain of responsibility is often applied in conjunction with Composite. There, a component’s parent can act as its successor.
  5. Command and Memento act as magic tokens to be passed around and invoked at a later time. In Command, the token represents a request; in Memento, it represents the internal state of an object at a particular time. Polymorphism is important to Command, but not to Memento because its interface is so narrow that a memento can only be passed as a value.
  6. Command can use Memento to maintain the state required for an undo operation.
  7. MacroCommands can be implemented with Composite.
  8. A Command that must be copied before being placed on a history list acts as a Prototype.
  9. Interpreter can use State to define parsing contexts.
  10. The abstract syntax tree of Interpreter is a Composite (therefore Iterator and Visitor are also applicable).
  11. Terminal symbols within Interpreter’s abstract syntax tree can be shared with Flyweight.
  12. Iterator can traverse a Composite. Visitor can apply an operation over a Composite.
  13. Polymorphic Iterators rely on Factory Methods to instantiate the appropriate Iterator subclass.
  14. Mediator and Observer are competing patterns. The difference between them is that Observer distributes communication by introducing “observer” and “subject” objects, whereas a Mediator object encapsulates the communication between other objects. We’ve found it easier to make reusable Observers and Subjects than to make reusable Mediators.
  15. On the other hand, Mediator can leverage Observer for dynamically registering colleagues and communicating with them.
  16. Mediator is similar to Facade in that it abstracts functionality of existing classes. Mediator abstracts/centralizes arbitrary communication between colleague objects, it routinely “adds value”, and it is known/referenced by the colleague objects (i.e. it defines a multidirectional protocol). In contrast, Facade defines a simpler interface to a subsystem, it doesn’t add new functionality, and it is not known by the subsystem classes (i.e. it defines a unidirectional protocol where it makes requests of the subsystem classes but not vice versa).
  17. Memento is often used in conjunction with Iterator. An Iterator can use a Memento to capture the state of an iteration. The Iterator stores the Memento internally.
  18. State is like Strategy except in its intent.
  19. Flyweight explains when and how State objects can be shared.
  20. State objects are often Singletons.
  21. Strategy lets you change the guts of an object. Decorator lets you change the skin.
  22. Strategy is to algorithm. as Builder is to creation.
  23. Strategy has 2 different implementations, the first is similar to State. The difference is in binding times (Strategy is a bind-once pattern, whereas State is more dynamic).
  24. Strategy objects often make good Flyweights.
  25. Strategy is like Template method except in its granularity.
  26. Template method uses inheritance to vary part of an algorithm. Strategy uses delegation to vary the entire algorithm.
  27. The Visitor pattern is like a more powerful Command pattern because the visitor may initiate whatever is appropriate for the kind of object it encounters.

The behavioral patterns are:

Patterns.
1. Chain of Resposibility Pattern

The chain of responsibility pattern is based on the same principle as written above. It decouples the sender of the request to the receiver. The only link between sender and the receiver is the request which is sent. Based on the request data sent, the receiver is picked. This is called “data-driven”. In most of the behavioral patterns, the data-driven concepts are used to have a loose coupling.

The responsibility of handling the request data is given to any of the members of the “chain”. If the first link of the chain cannot handle the responsibility, it passes the request data to the next level in the chain, i.e. to the next link. For readers, familiar with concepts of Java, this is similar to what happens in an Exception Hierarchy. Suppose the code written throws an ArrayIndexOutOfBoundsException. Now, this exception is because of some bug in coding and so, it gets caught at the correct level. Suppose, we have an application specific exception in the catch block. This will not be caught by that. It will find for an Exception class and will be caught by that as both the application specific exceptions and the ArrayIndexOutOfBoundsException are sub-classes of the class Exception.

Once get caught by the exception, which is the base class, it will then not look for any other exception. This is precisely the reason why, we get an “Exception is unreachable” message when we try to add a catch block with the exception below the parent exception catch block.

So, in short, the request rises in hierarchy till some object takes responsibility to handle this request.

It’s the same mechanism used for multi-level filtration. Suppose, we have a multi level filter and gravel of different sizes and shapes. We need to filter this gravel of different sizes to approx size categories. We will put the gravel on the multi-level filtration unit, with the filter of maximum size at the top and then the sizes descending. The gravel with the maximum sizes will stay on the first one and rest will pass, again this cycle will repeat until, the finest of the gravel is filtered and is collected in the sill below the filters. Each of the filters will have the sizes of gravel which cannot pass through it. And hence, we will have approx similar sizes of gravels grouped.

2. Command Pattern

This is another of the data-driven pattern. The client invokes a particular module using a command. The client passes a request, this request gets propagated as a command. The command request maps to particular modules. According to the command, a module is invoked.

This pattern is different from the Chain of Responsibility in a way that, in the earlier one, the request passes through each of the classes before finding an object that can take the responsibility. The command pattern however finds the particular object according to the command and invokes only that one.

It’s like there is a server having a lot of services to be given, and on Demand (or on command), it caters to that service for that particular client.

A classic example of this is a restaurant. A customer goes to restaurant and orders the food according to his/her choice. The waiter/ waitress takes the order (command, in this case) and hands it to the cook in the kitchen. The cook can make several types of food and so, he/she prepares the ordered item and hands it over to the waiter/waitress who in turn serves to the customer.

3. Interpreter Pattern

Intent

  • Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.
  • Map a domain to a language, the language to a grammar, and the grammar to a hierarchical object-oriented design.

Problem

A class of problems occurs repeatedly in a well-defined and well-understood domain. If the domain were characterized with a “language”, then problems could be easily solved with an interpretation “engine”.

Discussion

The Interpreter pattern discusses: defining a domain language (i.e. problem characterization) as a simple language grammar, representing domain rules as language sentences, and interpreting these sentences to solve the problem. The pattern uses a class to represent each grammar rule. And since grammars are usually hierarchical in structure, an inheritance hierarchy of rule classes maps nicely.

An abstract base class specifies the method interpret(). Each concrete subclass implements interpret() by accepting (as an argument) the current state of the language stream, and adding its contribution to the problem solving process.

Structure

Interpreter suggests modeling the domain with a recursive grammar. Each rule in the grammar is either a ‘composite’ (a rule that references other rules) or a terminal (a leaf node in a tree structure). Interpreter relies on the recursive traversal of the Composite pattern to interpret the ‘sentences’ it is asked to process.

Scheme of Interpreter

Example

The Intepreter pattern defines a grammatical representation for a language and an interpreter to interpret the grammar. Musicians are examples of Interpreters. The pitch of a sound and its duration can be represented in musical notation on a staff. This notation provides the language of music. Musicians playing the music from the score are able to reproduce the original pitch and duration of each sound represented.

Example of Interpreter

4. Iterator Pattern

Intent

  • Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
  • The C++ and Java standard library abstraction that makes it possible to decouple collection classes and algorithms.
  • Promote to “full object status” the traversal of a collection.
  • Polymorphic traversal

Problem

Need to “abstract” the traversal of wildly different data structures so that algorithms can be defined that are capable of interfacing with each transparently.

Discussion

“An aggregate object such as a list should give you a way to access its elements without exposing its internal structure. Moreover, you might want to traverse the list in different ways, depending on what you need to accomplish. But you probably don’t want to bloat the List interface with operations for different traversals, even if you could anticipate the ones you’ll require. You might also need to have more than one traversal pending on the same list.” And, providing a uniform interface for traversing many types of aggregate objects (i.e. polymorphic iteration) might be valuable.

The Iterator pattern lets you do all this. The key idea is to take the responsibility for access and traversal out of the aggregate object and put it into an Iterator object that defines a standard traversal protocol.

The Iterator abstraction is fundamental to an emerging technology called “generic programming”. This strategy seeks to explicitly separate the notion of “algorithm” from that of “data structure”. The motivation is to: promote component-based development, boost productivity, and reduce configuration management.

As an example, if you wanted to support four data structures (array, binary tree, linked list, and hash table) and three algorithms (sort, find, and merge), a traditional approach would require four times three permutations to develop and maintain. Whereas, a generic programming approach would only require four plus three configuration items.

Structure

The Client uses the Collection class’ public interface directly. But access to the Collection’s elements is encapsulated behind the additional level of abstraction called Iterator. Each Collection derived class knows which Iterator derived class to create and return. After that, the Client relies on the interface defined in the Iterator base class.

Iterator example

Example

The Iterator provides ways to access elements of an aggregate object sequentially without exposing the underlying structure of the object. Files are aggregate objects. In office settings where access to files is made through administrative or secretarial staff, the Iterator pattern is demonstrated with the secretary acting as the Iterator. Several television comedy skits have been developed around the premise of an executive trying to understand the secretary’s filing system. To the executive, the filing system is confusing and illogical, but the secretary is able to access files quickly and efficiently.

On early television sets, a dial was used to change channels. When channel surfing, the viewer was required to move the dial through each channel position, regardless of whether or not that channel had reception. On modern television sets, a next and previous button are used. When the viewer selects the “next” button, the next tuned channel will be displayed. Consider watching television in a hotel room in a strange city. When surfing through channels, the channel number is not important, but the programming is. If the programming on one channel is not of interest, the viewer can request the next channel, without knowing its number.

Iterator example

Check list

  1. Add a create_iterator() method to the “collection” class, and grant the “iterator” class privileged access.
  2. Design an “iterator” class that can encapsulate traversal of the “collection” class.
  3. Clients ask the collection object to create an iterator object.
  4. Clients use the first(), is_done(), next(), and current_item() protocol to access the elements of the collection class.

Rules of thumb

  • The abstract syntax tree of Interpreter is a Composite (therefore Iterator and Visitor are also applicable).
  • Iterator can traverse a Composite. Visitor can apply an operation over a Composite.
  • Polymorphic Iterators rely on Factory Methods to instantiate the appropriate Iterator subclass.
  • Memento is often used in conjunction with Iterator. An Iterator can use a Memento to capture the state of an iteration. The Iterator stores the Memento internally.

5. Mediator Pattern

Intent

  • Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
  • Design an intermediary to decouple many peers.
  • Promote the many-to-many relationships between interacting peers to “full object status”.

Problem

We want to design reusable components, but dependencies between the potentially reusable pieces demonstrates the “spaghetti code” phenomenon (trying to scoop a single serving results in an “all or nothing clump”).

Discussion

In Unix, permission to access system resources is managed at three levels of granularity: world, group, and owner. A group is a collection of users intended to model some functional affiliation. Each user on the system can be a member of one or more groups, and each group can have zero or more users assigned to it. Next figure shows three users that are assigned to all three groups.

Mediator example

If we were to model this in software, we could decide to have User objects coupled to Group objects, and Group objects coupled to User objects. Then when changes occur, both classes and all their instances would be affected.

An alternate approach would be to introduce “an additional level of indirection” – take the mapping of users to groups and groups to users, and make it an abstraction unto itself. This offers several advantages: Users and Groups are decoupled from one another, many mappings can easily be maintained and manipulated simultaneously, and the mapping abstraction can be extended in the future by defining derived classes.

Mediator example

Partitioning a system into many objects generally enhances reusability, but proliferating interconnections between those objects tend to reduce it again. The mediator object: encapsulates all interconnections, acts as the hub of communication, is responsible for controlling and coordinating the interactions of its clients, and promotes loose coupling by keeping objects from referring to each other explicitly.

The Mediator pattern promotes a “many-to-many relationship network” to “full object status”. Modelling the inter-relationships with an object enhances encapsulation, and allows the behavior of those inter-relationships to be modified or extended through subclassing.

An example where Mediator is useful is the design of a user and group capability in an operating system. A group can have zero or more users, and, a user can be a member of zero or more groups. The Mediator pattern provides a flexible and non-invasive way to associate and manage users and groups.

Structure

Mediator scheme

09

Colleagues (or peers) are not coupled to one another. Each talks to the Mediator, which in turn knows and conducts the orchestration of the others. The “many to many” mapping between colleagues that would otherwise exist, has been “promoted to full object status”. This new abstraction provides a locus of indirection where additional leverage can be hosted.

Mediator scheme

Example

The Mediator defines an object that controls how a set of objects interact. Loose coupling between colleague objects is achieved by having colleagues communicate with the Mediator, rather than with each other. The control tower at a controlled airport demonstrates this pattern very well. The pilots of the planes approaching or departing the terminal area communicate with the tower rather than explicitly communicating with one another. The constraints on who can take off or land are enforced by the tower. It is important to note that the tower does not control the whole flight. It exists only to enforce constraints in the terminal area.

Mediator example

Check list

  1. Identify a collection of interacting objects that would benefit from mutual decoupling.
  2. Encapsulate those interactions in the abstraction of a new class.
  3. Create an instance of that new class and rework all “peer” objects to interact with the Mediator only.
  4. Balance the principle of decoupling with the principle of distributing responsibility evenly.
  5. Be careful not to create a “controller” or “god” object.

Rules of thumb

  • Chain of Responsibility, Command, Mediator, and Observer, address how you can decouple senders and receivers, but with different trade-offs. Chain of Responsibility passes a sender request along a chain of potential receivers. Command normally specifies a sender-receiver connection with a subclass. Mediator has senders and receivers reference each other indirectly. Observer defines a very decoupled interface that allows for multiple receivers to be configured at run-time.
  • Mediator and Observer are competing patterns. The difference between them is that Observer distributes communication by introducing “observer” and “subject” objects, whereas a Mediator object encapsulates the communication between other objects. We’ve found it easier to make reusable Observers and Subjects than to make reusable Mediators.
  • On the other hand, Mediator can leverage Observer for dynamically registering colleagues and communicating with them.
  • Mediator is similar to Facade in that it abstracts functionality of existing classes. Mediator abstracts/centralizes arbitrary communication between colleague objects, it routinely “adds value”, and it is known/referenced by the colleague objects (i.e. it defines a multidirectional protocol). In contrast, Facade defines a simpler interface to a subsystem, it doesn’t add new functionality, and it is not known by the subsystem classes (i.e. it defines a unidirectional protocol where it makes requests of the subsystem classes but not vice versa).

6. Momento Pattern

Intent

  • Without violating encapsulation, capture and externalize an object’s internal state so that the object can be returned to this state later.
  • A magic cookie that encapsulates a “check point” capability.
  • Promote undo or rollback to full object status.

Problem

Need to restore an object back to its previous state (e.g. “undo” or “rollback” operations).

Discussion

The client requests a Memento from the source object when it needs to checkpoint the source object’s state. The source object initializes the Memento with a characterization of its state. The client is the “care-taker” of the Memento, but only the source object can store and retrieve information from the Memento (the Memento is “opaque” to the client and all other objects). If the client subsequently needs to “rollback” the source object’s state, it hands the Memento back to the source object for reinstatement.

An unlimited “undo” and “redo” capability can be readily implemented with a stack of Command objects and a stack of Memento objects.

The Memento design pattern defines three distinct roles:

  1. Originator – the object that knows how to save itself.
  2. Caretaker – the object that knows why and when the Originator needs to save and restore itself.
  3. Memento – the lock box that is written and read by the Originator, and shepherded by the Caretaker.

Structure

Memento scheme

Example

The Memento captures and externalizes an object’s internal state so that the object can later be restored to that state. This pattern is common among do-it-yourself mechanics repairing drum brakes on their cars. The drums are removed from both sides, exposing both the right and left brakes. Only one side is disassembled and the other serves as a Memento of how the brake parts fit together. Only after the job has been completed on one side is the other side disassembled. When the second side is disassembled, the first side acts as the Memento.

Memento example

Check list

  1. Identify the roles of “caretaker” and “originator”.
  2. Create a Memento class and declare the originator a friend.
  3. Caretaker knows when to “check point” the originator.
  4. Originator creates a Memento and copies its state to that Memento.
  5. Caretaker holds on to (but cannot peek into) the Memento.
  6. Caretaker knows when to “roll back” the originator.
  7. Originator reinstates itself using the saved state in the Memento.

Rules of thumb

  • Command and Memento act as magic tokens to be passed around and invoked at a later time. In Command, the token represents a request; in Memento, it represents the internal state of an object at a particular time. Polymorphism is important to Command, but not to Memento because its interface is so narrow that a memento can only be passed as a value.
  • Command can use Memento to maintain the state required for an undo operation.
  • Memento is often used in conjunction with Iterator. An Iterator can use a Memento to capture the state of an iteration. The Iterator stores the Memento internally.

7. Observer Pattern

Intent

  • Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
  • Encapsulate the core (or common or engine) components in a Subject abstraction, and the variable (or optional or user interface) components in an Observer hierarchy.
  • The “View” part of Model-View-Controller.

Problem

A large monolithic design does not scale well as new graphing or monitoring requirements are levied.

Discussion

Define an object that is the “keeper” of the data model and/or business logic (the Subject). Delegate all “view” functionality to decoupled and distinct Observer objects. Observers register themselves with the Subject as they are created. Whenever the Subject changes, it broadcasts to all registered Observers that it has changed, and each Observer queries the Subject for that subset of the Subject’s state that it is responsible for monitoring.

This allows the number and “type” of “view” objects to be configured dynamically, instead of being statically specified at compile-time.

The protocol described above specifies a “pull” interaction model. Instead of the Subject “pushing” what has changed to all Observers, each Observer is responsible for “pulling” its particular “window of interest” from the Subject. The “push” model compromises reuse, while the “pull” model is less efficient.

Issues that are discussed, but left to the discretion of the designer, include: implementing event compression (only sending a single change broadcast after a series of consecutive changes has occurred), having a single Observer monitoring multiple Subjects, and ensuring that a Subject notify its Observers when it is about to go away.

The Observer pattern captures the lion’s share of the Model-View-Controller architecture that has been a part of the Smalltalk community for years.

Structure

Observer scheme

Subject represents the core (or independent or common or engine) abstraction. Observer represents the variable (or dependent or optional or user interface) abstraction. The Subject prompts the Observer objects to do their thing. Each Observer can call back to the Subject as needed.

Example

The Observer defines a one-to-many relationship so that when one object changes state, the others are notified and updated automatically. Some auctions demonstrate this pattern. Each bidder possesses a numbered paddle that is used to indicate a bid. The auctioneer starts the bidding, and “observes” when a paddle is raised to accept the bid. The acceptance of the bid changes the bid price which is broadcast to all of the bidders in the form of a new bid.

Observer example

Check list

  1. Differentiate between the core (or independent) functionality and the optional (or dependent) functionality.
  2. Model the independent functionality with a “subject” abstraction.
  3. Model the dependent functionality with an “observer” hierarchy.
  4. The Subject is coupled only to the Observer base class.
  5. The client configures the number and type of Observers.
  6. Observers register themselves with the Subject.
  7. The Subject broadcasts events to all registered Observers.
  8. The Subject may “push” information at the Observers, or, the Observers may “pull” the information they need from the Subject.

Rules of thumb

  • Chain of Responsibility, Command, Mediator, and Observer, address how you can decouple senders and receivers, but with different trade-offs. Chain of Responsibility passes a sender request along a chain of potential receivers. Command normally specifies a sender-receiver connection with a subclass. Mediator has senders and receivers reference each other indirectly. Observer defines a very decoupled interface that allows for multiple receivers to be configured at run-time.
  • Mediator and Observer are competing patterns. The difference between them is that Observer distributes communication by introducing “observer” and “subject” objects, whereas a Mediator object encapsulates the communication between other objects. We’ve found it easier to make reusable Observers and Subjects than to make reusable Mediators.
  • On the other hand, Mediator can leverage Observer for dynamically registering colleagues and communicating with them.

8. State Pattern

Intent

  • Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.
  • An object-oriented state machine
  • wrapper + polymorphic wrappee + collaboration

Problem

A monolithic object’s behavior is a function of its state, and it must change its behavior at run-time depending on that state. Or, an application is characterixed by large and numerous case statements that vector flow of control based on the state of the application.

Discussion

The State pattern is a solution to the problem of how to make behavior depend on state.

  • Define a “context” class to present a single interface to the outside world.
  • Define a State abstract base class.
  • Represent the different “states” of the state machine as derived classes of the State base class.
  • Define state-specific behavior in the appropriate State derived classes.
  • Maintain a pointer to the current “state” in the “context” class.
  • To change the state of the state machine, change the current “state” pointer.

The State pattern does not specify where the state transitions will be defined. The choices are two: the “context” object, or each individual State derived class. The advantage of the latter option is ease of adding new State derived classes. The disadvantage is each State derived class has knowledge of (coupling to) its siblings, which introduces dependencies between subclasses.

A table-driven approach to designing finite state machines does a good job of specifying state transitions, but it is difficult to add actions to accompany the state transitions. The pattern-based approach uses code (instead of data structures) to specify state transitions, but it does a good job of accomodating state transition actions.

Structure

The state machine’s interface is encapsulated in the “wrapper” class. The wrappee hierarchy’s interface mirrors the wrapper’s interface with the exception of one additional parameter. The extra parameter allows wrappee derived classes to call back to the wrapper class as necessary. Complexity that would otherwise drag down the wrapper class is neatly compartmented and encapsulated in a polymorphic hierarchy to which the wrapper object delegates.

State scheme

Example

The State pattern allows an object to change its behavior when its internal state changes. This pattern can be observed in a vending machine. Vending machines have states based on the inventory, amount of currency deposited, the ability to make change, the item selected, etc. When currency is deposited and a selection is made, a vending machine will either deliver a product and no change, deliver a product and change, deliver no product due to insufficient currency on deposit, or deliver no product due to inventory depletion.

State example

Check list

  1. Identify an existing class, or create a new class, that will serve as the “state machine” from the client’s perspective. That class is the “wrapper” class.
  2. Create a State base class that replicates the methods of the state machine interface. Each method takes one additional parameter: an instance of the wrapper class. The State base class specifies any useful “default” behavior.
  3. Create a State derived class for each domain state. These derived classes only override the methods they need to override.
  4. The wrapper class maintains a “current” State object.
  5. All client requests to the wrapper class are simply delegated to the current State object, and the wrapper object’s this pointer is passed.
  6. The State methods change the “current” state in the wrapper object as appropriate.

Rules of thumb

  • State objects are often Singletons.
  • Flyweight explains when and how State objects can be shared.
  • Interpreter can use State to define parsing contexts.
  • Strategy has 2 different implementations, the first is similar to State. The difference is in binding times (Strategy is a bind-once pattern, whereas State is more dynamic).
  • The structure of State and Bridge are identical (except that Bridge admits hierarchies of envelope classes, whereas State allows only one). The two patterns use the same structure to solve different problems: State allows an object’s behavior to change along with its state, while Bridge’s intent is to decouple an abstraction from its implementation so that the two can vary independently.
  • The implementation of the State pattern builds on the Strategy pattern. The difference between State and Strategy is in the intent. With Strategy, the choice of algorithm is fairly stable. With State, a change in the state of the “context” object causes it to select from its “palette” of Strategy objects.

9. Strategy Pattern

Intent

  • Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from the clients that use it.
  • Capture the abstraction in an interface, bury implementation details in derived classes.

Problem

One of the dominant strategies of object-oriented design is the “open-closed principle”.

Figure demonstrates how this is routinely achieved – encapsulate interface details in a base class, and bury implementation details in derived classes. Clients can then couple themselves to an interface, and not have to experience the upheaval associated with change: no impact when the number of derived classes changes, and no impact when the implementation of a derived class changes.

Strategy scheme

A generic value of the software community for years has been, “maximize cohesion and minimize coupling”. The object-oriented design approach shown in figure is all about minimizing coupling. Since the client is coupled only to an abstraction (i.e. a useful fiction), and not a particular realization of that abstraction, the client could be said to be practicing “abstract coupling” . an object-oriented variant of the more generic exhortation “minimize coupling”.

A more popular characterization of this “abstract coupling” principle is “Program to an interface, not an implementation”.

Clients should prefer the “additional level of indirection” that an interface (or an abstract base class) affords. The interface captures the abstraction (i.e. the “useful fiction”) the client wants to exercise, and the implementations of that interface are effectively hidden.

Structure

The Interface entity could represent either an abstract base class, or the method signature expectations by the client. In the former case, the inheritance hierarchy represents dynamic polymorphism. In the latter case, the Interface entity represents template code in the client and the inheritance hierarchy represents static polymorphism.

Strategy scheme

Example

A Strategy defines a set of algorithms that can be used interchangeably. Modes of transportation to an airport is an example of a Strategy. Several options exist such as driving one’s own car, taking a taxi, an airport shuttle, a city bus, or a limousine service. For some airports, subways and helicopters are also available as a mode of transportation to the airport. Any of these modes of transportation will get a traveler to the airport, and they can be used interchangeably. The traveler must chose the Strategy based on tradeoffs between cost, convenience, and time.

Strategy example

Check list

  1. Identify an algorithm (i.e. a behavior) that the client would prefer to access through a “flex point”.
  2. Specify the signature for that algorithm in an interface.
  3. Bury the alternative implementation details in derived classes.
  4. Clients of the algorithm couple themselves to the interface.

Rules of thumb

  • Strategy is like Template Method except in its granularity.
  • State is like Strategy except in its intent.
  • Strategy lets you change the guts of an object. Decorator lets you change the skin.
  • State, Strategy, Bridge (and to some degree Adapter) have similar solution structures. They all share elements of the ‘handle/body’ idiom. They differ in intent – that is, they solve different problems.
  • Strategy has 2 different implementations, the first is similar to State. The difference is in binding times (Strategy is a bind-once pattern, whereas State is more dynamic).
  • Strategy objects often make good Flyweights.

10. Template Pattern

Intent

  • Define the skeleton of an algorithm in an operation, deferring some steps to client subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.
  • Base class declares algorithm ‘placeholders’, and derived classes implement the placeholders.

Problem

Two different components have significant similarities, but demonstrate no reuse of common interface or implementation. If a change common to both components becomes necessary, duplicate effort must be expended.

Discussion

The component designer decides which steps of an algorithm are invariant (or standard), and which are variant (or customizable). The invariant steps are implemented in an abstract base class, while the variant steps are either given a default implementation, or no implementation at all. The variant steps represent “hooks”, or “placeholders”, that can, or must, be supplied by the component’s client in a concrete derived class.

The component designer mandates the required steps of an algorithm, and the ordering of the steps, but allows the component client to extend or replace some number of these steps.

Template Method is used prominently in frameworks. Each framework implements the invariant pieces of a domain’s architecture, and defines “placeholders” for all necessary or interesting client customization options. In so doing, the framework becomes the “center of the universe”, and the client customizations are simply “the third rock from the sun”. This inverted control structure has been affectionately labelled “the Hollywood principle” – “don’t call us, we’ll call you”.

Structure

Template Method scheme

The implementation of template_method() is: call step_one(), call step_two(), and call step_three(). step_two() is a “hook” method – a placeholder. It is declared in the base class, and then defined in derived classes. Frameworks (large scale reuse infrastructures) use Template Method a lot. All reusable code is defined in the framework’s base classes, and then clients of the framework are free to define customizations by creating derived classes as needed.

Template Method scheme

Example

The Template Method defines a skeleton of an algorithm in an operation, and defers some steps to subclasses. Home builders use the Template Method when developing a new subdivision. A typical subdivision consists of a limited number of floor plans with different variations available for each. Within a floor plan, the foundation, framing, plumbing, and wiring will be identical for each house. Variation is introduced in the later stages of construction to produce a wider variety of models.

Template Method example

Check list

  1. Examine the algorithm, and decide which steps are standard and which steps are peculiar to each of the current classes.
  2. Define a new abstract base class to host the “don’t call us, we’ll call you” framework.
  3. Move the shell of the algorithm (now called the “template method”) and the definition of all standard steps to the new base class.
  4. Define a placeholder or “hook” method in the base class for each step that requires many different implementations. This method can host a default implementation – or – it can be defined as abstract (Java) or pure virtual (C++).
  5. Invoke the hook method(s) from the template method.
  6. Each of the existing classes declares an “is-a” relationship to the new abstract base class.
  7. Remove from the existing classes all the implementation details that have been moved to the base class.
  8. The only details that will remain in the existing classes will be the implementation details peculiar to each derived class.

Rules of thumb

  • Strategy is like Template Method except in its granularity.
  • Template Method uses inheritance to vary part of an algorithm. Strategy uses delegation to vary the entire algorithm.
  • Strategy modifies the logic of individual objects. Template Method modifies the logic of an entire class.
  • Factory Method is a specialization of Template Method.

11. Visitor Pattern

Intent

  • Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.
  • The classic technique for recovering lost type information.
  • Do the right thing based on the type of two objects.
  • Double dispatch

Problem

Many distinct and unrelated operations need to be performed on node objects in a heterogeneous aggregate structure. You want to avoid “polluting” the node classes with these operations. And, you don’t want to have to query the type of each node and cast the pointer to the correct type before performing the desired operation.

Discussion

Visitor’s primary purpose is to abstract functionality that can be applied to an aggregate hierarchy of “element” objects. The approach encourages designing lightweight Element classes – because processing functionality is removed from their list of responsibilities. New functionality can easily be added to the original inheritance hierarchy by creating a new Visitor subclass.

Visitor implements “double dispatch”. OO messages routinely manifest “single dispatch” – the operation that is executed depends on: the name of the request, and the type of the receiver. In “double dispatch”, the operation executed depends on: the name of the request, and the type of TWO receivers (the type of the Visitor and the type of the element it visits).

The implementation proceeds as follows. Create a Visitor class hierarchy that defines a pure virtual visit() method in the abstract base class for each concrete derived class in the aggregate node hierarchy. Each visit() method accepts a single argument – a pointer or reference to an original Element derived class.

Each operation to be supported is modelled with a concrete derived class of the Visitor hierarchy. The visit() methods declared in the Visitor base class are now defined in each derived subclass by allocating the “type query and cast” code in the original implementation to the appropriate overloaded visit() method.

07

Add a single pure virtual accept() method to the base class of the Element hierarchy. accept() is defined to receive a single argument – a pointer or reference to the abstract base class of the Visitor hierarchy.

Each concrete derived class of the Element hierarchy implements the accept() method by simply calling the visit() method on the concrete derived instance of the Visitor hierarchy that it was passed, passing its this” pointer as the sole argument.

Everything for “elements” and “visitors” is now set-up. When the client needs an operation to be performed, (s)he creates an instance of the Vistor object, calls the accept() method on each Element object, and passes the Visitor object.

The accept() method causes flow of control to find the correct Element subclass. Then when the visit() method is invoked, flow of control is vectored to the correct Visitor subclass. accept() dispatch plus visit() dispatch equals double dispatch.

11

The Visitor pattern makes adding new operations (or utilities) easy – simply add a new Visitor derived class. But, if the subclasses in the aggregate node hierarchy are not stable, keeping the Visitor subclasses in sync requires a prohibitive amount of effort.

12

An acknowledged objection to the Visitor pattern is that is represents a regression to functional decomposition – separate the algorithms from the data structures. While this is a legitimate interpretation, perhaps a better perspective/rationale is the goal of promoting non-traditional behavior to full object status.

Structure

13

The Element hierarchy is instrumented with a “universal method adapter”. The implementation of accept() in each Element derived class is always the same. But – it cannot be moved to the Element base class and inherited by all derived classes because a reference to this in the Element class always maps to the base type Element.

Visitor scheme

14

When the polymorphic firstDispatch() method is called on an abstract First object, the concrete type of that object is “recovered”. When the polymorphic secondDispatch() method is called on an abstract Second object, its concrete type is “recovered”. The application functionality appropriate for this pair of types can now be exercised.

Visitor scheme

Example

15

The Visitor pattern represents an operation to be performed on the elements of an object structure without changing the classes on which it operates. This pattern can be observed in the operation of a taxi company. When a person calls a taxi company (accepting a visitor), the company dispatches a cab to the customer. Upon entering the taxi the customer, or Visitor, is no longer in control of his or her own transportation, the taxi (driver) is.

Visitor example

Check list

16

  1. Confirm that the current hierarchy (known as the Element hierarchy) will be fairly stable and that the public interface of these classes is sufficient for the access the Visitor classes will require. If these conditions are not met, then the Visitor pattern is not a good match.
  2. Create a Visitor base class with a visit(ElementXxx) method for each Element derived type.
  3. Add an accept(Visitor) method to the Element hierarchy. The implementation in each Element derived class is always the same – accept( Visitor v ) { v.visit( this ); }. Because of cyclic dependencies, the declaration of the Element and Visitor classes will need to be interleaved.
  4. The Element hierarchy is coupled only to the Visitor base class, but the Visitor hierarchy is coupled to each Element derived class. If the stability of the Element hierarchy is low, and the stability of the Visitor hierarchy is high; consider swapping the ‘roles’ of the two hierarchies.
  5. Create a Visitor derived class for each “operation” to be performed on Element objects. visit() implementations will rely on the Element’s public interface.
  6. The client creates Visitor objects and passes each to Element objects by calling accept().

Rules of thumb

  • The abstract syntax tree of Interpreter is a Composite (therefore Iterator and Visitor are also applicable).
  • Iterator can traverse a Composite. Visitor can apply an operation over a Composite.
  • The Visitor pattern is like a more powerful Command pattern because the visitor may initiate whatever is appropriate for the kind of object it encounters.
  • The Visitor pattern is the classic technique for recovering lost type information without resorting to dynamic casts.

Notes

The November 2000 issue of JavaPro has an article by James Cooper (author of a Java companion to the GoF) on the Visitor design pattern. He suggests it “turns the tables on our object-oriented model and creates an external class to act on data in other classes … while this may seem unclean … there are good reasons for doing it.”

His primary example. Suppose you have a hierarchy of Employee-Engineer-Boss. They all enjoy a normal vacation day accrual policy, but, Bosses also participate in a “bonus” vacation day program. As a result, the interface of class Boss is different than that of class Engineer. We cannot polymorphically traverse a Composite-like organization and compute a total of the organization’s remaining vacation days. “The Visitor becomes more useful when there are several classes with different interfaces and we want to encapsulate how we get data from these classes.”

His benefits for Visitor include:

  • Add functions to class libraries for which you either do not have the source or cannot change the source
  • Obtain data from a disparate collection of unrelated classes and use it to present the results of a global calculation to the user program
  • Gather related operations into a single class rather than force you to change or derive classes to add these operations
  • Collaborate with the Composite pattern

Visitor is not good for the situation where “visited” classes are not stable. Every time a new Composite hierarchy derived class is added, every Visitor derived class must be amended.

Advertisements

Structural patterns

Structural Patterns

Structural Patterns describe how objects and classes can be combined to form larger structures. The difference between class patterns and object patterns is that class patterns describe abstraction with the help of inheritance and how it can be used to provide more useful program interface. Object patterns, on other hand, describe how objects can be associated and composed to form larger, more complex structures.

There are seven structural patterns described. They are as follows:

Patterns.
1. Adapter Pattern

 Structural Patterns – Adapter Pattern

The Adapter pattern is used so that two unrelated interfaces can work together. The joining between them is called an Adapter. This is something like we convert interface of one class into interface expected by the client. We do that using an Adapter.

Let’s try and understand this with the help of an example.  We all have electric sockets in our houses of different sizes and shapes. we will take an example of a socket of 15 Ampere. This is a bigger socket and the other one which is smaller is of 5 Ampere. A 15 Amp plug cannot fit into a 5 Amp socket. Here, we will use an Adapter. The adapter can be called a connector here. The connector connects both of these and gives output to the client plug which is of 5 Amp.

The Adapter is something like this. It will be having the plug of suitable for 15 Amp and a socket suitable for a 5 Amp plug. So, that the 5 Amp plug which here is the client can fit in and also the server which here is the 15 Amp socket can give the output.

Let’s try and convert the same example into a software program. How do we do this? Let’s try and understand the problem once more. We have a 5 Amp plug and want a 5 Amp socket so that it can work. We DO NOT have a 5 Amp socket, what we have is a 15 Amp socket in which the 5 Amp plug cannot fit. The problem is how to cater to the client without changing the plug or socket.

The Adapter Pattern can be implemented in two ways, by Inheritance and by Composition.


2. Bridge Pattern

The Bridge Pattern is used to separate out the interface from its implementation. Doing this gives the flexibility so that both can vary independently.

The best example for this is like the electric equipments you have at home and their switches. For e.g., the switch of the fan. The switch is the interface and the actual implementation is the Running of the fan once its switched-on. Still, both the switch and the fan are independent of each other. Another switch can be plugged in for the fan and this switch can be connected to light bulb.

Let’s see how we can convert this into a software program. Switch is the interface having two functions, switchOn() and switchOff().


3. Composite Pattern

In developing applications, we come across components which are individual objects and also can be collection of objects. Composite pattern can represent both the conditions. In this pattern, you can develop tree structures for representing part-whole hierarchies.

The most common example in this pattern is of a company’s employee hierarchy. We here will also take the same example.

The employees of a company are at various positions. Now, say in a hierarchy, the manager has subordinates; also the Project Leader has subordinates, i.e. employees reporting to him/her. The developer has no subordinates.

So, let’s have a look at the class Employee: This is a simple class with getters and setters for attributes as name, salary and subordinates.

4. Decorator Pattern

The decorator pattern helps to add behavior or responsibilities to an object. This is also called “Wrapper”. Suppose we have some 6 objects and 2 of them need a special behavior, we can do this with the help of a decorator.

Java Design Patterns suggest that Decorators should be abstract classes and the concrete implementation should be derived from them.

The decorator pattern can be use wherever there is a need to add some functionality to the object or group of objects. Let’s take an example of a Christmas tree. There is a need to decorate a Christmas tree. Now we have many branches which need to be decorated in different ways.


5. Facade Pattern

Facade as the name suggests means the face of the building. The people walking past the road can only see this glass face of the building. They do not know anything about it, the wiring, the pipes and other complexities. The face hides all the complexities of the building and displays a friendly face.

This is how facade pattern is used. It hides the complexities of the system and provides an interface to the client from where the client can access the system. In Java, the interface JDBC can be called a facade. We as users or clients create connection using the “java.sql.Connection” interface, the implementation of which we are not concerned about. The implementation is left to the vendor of driver.

Let’s try and understand the facade pattern better using a simple example. Let’s consider a store. This store has a store keeper. In the storage, there are a lot of things stored e.g. packing material, raw material and finished goods.

You, as client want access to different goods. You do not know where the different materials are stored. You just have access to store keeper who knows his store well. Whatever you want, you tell the store keeper and he takes it out of store and hands it over to you on showing him the credentials. Here, the store keeper acts as the facade, as he hides the complexities of the system Store.

6. Flyweight Pattern

The pattern here states about a mechanism by which you can avoid creating a large number of object instances to represent the entire system.

To decide if some part of your program is a candidate for using Flyweights, consider whether it is possible to remove some data from the class and make it extrinsic. If this makes it possible to reduce greatly the number of different class instances your program needs to maintain, this might be a case where Flyweights will help.

The typical example you can see on this in every book will be of folders. The folder with name of each of the company employee on it, so, the attributes of class Folder are: ‘Selected’ , ‘Not Selected’ and the third one is ‘employeeName’. With this methodology, we will have to create 2000 folder class instances for each of the employees. This can be costly, so we can create just two class instances with attributes ‘selected’ and ‘not selected’ and set the employee’s name by a method like:

setNameOnFolder(String name);

This way, the instances of class folder will be shared and you will not have to create multiple instances for each employee.

   The grinding wheels are used for metal cutting across the industry. Basically the main ingredients for these grinding wheels are Aluminum Oxide (Al2O3) and Silicon Carbide (SiC). These compounds are used in form of grains. For those who remember Chemistry from schools, and for others, just follow the example.

His company manufactures nearly 25000 types of grinding wheels. Now, there is another technicality in this and that is bonding.

There are two types of bondings used to bond the material i.e. Aluminum Oxide and Silicon Carbide together. One is Glass bonding – this is like, the wheel is heated to 1300 degree C and the silicon turns into glass to hold the two materials together. The second type of bonding is Resin bonding, this is when some resins help in holding the materials together. The wheels are in different sizes, have different ratio of materials mixed and have any of these two types of bondings. This decides the strength of the wheel. In all, creating 25,000 types of combinations is a pretty complex looking scenario.

If we consider this from software point of view, we can see that each wheel is of a different type and so, we need to make 25000 classes for taking care of each of the wheel. This of course will be very resource intensive. So, how to avoid this?

Well, we already know a few things and we can see a common pattern in each of the wheels. The common things are as follows:

1. Materials of use – They are always Aluminum Oxide and Silicon Carbide.
2. Each wheel has a bonding.
3. Each wheel has a size.

We can follow one thing, the combination above mentioned three ingredients can give us a large number of instances so, why not take a scenario where only one of these is used in the constructor and rest be passed as method parameters.

Let’s have a look at the code. For every flyweight, there is a factory providing the object instance. Now, naturally wheels are made in a factory so, there is GrindingWheelFactory class which returns the type of wheel needed.


7. Proxy Pattern

The proxy pattern is used when you need to represent a complex with a simpler one. If creation of object is expensive, its creation can be postponed till the very need arises and till then, a simple object can represent it. This simple object is called the “Proxy” for the complex object

The cases can be innumerable why we can use the proxy. Let’s take a scenario. Say, we want to attach an image with the email. Now, suppose this email has to be sent to 1 lakh consumers in a campaign. Attaching the image and sending along with the email will be a very heavy operation. What we can do instead is, send the image as a link to one of the servlet. The place holder of the image will be sent. Once the email reaches the consumer, the image place holder will call the servlet and load the image at run time straight from the server.

Let’s try and understand this pattern with the help of a non-software example as we have tried to do throughout this article.

Let’ say we need to withdraw money to make some purchase. The way we will do it is, go to an ATM and get the money, or purchase straight with a cheque. In old days when ATMs and cheques were not available, what used to be the way??? Well, get your passbook, go to bank, get withdrawal form there, stand in a queue and withdraw money. Then go to the shop where you want to make the purchase. In this way, we can say that ATM or cheque in modern times act as proxies to the Bank.

Bank will define the entire method described above. There are references of classes like You (as the person who wants to withdraw money), also Account, as persons account. These are dummy classes and can be considered of fulfilling the responsibilities as described.

Creational design patterns

In software engineering, creational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic form of object creation could result in design problems or added complexity to the design. Creational design patterns solve this problem by somehow controlling this object creation.

  • Abstract Factory
    Creates an instance of several families of classes This pattern is one level of abstraction higher than factory pattern. This means that the abstract factory returns the factory of classes. Like Factory pattern returned one of the several sub-classes, this returns such factory which later will return one of the sub-classes.
  • Builder
    Separates object construction from its representation . Builder, as the name suggests builds complex objects from simple ones step-by-step. It separates the construction of complex objects from their representation. This is common to all the fast food restaurants and all the children meals. Here, what is important? Every time a children’s meal is ordered, the service boy will take a burger, a fries, a cold drink and a toy. Now suppose, there are 3 types of burgers available. Vegetable, Fish and Chicken, 2 types of cold drinks available. Cola and Orange and 2 types of toys available, a car and a doll. So, the order might be a combination of one of these, but the process will be the same. One burger, one cold drink, one fries and one toy. All these items are placed in a paper bag and is given to the customer. Now let’s see how we can apply software to this above mentioned example. The whole thing is called a children meal. Each of the four burger, cold drink, fries and toy are items in the meal. So, we can say, there is an interface Item having two methods, pack() and price().
  • Factory Method
    Creates an instance of several derived classes Let’s take a non-software example for this. Say, we have to plan for a children meal at a fast food restaurant. What is it comprised of? Well, a burger, a cold drink, a medium fries and a toy. Factory of Of classes. In simple words, if we have a super class and n sub-classes, and based on data provided, we have to return the object of one of the sub-classes, we use a factory pattern.
  • Object Pool
    Avoid expensive acquisition and release of resources by recycling objects that are no longer in use
  • Prototype
    A fully initialized instance to be copied or cloned . The prototype means making a clone. This implies cloning of an object to avoid creation. If the cost of creating a new object is large and creation is resource intensive, we clone the object. We use the interface Cloneable and call its method clone() to clone the object. Again let’s try and understand this with the help of a non-software example.  The example here we will take will be of a plant cell. This example is a bit different from the actual cloning in a way that cloning involves making a copy of the original one. Here, we break the cell in two and make two copies and the original one does not exist. But, this example will serve the purpose. Let’s say the Mitotic Cell Division in plant cells. Let’s take a class PlantCell having a method split(). The plant cell will implement the interface Cloneable.
  • Singleton
    A class of which only a single instance can exist This is one of the most commonly used patterns. There are some instances in the application where we have to use just one instance of a particular class. Let’s take up an example to understand this.A very simple example is say Logger, suppose we need to implement the logger and log it to some file according to date time. In this case, we cannot have more than one instances of Logger in the application otherwise the file in which we need to log will be created with every instance.We use Singleton pattern for this and instantiate the logger when the first request hits or when the server is started.

Rules of thumb

  1. Sometimes creational patterns are competitors: there are cases when either Prototype or Abstract Factory could be used profitably. At other times they are complementory: Abstract Factory might store a set of Prototypes from which to clone and return product objects, Builder can use one of the other patterns to implement which components get built. Abstract Factory, Builder, and Prototype can use Singleton in their implementation.
  2. Abstract Factory, Builder, and Prototype define a factory object that’s responsible for knowing and creating the class of product objects, and make it a parameter of the system. Abstract Factory has the factory object producing objects of several classes. Builder has the factory object building a complex product incrementally using a correspondingly complex protocol. Prototype has the factory object (aka prototype) building a product by copying a prototype object.
  3. Abstract Factory classes are often implemented with Factory Methods, but they can also be implemented using Prototype.
  4. Abstract Factory can be used as an alternative to Facade to hide platform-specific classes.
  5. Builder focuses on constructing a complex object step by step. Abstract Factory emphasizes a family of product objects (either simple or complex). Builder returns the product as a final step, but as far as the Abstract Factory is concerned, the product gets returned immediately.
  6. Builder is to creation as Strategy is to algorithm.
  7. Builder often builds a Composite.
  8. Factory Methods are usually called within Template methods.
  9. Factory Method: creation through inheritance. Prototype: creation through delegation.
  10. Often, designs start out using Factory Method (less complicated, more customizable, subclasses proliferate) and evolve toward Abstract Factory, Prototype, or Builder (more flexible, more complex) as the designer discovers where more flexibility is needed.
  11. Prototype doesn’t require subclassing, but it does require an Initialize operation. Factory Method requires subclassing, but doesn’t require Initialize.
  12. Designs that make heavy use of the Composite and Decorator patterns often can benefit from Prototype as well.

software design patterns

In software engineering, a design pattern is a general reusable solution to a commonly occurring problem within a given context in software design. A design pattern is not a finished design that can be transformed directly into source or machine code. It is a description or template for how to solve a problem that can be used in many different situations. Patterns are formalized best practices that the programmer must implement themselves in the application.  Object-oriented design patterns typically show relationships and interactions between classes or objects, without specifying the final application classes or objects that are involved. Many patterns imply object-orientation or more generally mutable state, and so may not be as applicable in functional programming languages, in which data is immutable or treated as such.

Design patterns reside in the domain of modules and interconnections. At a higher level there are architectural patterns that are larger in scope, usually describing an overall pattern followed by an entire system.

There are many types of design patterns, for instance

  • Algorithm strategy patterns addressing concerns related to high-level strategies describing how to exploit application characteristics on a computing platform.
  • Computational design patterns addressing concerns related to key computation identification.
  • Execution patterns that address concerns related to supporting application execution, including strategies in executing streams of tasks and building blocks to support task synchronization.
  • Implementation strategy patterns addressing concerns related to implementing source code to support
    1. program organization, and
    2. the common data structures specific to parallel programming.
  • Structural design patterns addressing concerns related to high-level structures of applications being developed.

Design patterns can speed up the development process by providing tested, proven development paradigms.  Effective software design requires considering issues that may not become visible until later in the implementation. Reusing design patterns helps to prevent subtle issues that can cause major problems, and it also improves code readability for coders and architects who are familiar with the patterns.

In order to achieve flexibility, design patterns usually introduce additional levels of indirection, which in some cases may complicate the resulting designs and hurt application performance.

By definition, a pattern must be programmed anew into each application that uses it. Since some authors see this as a step backward from software reuse as provided by components, researchers have worked to turn patterns into components. Meyer and Arnout were able to provide full or partial componentization of two-thirds of the patterns they attempted.

Software design techniques are difficult to apply to a broader range of problems. Design patterns provide general solutions, documented in a format that does not require specifics tied to a particular problem.

Structure

Design patterns are composed of several sections . Of particular interest are the Structure, Participants, and Collaboration sections. These sections describe a design motif: a prototypical micro-architecture that developers copy and adapt to their particular designs to solve the recurrent problem described by the design pattern. A micro-architecture is a set of program constituents (e.g., classes, methods…) and their relationships. Developers use the design pattern by introducing in their designs this prototypical micro-architecture, which means that micro-architectures in their designs will have structure and organization similar to the chosen design motif.

In addition to this, patterns allow developers to communicate using well-known, well understood names for software interactions. Common design patterns can be improved over time, making them more robust than ad-hoc designs.

Domain-specific patterns

Efforts have also been made to codify design patterns in particular domains, including use of existing design patterns as well as domain specific design patterns. Examples include user interface design patterns, information visualization, secure design, “secure usability”, Web design [14] and business model design.

The annual Pattern Languages of Programming Conference proceedings [16] include many examples of domain specific patterns.

Classification and list

Design patterns were originally grouped into the categories: creational patterns, structural patterns, and behavioral patterns, and described using the concepts of delegation, aggregation, and consultation. For further background on object-oriented design, see coupling and cohesion, inheritance, interface, and polymorphism. Another classification has also introduced the notion of architectural design pattern that may be applied at the architecture level of the software such as the Model–View–Controller pattern.

Creational patterns
Name Description In Design Patterns In Code Complete Other
Abstract factory Provide an interface for creating families of related or dependent objects without specifying their concrete classes. Yes Yes N/A
Builder Separate the construction of a complex object from its representation allowing the same construction process to create various representations. Yes No N/A
Factory method Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses (dependency injection[18]). Yes Yes N/A
Lazy initialization Tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed. No No PoEAA[19]
Multiton Ensure a class has only named instances, and provide global point of access to them. No No N/A
Object pool Avoid expensive acquisition and release of resources by recycling objects that are no longer in use. Can be considered a generalisation of connection pool and thread pool patterns. No No N/A
Prototype Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype. Yes No N/A
Resource acquisition is initialization Ensure that resources are properly released by tying them to the lifespan of suitable objects. No No N/A
Singleton Ensure a class has only one instance, and provide a global point of access to it. Yes Yes N/A
Structural patterns
Name Description In Design Patterns In Code Complete[17] Other
Adapter or Wrapper or Translator. Convert the interface of a class into another interface clients expect. An adapter lets classes work together that could not otherwise because of incompatible interfaces. The enterprise integration pattern equivalent is the translator. Yes Yes N/A
Bridge Decouple an abstraction from its implementation allowing the two to vary independently. Yes Yes N/A
Composite Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. Yes Yes N/A
Decorator Attach additional responsibilities to an object dynamically keeping the same interface. Decorators provide a flexible alternative to subclassing for extending functionality. Yes Yes N/A
Facade Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use. Yes Yes N/A
Flyweight Use sharing to support large numbers of similar objects efficiently. Yes No N/A
Front Controller The pattern relates to the design of Web applications. It provides a centralized entry point for handling requests. No Yes N/A
Module Group several related elements, such as classes, singletons, methods, globally used, into a single conceptual entity. No No N/A
Proxy Provide a surrogate or placeholder for another object to control access to it. Yes No N/A
Behavioral patterns
Name Description In Design Patterns In Code Complete[17] Other
Blackboard Generalized observer, which allows multiple readers and writers. Communicates information system-wide. No No N/A
Chain of responsibility Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it. Yes No N/A
Command Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations. Yes No N/A
Interpreter Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language. Yes No N/A
Iterator Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation. Yes Yes N/A
Mediator Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently. Yes No N/A
Memento Without violating encapsulation, capture and externalize an object’s internal state allowing the object to be restored to this state later. Yes No N/A
Null object Avoid null references by providing a default object. No No N/A
Observer or Publish/subscribe Define a one-to-many dependency between objects where a state change in one object results in all its dependents being notified and updated automatically. Yes Yes N/A
Servant Define common functionality for a group of classes No No N/A
Specification Recombinable business logic in a Boolean fashion No No N/A
State Allow an object to alter its behavior when its internal state changes. The object will appear to change its class. Yes No N/A
Strategy Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it. Yes Yes N/A
Template method Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure. Yes Yes N/A
Visitor Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates. Yes No N/A
Concurrency patterns
Name Description In POSA2[20] Other
Active Object Decouples method execution from method invocation that reside in their own thread of control. The goal is to introduce concurrency, by using asynchronous method invocation and a scheduler for handling requests. Yes N/A
Balking Only execute an action on an object when the object is in a particular state. No N/A
Binding properties Combining multiple observers to force properties in different objects to be synchronized or coordinated in some way.[21] No N/A
Double-checked locking Reduce the overhead of acquiring a lock by first testing the locking criterion (the ‘lock hint’) in an unsafe manner; only if that succeeds does the actual lock proceed.Can be unsafe when implemented in some language/hardware combinations. It can therefore sometimes be considered an anti-pattern. Yes N/A
Event-based asynchronous Addresses problems with the asynchronous pattern that occur in multithreaded programs. No N/A
Guarded suspension Manages operations that require both a lock to be acquired and a precondition to be satisfied before the operation can be executed. No N/A
Lock One thread puts a “lock” on a resource, preventing other threads from accessing or modifying it.[23] No PoEAA[19]
Messaging design pattern (MDP) Allows the interchange of information (i.e. messages) between components and applications. No N/A
Monitor object An object whose methods are subject to mutual exclusion, thus preventing multiple objects from erroneously trying to use it at the same time. Yes N/A
Reactor A reactor object provides an asynchronous interface to resources that must be handled synchronously. Yes N/A
Read-write lock Allows concurrent read access to an object, but requires exclusive access for write operations. No N/A
Scheduler Explicitly control when threads may execute single-threaded code. No N/A
Thread pool A number of threads are created to perform a number of tasks, which are usually organized in a queue. Typically, there are many more tasks than threads. Can be considered a special case of the object pool pattern. No N/A
Thread-specific storage Static or “global” memory local to a thread. Yes N/A

Dependency injection

Dependency injection is a software design pattern that allows removing hard-coded dependencies and making it possible to change them, whether at run-time or compile-time.

This can be used, for example, as a simple way to load plugins dynamically or to choose stubs or mock objects in test environments vs. real objects in production environments. This software design pattern injects the depended-on element (object or value etc) to the destination automatically by knowing the requirement of the destination. Another pattern, called dependency lookup, is a regular process and reverse process to dependency injection.

Definition

Dependency injection involves at least three elements:

  • a dependent consumer,
  • a declaration of a component’s dependencies, defined as interface contracts,
  • an injector (sometimes referred to as a provider or container) that creates instances of classes that implement a given dependency interface on request.

The dependent object describes what software component it depends on to do its work. The injector decides what concrete classes satisfy the requirements of the dependent object, and provides them to the dependent.

In conventional software development, the dependent object decides for itself what concrete classes it will use. In the dependency injection pattern, this decision is delegated to the “injector” which can choose to substitute different concrete class implementations of a dependency contract interface at run-time rather than at compile time.

Being able to make this decision at run-time rather than compile time is the key advantage of dependency injection. Multiple, different implementations of a single software component can be created at run-time and passed (injected) into the same test code. The test code can then test each different software component without being aware that what has been injected is implemented differently.

Motivation

The primary purpose of the dependency injection pattern is to allow selection among multiple implementations of a given dependency interface at runtime, or via configuration files, instead of at compile time. The pattern is particularly useful for providing stub test implementations of complex components when testing, but is often used for locating plugin components, or locating and initializing software services.

Unit testing of components in large software systems is difficult, because components under test often require the presence of a substantial amount of infrastructure and set up in order to operate at all. Dependency injection simplifies the process of bringing up a working instance of an isolated component for testing. Because components declare their dependencies, a test can automatically bring up only those dependencies required to perform testing.

More importantly, injectors can be configured to swap in simplified stub implementations of sub-components when testing, the idea being that the component under test can be tested in isolation as long as the substituted sub-components implement the contract of the dependent interface sufficiently to perform the unit test in question.

As an example, consider an automatic stock trading program that communicates with a live online trading service and stores historical analytic data in a distributed database. To test the component which recommends trades, one would ordinarily need to have a connection to the online service and an actual distributed database suitably populated with test data. Using dependency injection, the components that provide access to the online service and back-end databases could be replaced altogether with a test implementation of the dependency interface contracts that provide just enough behavior to perform tests on the component under test.

Basics

Without dependency injection, a consumer component that needs a particular service in order to accomplish a task must create an instance of a class that concretely implements the dependency interface.

When using dependency injection, a consumer component specifies the service contract by interface, and the injector component selects an implementation on behalf of the dependent component.

In its simplest implementation, code that creates a dependent object supplies dependencies to that object via constructor arguments or by setting properties on the object.

More complicated implementations, such as Spring, Google Guice, and Microsoft Managed Extensibility Framework (MEF), automate this procedure. These frameworks identify constructor arguments or properties on the objects being created as requests for dependent objects, and automatically inject constructor arguments or set properties with pre-constructed instances of dependencies as part of the process of creating the dependent object. The client makes a request to the dependency injection system for an implementation of a particular interface; the dependency injection system creates the object, automatically filling in dependencies as required.

One of its core principles is the separation of behavior from dependency resolution.

Software components (Clients), are often a part of a set of collaborating components which depend upon other components (Services) to successfully complete their intended purpose. In many scenarios, they need to know “which” components to communicate with, “where” to locate them, and “how” to communicate with them. When the way such services can be accessed is changed, such changes can potentially require the source of lot of clients to be changed.

One way of structuring the code is to let the clients embed the logic of locating and/or instantiating the services as a part of their usual logic. Another way to structure the code is to have the clients declare their dependency on services, and have some “external” piece of code assume the responsibility of locating and/or instantiating the services and simply supplying the relevant service references to the clients when needed. In the latter method, client code typically is not required to be changed when the way to locate an external dependency changes. This type of implementation is considered to be an implementation of Dependency Injection and the “external” piece of code referred to earlier is likely to be either hand coded or implemented using one of a variety of DI frameworks.

Those attempting to map the above scenario to design idioms will notice that the analogy could be applied to three different design idioms – Dependency Injection, Factory and Program to an Interface and not an Implementation. As in this analogy these three idioms are often but not necessarily used together.

The conventional approach till a few years ago was to separate the interface from the implementation. The factory pattern even allowed for hiding the complexity of instantiation. However the mechanism to “locate” the services was often left to the clients. Moreover some parts of the software also needed to be aware of the dependencies between the various services themselves and thus implicitly had to work out the appropriate sequencing of such component initialization, and had to track and manage their life cycles.

As an example, while the J2EE specification uses JNDI as a mechanism to standardize the mechanism of locating object references, such implementations often require a lot of code change when say the clients need to work in much simpler environments where say JNDI is not available.

Usage of Dependency Injection requires that the software we write to declare the dependencies, and lets the framework or the container work out the complexities of service instantiation, initialization, sequencing and supplies the service references to the clients as required.

There are a number of frameworks available today to help the developer. The following have found useful are :

  • Spring Framework : A substantially large framework which offers a number of other capabilities apart from Dependency Injection.
  • PicoContainer : A fairly small tightly focused DI container framework.
  • HiveMind : Another DI container framework.
  • XWork : Primarily a command pattern framework which very effectively leverages Dependency Injection. While it is an independent framework in its own right, it is often used in conjunction with Webwork

In the following sections we shall take a scenario and implement the same first without using DI and then using the above frameworks respectively. This will allow us to get a flavor of how these frameworks can be leveraged. Note that we need  to keep the code to the minimum with a strict focus on DI related functionalities.