Skip to content

Instantly share code, notes, and snippets.

@rain1024
Last active March 9, 2024 22:47
Show Gist options
  • Save rain1024/0994da28e964df527a45 to your computer and use it in GitHub Desktop.
Save rain1024/0994da28e964df527a45 to your computer and use it in GitHub Desktop.
design pattern

Design Pattern

  • name
  • intent
  • problem/motivation
  • solution
  • structure
  • code
  • consequences & trade-offs

Creational

Creational patterns are ones that create objects for you, rather than having you instantiate objects directly. This gives your program more flexibility in deciding which objects need to be created for a given case.

  • Abstract Factory groups object factories that have a common theme.
  • Builder constructs complex objects by separating construction and representation.
  • Factory Method creates objects without specifying the exact class to create.
  • Prototype creates objects by cloning an existing object.
  • Singleton restricts object creation for a class to only one instance.

Structural

These concern class and object composition. They use inheritance to compose interfaces and define ways to compose objects to obtain new functionality.

  • Adapter allows classes with incompatible interfaces to work together by wrapping its own interface around that of an already existing class.
  • Bridge decouples an abstraction from its implementation so that the two can vary independently.
  • Composite composes zero-or-more similar objects so that they can be manipulated as one object.
  • Decorator dynamically adds/overrides behaviour in an existing method of an object.
  • Facade provides a simplified interface to a large body of code.
  • Flyweight reduces the cost of creating and manipulating a large number of similar objects.
  • Proxy provides a placeholder for another object to control access, reduce cost, and reduce complexity.

Behavioral

Most of these design patterns are specifically concerned with communication between objects.

  • Chain of responsibility delegates commands to a chain of processing objects.
  • Command creates objects which encapsulate actions and parameters.
  • Interpreter implements a specialized language.
  • Iterator accesses the elements of an object sequentially without exposing its underlying representation.
  • Mediator allows loose coupling between classes by being the only class that has detailed knowledge of their methods.
  • Memento provides the ability to restore an object to its previous state (undo).
  • Observer is a publish/subscribe pattern which allows a number of observer objects to see an event.
  • State allows an object to alter its behavior when its internal state changes.
  • Strategy allows one of a family of algorithms to be selected on-the-fly at runtime.
  • Template method defines the skeleton of an algorithm as an abstract class, allowing its subclasses to provide concrete behavior.
  • Visitor separates an algorithm from an object structure by moving the hierarchy of methods into one object.

Reference

Design Patterns, http://en.wikipedia.org/wiki/Design_Patterns

Builder

Tags: <creational>

image

Prototype

Tags: <creational> image

The Prototype pattern specifies the kind of objects to create using a prototypical instance. Prototypes of new products are often built prior to full production, but in this example, the prototype is passive and does not participate in copying itself. The mitotic division of a cell - resulting in two identical cells - is an example of a prototype that plays an active role in copying itself and thus, demonstrates the Prototype pattern. When a cell splits, two cells of identical genotvpe result. In other words, the cell clones itself.

Intent

  • Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.
  • Co-opt one instance of a class for use as a breeder of all future instances.
  • The new operator considered harmful.

Rules of thumb

  • Sometimes creational patterns are competitors: there are cases when either Prototype or Abstract Factory could be used properly. At other times they are complementory: Abstract Factory might store a set of Prototypes from which to clone and return product objects. Abstract Factory, Builder, and Prototype can use Singleton in their implementations.
  • Abstract Factory classes are often implemented with Factory Methods, but they can be implemented using Prototype.
  • Factory Method: creation through inheritance. Protoype: creation through delegation.
  • Often, designs start out using Factory Method (less complicated, more customizable, subclasses proliferate) and evolve toward Abstract Factory, Protoype, or Builder (more flexible, more complex) as the designer discovers where more flexibility is needed.
  • Prototype doesn't require subclassing, but it does require an "initialize" operation. Factory Method requires subclassing, but doesn't require Initialize.
  • Designs that make heavy use of the Composite and Decorator patterns often can benefit from Prototype as well.
  • Prototype co-opts one instance of a class for use as a breeder of all future instances.
  • Prototypes are useful when object initialization is expensive, and you anticipate few variations on the initialization parameters. In this context, Prototype can avoid expensive "creation from scratch", and support cheap cloning of a pre-initialized prototype.
  • Prototype is unique among the other creational patterns in that it doesn't require a class – only an object. Object-oriented languages like Self and Omega that do away with classes completely rely on prototypes for creating new objects.

References

Singleton

Tags: <creational> image

The Singleton pattern ensures that a class has only one instance and provides a global point of access to that instance. It is named after the singleton set, which is defined to be a set containing one element. The office of the President of the United States is a Singleton. The United States Constitution specifies the means by which a president is elected, limits the term of office, and defines the order of succession. As a result, there can be at most one active president at any given time. Regardless of the personal identity of the active president, the title, "The President of the United States" is a global point of access that identifies the person in the office.

Intent

  • Ensure a class has only one instance, and provide a global point of access to it.
  • Encapsulated "just-in-time initialization" or "initialization on first use".

Consequences and Trade-offs

  • Abstract Factory, Builder, and Prototype can use Singleton in their implementation.
  • Facade objects are often Singletons because only one Facade object is required.
  • State objects are often Singletons.
  • The advantage of Singleton over global variables is that you are absolutely sure of the number of instances when you use Singleton, and, you can change your mind and manage any number of instances.
  • The Singleton design pattern is one of the most inappropriately used patterns. Singletons are intended to be used when a class must have exactly one instance, no more, no less. Designers frequently use Singletons in a misguided attempt to replace global variables. A Singleton is, for intents and purposes, a global variable. The Singleton does not do away with the global; it merely renames it.
  • When is Singleton unnecessary? Short answer: most of the time. Long answer: when it's simpler to pass an object resource as a reference to the objects that need it, rather than letting objects access the resource globally. The real problem with Singletons is that they give you such a good excuse not to think carefully about the appropriate visibility of an object. Finding the right balance of exposure and protection for an object is critical for maintaining flexibility.
  • Our group had a bad habit of using global data, so I did a study group on Singleton. The next thing I know Singletons appeared everywhere and none of the problems related to global data went away. The answer to the global data question is not, "Make it a Singleton." The answer is, "Why in the hell are you using global data?" Changing the name doesn't change the problem. In fact, it may make it worse because it gives you the opportunity to say, "Well I'm not doing that, I'm doing this" – even though this and that are the same thing.

References

Adapter

Tags: <structural>, <wrapper>

image

Adapter is about creating an intermediary abstraction that translates, or maps, the old component to the new system. Clients call methods on the Adapter object which redirects them into calls to the legacy component. This strategy can be implemented either with inheritance or with aggregation.

Intent

  • Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.
  • Wrap an existing class with a new interface.
  • Impedance match an old component to a new system

Structure

image

Bridge

Tags: <structural>

image

Composite

Tags: <structural>

image

Decorator

Tags: <structural>

image

Facade

Tags: <structural> <wrapper> image

The Facade defines a unified, higher level interface to a subsystem that makes it easier to use. Consumers encounter a Facade when ordering from a catalog. The consumer calls one number and speaks with a customer service representative. The customer service representative acts as a Facade, providing an interface to the order fulfillment department, the billing department, and the shipping department.

Intent

  • 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.
  • Wrap a complicated subsystem with a simpler interface.

Consequences & Trade-offs

  • Facade defines a new interface, whereas Adapter uses an old interface.
    • Remember that Adapter makes two existing interfaces work together as opposed to defining an entirely new one.
  • Whereas Flyweight shows how to make lots of little objects, Facade shows how to make a single object represent an entire subsystem.
  • Mediator is similar to Facade in that it abstracts functionality of existing classes.
    • Mediator abstracts/centralizes arbitrary communications between colleague objects. It routinely "adds value", and it is known/referenced by the colleague objects. 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.
  • Abstract Factory can be used as an alternative to Facade to hide platform-specific classes.
  • Facade objects are often Singletons because only one Facade object is required.
  • Adapter and Facade are both wrappers; but they are different kinds of wrappers.
    • The intent of Facade is to produce a simpler interface, and the intent of Adapter is to design to an existing interface.
    • While Facade routinely wraps multiple objects and Adapter wraps a single object; Facade could front-end a single complex object and Adapter could wrap several legacy objects.

Reference

Flyweight

Tags: <structural> image

The Flyweight uses sharing to support large numbers of objects efficiently. Modern web browsers use this technique to prevent loading same images twice. When browser loads a web page, it traverse through all images on that page. Browser loads all new images from Internet and places them the internal cache. For already loaded images, a flyweight object is created, which has some unique data like position within the page, but everything else is referenced to the cached one.

Intent

  • Use sharing to support large numbers of fine-grained objects efficiently.
  • The Motif GUI strategy of replacing heavy-weight widgets with light-weight gadgets.

Consequences and Trade-offs

  • Whereas Flyweight shows how to make lots of little objects, Facade shows how to make a single object represent an entire subsystem.
  • Flyweight is often combined with Composite to implement shared leaf nodes.
  • Terminal symbols within Interpreter's abstract syntax tree can be shared with Flyweight.
  • Flyweight explains when and how State objects can be shared.

References

Proxy

Tags: <structural>

Chain of responsibility

Tags: <behavioral>, <decouple> image

The Chain of Responsibility pattern avoids coupling the sender of a request to the receiver by giving more than one object a chance to handle the request. ATM use the Chain of Responsibility in money giving mechanism.

Intent

  • 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.
  • Launch-and-leave requests with a single processing pipeline that contains many possible handlers.
  • An object-oriented linked list with recursive traversal.

Structure

image

Consequences and Trade-offs

  • 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.
  • Chain of Responsibility can use Command to represent requests as objects.
  • Chain of Responsibility is often applied in conjunction with Composite. There, a component's parent can act as its successor.

References

Command

Tags: <behavioral> image

Intent

  • Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
  • Promote "invocation of a method on an object" to full object status
  • An object-oriented callback

Code

javascript

carManager.execute( "arrangeViewing", "Ferrari", "14523" );
carManager.execute( "requestInfo", "Ford Mondeo", "54323" );
carManager.execute( "requestInfo", "Ford Escort", "34232" );
carManager.execute( "buyVehicle", "Ford Escort", "34232" );

Reference

Interpreter

Tags: <behavioral>

Iterator

Tags: <behavioral>

Mediator

Tags: <behavioral>, <decouple> image

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".

Consequences & Tradeoffs

  • 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).

Reference

Memento

Tags: <behavioral> image

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.

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.

References

Observer

Tags: <behavioral>, <state>, <decouple> image

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.

Structure

image

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.

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.

Reference

State

Tags: <behavioral>

# Strategy
**Tags:** `<behavioral>`
![image](https://cloud.githubusercontent.com/assets/1780281/3297965/e93ca37e-f5fa-11e3-8a46-c3c2376dd2ae.png)
## 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.
## 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.
## Code
[Python](https://github.com/rain1024/gVim-Pathogen/blob/master/design-pattern/strategy.py)
```python
strategy0 = StrategyExample()
strategy1 = StrategyExample(executeReplacement1)
strategy2 = StrategyExample(executeReplacement2)
```
## References
* [Strategy Design Pattern](http://sourcemaking.com/design_patterns/strategy)

Template

Tags: <behavioral>

Visitor

Tags: <behavioral>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment