Strategy DP
this design pattern should: "
Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it."
Consider using it when (one of the following):
- You have a volatile code that you can separate out of your application for easy maintenance
- You want to avoid muddling how you handle a task by having to split implementation code over several inherited classes
- You want to change the algorithm you use for a task at runtime
Decorator DP
This DP allows new/additional behaviour to be added to an existing method of an object dynamically.
The formal definition: "
Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality."
The decorator pattern works by wrapping the new "decorator" object around the original object, which is typically achieved by passing the original object as a parameter to the constructor of the decorator, with the decorator implementing the new functionality. The interface of the original object needs to be maintained by the decorator.
Decorators are alternatives to subclassing. Subclassing adds behaviour at compile time whereas decorators provide a new behaviour at runtime.
This difference becomes most important when there are several independent ways of extending functionality. In some object-oriented programming languages, classes cannot be created at runtime, and it is typically not possible to predict what combinations of extensions will be needed at design time. This would mean that a new class would have to be made for every possible combination. By contrast, decorators are objects, created at runtime, and can be combined on a per-use basis. An example of the decorator pattern is the Java I/O Streams implementation.
Factory DP
This DP applies very valuable practice: "
Separate the parts of your code that will change the most, from the rest of your applications. And always try to reuse those parts as much as possible".
Abstract Factory Pattern provides a way to encapsulate a group of individual
factories that have a common theme.
In normal usage, the client software would create a concrete implementation of the abstract factory and then use the generic
interfaces to create the concrete
objects that are part of the theme.
The client does not know (nor care) about
which concrete objects it gets from each of these internal factories since it
uses only the generic interfaces of their products.
This pattern separates the details of implementation of a set of objects from its general usage.
Mediator DP
Let's say you have a four-page web site that lets users browse a store and make purchases. The user should be able to move from randomly from page to page.
Instead of modifying the code in each page to know when and how to jump to every new page and how to activate it, create a
mediator class to encapsulate all the navigation code out of the separate pages and place it into a mediator object instead.
From then on, each page just has to report any change of state to the mediator, and the mediator knows what page to send the user to.
Adapter DP
(also called
wrapper pattern, or simply
wrapper)
You have an upgrade in the system, and the code now needs a new interface. But you already have the code that works with old-type objects.
Now, you create a
adapter class that exposes the new interface and calls the already existing methods.
The adapter pattern is useful in situations where an already existing class provides some or all of the
services you need but does not use the
interface you need.
Proxy DP
Say that you've got some local code that's used to dealing with a local object (only). But, if you want to deal with some remote object, somewhere else in the world.
You create a
proxy, a stand-in for another object that makes the local code think it's dealing with a local object. Behind the scenes, the proxy connects to the remote object, all the while making the local code believe it's working with a local object.