Since the article is limited to 20,000 words, some of them have been cut. You can check out the full text (45) on Github for a brief introduction to design patterns, which is suggested to be read with the Chinese version of Design-patterns for Humans.

Recommended reading

  • Introduction to Super complete Design Patterns (45 kinds)
  • Design — Patterns — For — Humans
  • MongoDB resources, libraries, tools, applications selected list Chinese version
  • What are some little-known but interesting websites?
  • A siege lion notebook
  • Collect great projects on Github every day
  • Some interesting folk stories
  • Excellent Google Chrome, Sublime Text, Phpstorm, oil monkey plugin collection

Design patterns represent best practices commonly adopted by experienced object-oriented software developers. Design patterns are solutions to common problems faced by software developers during software development. These solutions were developed through trial and error by many software developers over a considerable period of time. Design patterns are a set of repeatedly used, widely known, catalogued, and catalogued code design experiences. Design patterns are used to reuse code, make it easier for others to understand, and ensure code reliability. There is no doubt that design patterns are all-win for themselves, others and the system. Design patterns make coding truly engineering. Design patterns are the cornerstone of software engineering, like the blocks of a building. The rational application of design patterns in projects can perfectly solve many problems. Each pattern has its corresponding principles in reality. Each pattern describes a recurring problem around us and the core solution of the problem, which is the reason why design patterns can be widely applied.

Types of design patterns

There are 23 design patterns. These patterns fall into three broad categories:

  • Creational Patterns – These design Patterns provide a way to hide the creation logic while creating an object, rather than directly instantiating the object using the new operator. This gives programs more flexibility in determining which objects need to be created for a given instance.
    • Factory Pattern
    • Abstract Factory Pattern
    • Singleton Pattern
    • Builder Pattern
    • Prototype Pattern
    • Object Pool mode * (Pool)
    • Multicase mode * (Multiton)
    • Static Factory * (Static Factory)
  • Structural Patterns – These design Patterns focus on combinations of classes and objects. The concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionality.
    • Adapter Pattern
    • Bridge Pattern
    • Filter Pattern (Filter, Criteria Pattern)
    • Composite Pattern
    • Decorator Pattern
    • Facade Pattern
    • Flyweight Pattern
    • Proxy Pattern
    • Data Mapping mode * (Data Mapper)
    • Dependency Injection
    • Facade mode *
    • * (Fluent Interface)
    • Registry mode * (Registry)
  • Behavioral Patterns — These design Patterns focus specifically on communication between objects.
    • Chain of Responsibility Pattern
    • Command Pattern
    • Interpreter Pattern
    • Iterator Pattern
    • Mediator Pattern
    • Memento Pattern
    • Observer Pattern
    • State Pattern
    • Null Object Pattern
    • Strategy Pattern
    • Template Pattern
    • Visitor Pattern
    • * (Specification)
    • Visitor pattern * (Visitor)
  • J2EE design patterns – These design patterns focus specifically on the presentation layer. These patterns are identified by the Sun Java Center.
    • MVC Pattern
    • Business Delegate Pattern
    • Composite Entity Pattern
    • Data Access Object Pattern
    • Front Controller Pattern
    • Intercepting Filter Pattern
    • Service Locator Pattern
    • Transfer Object Pattern
    • (Delegation)
    • * (Repository)

Here is a picture to describe the overall relationship between design patterns:

Six principles of design patterns

1. Open Close Principle

The open closed principle means: open for extension, closed for modification. When the program needs to be expanded, the original code should not be modified to achieve a hot swap effect. In short, to make the program scalable, easy to maintain and upgrade. To achieve this, we need to use interfaces and abstract classes, which will be discussed later in the concrete design.

2. Liskov Substitution Principle

Richter’s substitution principle is one of the basic principles of object – oriented design. The Richter substitution principle says that wherever a base class can appear, a subclass must appear. LSP is the cornerstone of inheritance reuse. Only when the derived class can replace the base class, and the function of the software unit is not affected, the base class can be truly reused, and the derived class can add new behavior on the basis of the base class. The Richter substitution principle is a supplement to the open – closed principle. Abstract is the key step to realize the open closed principle, and the inheritance relationship between the base class and the subclass is the concrete realization of abstract, so The Richter substitution principle is the specification of the concrete steps to realize abstract.

3. Dependence Inversion Principle

This principle is the basis of the Open closed principle, concrete content: programming for interfaces that rely on abstractions rather than concrete.

4. Interface Segregation Principle

This principle means that it is better to use multiple, isolated interfaces than a single interface. It also has another meaning: reducing the coupling between classes. Thus, in fact, design patterns are software design ideas that start from large software architectures and facilitate upgrading and maintenance. They emphasize reducing dependencies and coupling.

5. Demeter Principle, also known as the Least Known Principle

The principle of least knowledge is that an entity should interact with as few other entities as possible, so that the functional modules of the system are relatively independent.

6. Composite Reuse Principle

The principle of composite reuse is: try to use a composite/aggregate approach rather than inheritance.

The factory pattern

The Factory Pattern is one of the most commonly used design patterns. This type of design pattern is a creation pattern that provides an optimal way to create objects. In the factory pattern, we create objects without exposing the creation logic to the client and by using a common interface to point to the newly created object.

introduce

Intent: Define an interface for creating an object and let its subclasses decide which factory class to instantiate. The factory pattern delays its creation to the subclasses.

Main solution: mainly solve the problem of interface selection.

When to use it: We explicitly plan when to create different instances under different conditions.

How to fix it: Have its subclasses implement the factory interface and return an abstract product as well.

Key code: The creation process is executed in its subclass.

Application example:

  1. You need a car that you can pick up directly from the factory, regardless of how it was built or what’s inside the car.
  2. Hibernate database only need to change the dialect and driver.

Advantages:

  1. When a caller wants to create an object, all he needs to know is its name.
  2. Scalability is high. If you want to add a product, you can simply extend a factory class.
  3. By masking the specific implementation of the product, the caller only cares about the interface of the product.

Disadvantages: Each time you add a product, you need to add a concrete class and object implementation factory, which makes the number of classes in the system multiply, to a certain extent, increases the complexity of the system, but also increases the dependency of the system concrete class. And that’s not a good thing.

Usage scenario:

  1. Logger: Logs may be recorded to a local hard disk, system events, or a remote server. Users can choose where to record logs.
  2. Database access, when the user does not know which type of database the system will eventually use, and the database may change.
  3. To design a framework for connecting to a server, you need three protocols, “POP3”, “IMAP”, and “HTTP”, which can be used as product classes to implement one interface.

Note: As a class creation pattern, you can use the factory method pattern anywhere you need to generate complex objects. One thing to note is that the factory pattern is good for complex objects, while simple objects, especially those that can be created by simply using new, do not need the factory pattern. If you use the factory pattern, you need to introduce a factory class, which increases the complexity of the system.

Abstract Factory pattern

Abstract Factory patterns create other factories around a Gigafactory. The gigafactory is also known as the Other factory’s factory. This type of design pattern is a creation pattern that provides an optimal way to create objects. In the abstract factory pattern, an interface is a factory responsible for creating a related object without explicitly specifying their classes. Each generated factory can provide objects according to the factory pattern.

introduce

Intent: Provides an interface for creating a set of related or interdependent objects without specifying their concrete classes.

Main solution: mainly solve the problem of interface selection.

When to use: The system’s products have more than one product family, and the system consumes only one of the products.

How to solve this problem: Within a product family, define multiple products.

Key code: Aggregate multiple products of the same type in a single factory.

Application example: work, in order to attend some parties, there must be two or more sets of clothes, such as a business attire (complete, a series of specific products), fashionable outfit (complete, a series of specific products), even for a family, there may be business women’s clothing, men’s clothing, fashion women’s clothing, fashion men’s wear, these are complete, namely a series of specific products. Suppose a situation (does not exist in reality, otherwise, can not enter the communist, but beneficial to explain the abstract factory pattern), in your home, a wardrobe (factory) only one such clothes (complete, a series of specific products), every time with this set of clothes is natural to take out from the chest. Using OO thoughts to understand, all chest (factory) is chest (abstract factory) one of a class, and each set of clothes, including specific jacket (a specific products), pants (a specific products), these specific coat also is actually coat (abstract), specific pants also are pants (another abstract products).

Advantage: When multiple objects in a product family are designed to work together, it ensures that clients always use only objects from the same product family.

Disadvantages: It is very difficult to extend the product family. To add a product in a series, you need to add code in both the abstract Creator and the concrete.

Usage scenario:

  1. QQ for skin, a whole set of change together.
  2. Generate programs for different operating systems.

Note: Product family is difficult to expand, product grade is easy to expand.

The singleton pattern

Singleton patterns are one of the simplest design patterns in Java. This type of design pattern is a creation pattern that provides an optimal way to create objects. This pattern involves a single class that is responsible for creating its own objects, while ensuring that only a single object is created. This class provides a way to access its unique objects directly, without the need to instantiate objects of the class.

Note:

  • A singleton class can have only one instance.
  • A singleton class must create its own unique instance.
  • The singleton class must provide this instance to all other objects.

introduce

Intent: Ensures that a class has only one instance and provides a global point of access to it.

Main solution: a globally used class is frequently created and destroyed.

When to use it: When you want to control the number of instances and save system resources.

How to solve this problem: Determine whether the system already has this singleton, if so, return, if not, create.

Key code: Constructor is private.

Application example:

  1. Each class has only one head teacher.
  2. Windows is multi-process and multi-threaded, when operating a file, it is inevitable that multiple processes or threads operate a file at the same time, so all file processing must be carried out through a unique instance.
  3. Some device managers are often designed to be singletons. For example, a computer with two printers has to deal with the fact that two printers cannot print the same file when output.

Advantages:

  1. Having only one instance in memory reduces memory overhead, especially when instances are frequently created and destroyed (such as the MSM home page cache).
  2. Avoid multiple use of resources (such as writing to files).

Disadvantages: No interface, no inheritance, conflicts with the single responsibility principle, a class should only care about the internal logic, not how the outside is instantiated.

Usage scenario:

  1. Requires production of unique serial numbers.
  2. Instead of adding counters to the database every time you refresh them, use singletons to cache them first.
  3. An object created consumes too many resources, such as I/O connections to the database.

** Synchronized (singleton.class) is required in the getInstance() method to prevent the instance from being instantiated multiple times by multiple threads.

Builder mode

The Builder Pattern uses multiple simple objects to build a complex object step by step. This type of design pattern is a creation pattern that provides an optimal way to create objects. A Builder class constructs the final object step by step. The Builder class is independent of other objects.

introduce

Intent: Separate a complex build from its representation so that the same build process can create different representations.

Main solution: the main solution in the software system, sometimes faced with the creation of “a complex object”, which is usually composed of various parts of the sub-object with a certain algorithm; The parts of this complex object often face drastic changes as requirements change, but the algorithms that hold them together are relatively stable.

When to use it: When some basic components do not change while their composition changes frequently.

How to fix it: Separate change from invariance.

Key code: Builder: creates and provides the instance, director: manages the dependencies of the built instance.

Application example:

  1. Go to KFC, burger, Coke, French fries, fried chicken wings and so on are unchanged, and its combination is often changed, resulting in the so-called “set meal”.
  2. StringBuilder in JAVA.

Advantages:

  1. Independent builder, easy to expand.
  2. Easy to control the details of risk.

Disadvantages:

  1. Products must have something in common and have a limited scope.
  2. If the internal changes are complex, there will be many build classes.

Usage scenario:

  1. The objects that need to be generated have complex internal structures.
  2. The internal properties of the objects that need to be generated are themselves interdependent.

Note: Unlike the factory pattern, the builder pattern focuses more on the order in which parts are assembled.

The prototype pattern

Prototype patterns are used to create duplicate objects while ensuring performance. This type of design pattern is a creation pattern that provides an optimal way to create objects. This pattern implements a prototype interface that is used to create a clone of the current object. This pattern is used when creating objects directly is expensive. For example, an object needs to be created after a costly database operation. We can reduce database calls by caching the object, returning a clone of it on the next request, and updating the database as needed.

introduce

Intent: Specify the types of objects to create with prototype instances, and create new objects by copying these prototypes.

Main solution: build and remove prototypes at run time.

When to Use:

  1. When a system should be created, constituted, and represented independently of its products.
  2. When the class to be instantiated is specified at run time, for example, by dynamic loading.
  3. To avoid creating a factory class hierarchy that is parallel to the product class hierarchy.
  4. When an instance of a class can have only one of several different combinations of states. It may be easier to build a corresponding number of prototypes and clone them than to manually instantiate the class with the appropriate state each time.

How to solve this problem: Take an existing prototype object and quickly generate an instance that looks like the prototype object.

Key code:

  1. In JAVA, clone() can be inherited from Cloneable, and clone() can be overwritten. In.NET, the MemberwiseClone() method of the Object class can be used to achieve a shallow copy of the Object or a deep copy by means of serialization.
  2. The prototype pattern is also used to isolate the coupling between the users of class objects and the concrete types (volatile classes), and it also requires that these “volatile classes” have stable interfaces.

Application example:

  1. Cells divide.
  2. The Object Clone () method in JAVA.

Advantages:

  1. Performance improvement.
  2. Escape the constraints of the constructor.

Disadvantages:

  1. Having clone methods requires a thorough consideration of the class’s functionality, which is not difficult for new classes, but not necessarily easy for existing classes, especially if a class references indirect objects that do not support serialization, or if the reference contains circular structures.
  2. The Cloneable interface must be implemented.

Usage scenario:

  1. Resource optimization scenario.
  2. Class initialization consumes a large number of resources, including data. Hardware resources, etc.
  3. Scenarios with performance and security requirements.
  4. Generating an object with new requires a lot of data preparation or access, so you can use the prototype pattern.
  5. Multiple modifiers for an object.
  6. When an object needs to be made available to other objects and each caller may need to modify its value, consider using the prototype pattern to copy multiple objects for the caller to use.
  7. In a real project, the prototype pattern is rarely seen alone, but usually in conjunction with the factory method pattern, where an object is created by the clone method and then supplied to the caller by the factory method. The archetype pattern has become so integrated with Java that it is readily available to use.

Note: Instead of constructing a new object by instantiating a class, the prototype pattern generates a new object by copying an existing object. The shallow copy implements Cloneable, overwritten, and the deep copy reads binary streams by implementing Serializable.

Object Pool Mode

Object pools (also called resource pools) are used to manage object caches. An object pool is a set of objects that have been initialized and can be used directly. Users can obtain objects from the object pool, manipulate them, and return them to the object pool when they are not needed, instead of destroying them. If objects are expensive to initialize and instantiate, and need to be instantiated frequently, but in small numbers at a time, using object pooling can yield significant performance gains. Common techniques that use the object pool pattern include thread pools, database connection pools, task queue pools, and image resource object pools. Of course, if the objects to be instantiated are small and do not require much resource overhead, there is no need to use the object pooling pattern, which does not improve performance, but wastes memory and even degrades performance.

The sample code

Pool.php


      

namespace DesignPatterns\Creational\Pool;

class Pool
{

    private $instances = array(a);private $class;

    public function __construct($class)
    {
        $this->class = $class;
    }

    public function get(a)
    {
        if (count($this->instances) > 0) {
            return array_pop($this->instances);
        }

        return new $this->class();
    }

    public function dispose($instance)
    {
        $this->instances[] = $instance; }}Copy the code

Processor.php


      

namespace DesignPatterns\Creational\Pool;

class Processor
{

    private $pool;
    private $processing = 0;
    private $maxProcesses = 3;
    private $waitingQueue = [];

    public function __construct(Pool $pool)
    {
        $this->pool = $pool;
    }

    public function process($image)
    {
        if ($this->processing++ < $this->maxProcesses) {
            $this->createWorker($image);
        } else {
            $this->pushToWaitingQueue($image); }}private function createWorker($image)
    {
        $worker = $this->pool->get();
        $worker->run($image, array($this.'processDone'));
    }

    public function processDone($worker)
    {
        $this->processing--;
        $this->pool->dispose($worker);

        if (count($this->waitingQueue) > 0) {
            $this->createWorker($this->popFromWaitingQueue()); }}private function pushToWaitingQueue($image)
    {
        $this->waitingQueue[] = $image;
    }

    private function popFromWaitingQueue(a)
    {
        return array_pop($this->waitingQueue); }}Copy the code

Worker.php


      

namespace DesignPatterns\Creational\Pool;

class Worker
{

    public function __construct(a)
    {
        // let's say that constuctor does really expensive work...
        // for example creates "thread"
    }

    public function run($image, array $callback)
    {
        // do something with $image...
        // and when it's done, execute callback
        call_user_func($callback, $this); }}Copy the code

Many cases of pattern

The multi-instance pattern is similar to the singleton pattern, but multiple instances can be returned. For example, if we have multiple database connections, MySQL, SQLite, Postgres, or if we have multiple loggers that record debug information and error information, respectively, these can be implemented using the multi-case pattern.

The sample code

Multiton.php


      

namespace DesignPatterns\Creational\Multiton;

/** * Multiton class */
class Multiton
{
    /** ** First instance */
    const INSTANCE_1 = '1';

    /** ** Second instance */
    const INSTANCE_2 = '2';

    /** * Instance array **@var array
     */
    private static $instances = array(a);The /** * constructor is private and cannot be instantiated from outside
    private function __construct(a)
    {}/** * returns an instance by specifying the name (instantiated only when the instance is used) **@param string $instanceName
     *
     * @return Multiton
     */
    public static function getInstance($instanceName)
    {
        if(! array_key_exists($instanceName,self::$instances)) {
            self::$instances[$instanceName] = new self(a); }return self::$instances[$instanceName];
    }

    /** * prevent instances from being cloned from outside **@return void
     */
    private function __clone(a)
    {}/** * prevent instance deserialization from outside **@return void
     */
    private function __wakeup(a)
    {}}Copy the code

Static factory mode

Like a simple factory, this pattern is used to create a set of related or dependent objects, except that the static factory pattern uses a static method to create all types of objects, usually factory or build.

The sample code

StaticFactory.php


      

namespace DesignPatterns\Creational\StaticFactory;

class StaticFactory
{
    /** * Create an instance of the corresponding object by passing in parameters **@param string $type
     *
     * @static
     *
     * @throws \InvalidArgumentException
     * @return FormatterInterface
     */
    public static function factory($type)
    {
        $className = __NAMESPACE__ . '\Format' . ucfirst($type);

        if(! class_exists($className)) {throw new \InvalidArgumentException('Missing format class.');
        }

        return new$className(); }}Copy the code

FormatterInterface.php


      

namespace DesignPatterns\Creational\StaticFactory;

/** * FormatterInterface */
interface FormatterInterface
{}Copy the code

FormatString.php


      

namespace DesignPatterns\Creational\StaticFactory;

/** * FormatNumber class */
class FormatNumber implements FormatterInterface
{}Copy the code

Adapter mode

Adapter patterns serve as a bridge between incompatible interfaces. This type of design pattern is a structural pattern that combines the functionality of two separate interfaces. This pattern involves a single class that is responsible for adding independent or incompatible interface functions. In a real world example, a card reader acts as an adapter between a memory card and a laptop. You insert the memory card into the card reader and the card reader into the notebook so that the memory card can be read from the notebook.

introduce

Intent: Convert the interface of a class to another interface that the client wants. The adapter pattern allows classes that otherwise would not work together due to interface incompatibilities to work together.

Main solution: the main solution in the software system, often to put some “existing objects” into the new environment, and the new environment requirements of the interface is the current object can not meet.

When to Use:

  1. The system needs to use an existing class, and the interface of this class does not meet the needs of the system.
  2. You want to create a reusable class to work with classes that are not very related to each other, including classes that may be introduced in the future, but that do not necessarily have a consistent interface.
  3. Inserting a class into another class family through an interface transformation. (For example, tigers and Birds, there is now a flying tiger, without the need to add an entity, add an adapter that contains a tiger object to implement the flying interface.)

How to fix it: Inheritance or dependency (recommended).

Key code: The adapter inherits or relies on existing objects to implement the desired target interface.

Application example:

  1. If the American appliance is 110V and the Chinese appliance is 220V, you need an adapter to convert 110V to 220V.
  2. The JAVA JDK 1.1 provides the Enumeration interface, while 1.2 provides the Iterator interface. To use the 1.2 JDK, convert the Enumeration interface from the previous system to the Iterator interface. This is where the adapter pattern is needed.
  3. Run WINDOWS programs on LINUX. 4. JDBC in JAVA.

Advantages:

  1. You can run any two classes that are not associated with each other.
  2. Improved class reuse.
  3. Increased class transparency.
  4. Good flexibility.

Disadvantages:

  1. Excessive use of adapters, will make the system very messy, not easy to grasp the overall. For example, it is clear that the call is interface A, in fact, the internal interface is adapted to the implementation of B, A system if too much of this situation, is no different from A disaster. So if you don’t really need an adapter, you can simply refactor your system.
  2. Since JAVA inherits at most one class, at most one adaptor class can be adapted, and the target class must be abstract.

Usage scenario: When you have an incentive to modify the interface of a functioning system, you should consider using the adapter pattern.

Note: The adapter is not added at detailed design time, but rather addresses the project in service.

The bridge model

Bridges are used to decouple abstraction and implementation so that they can vary independently. This type of design pattern is a structural pattern that decoupled abstraction and implementation by providing a bridge structure between the two. This pattern involves an interface that acts as a bridge, making the entity class function independently of the interface implementation class. These two types of classes can be changed structurally without affecting each other.

introduce

Intent: Separate the abstract from the implementation so that both can change independently.

Main solution: In a variety of possible changes, using inheritance causes explosive problems and is not flexible to expand.

When to use it: The implementation system may have multiple angles, each of which may vary.

How to fix it: Separate the multi-angle categories so they vary independently and reduce the coupling between them.

Key code: Abstract classes depend on implementation classes.

Application example:

  1. Pig Bajie is reincarnated from marshal Tianpeng to pig. The reincarnation mechanism divides the world into two levels, namely: soul and body, the former equivalent to abstraction, the latter equivalent to realization. Living creatures invoke the functions of the body object through the delegation of functions, allowing living creatures to dynamically select.
  2. The switch on the wall, the switch that you can see is abstract, regardless of how it’s done inside.

Advantages:

  1. Separation of abstraction and implementation.
  2. Excellent scalability.
  3. Implementation details are transparent to the customer.

Disadvantages: The introduction of bridge patterns can make the system more difficult to understand and design, because aggregation relationships are based on abstractions, requiring developers to design and program for abstractions.

Usage scenario:

  1. If a system needs to add more flexibility between the abstract and concrete roles of components, avoiding static inheritance relationships between the two levels, bridging patterns can make them establish an association relationship at the abstraction level.
  2. The bridge pattern is especially useful for systems that do not want to use inheritance or where multi-level inheritance causes the number of system classes to increase dramatically.
  3. A class has two dimensions that vary independently, and both dimensions need to be extended.

Note: For two dimensions that vary independently, the bridge pattern works best.

Filter mode

A Filter Pattern, or Criteria Pattern, is a design Pattern that allows developers to Filter a set of objects using different Criteria, and to connect them in a decoupled way through logical operations. This type of design pattern is a structural pattern that combines multiple standards to produce a single standard.

Portfolio model

Composite patterns, also known as partial whole patterns, are used to treat a group of similar objects as a single object. The composition pattern combines objects according to a tree structure to represent both partial and global hierarchies. This type of design pattern belongs to the structural pattern, which creates a tree structure of object groups. This pattern creates a class that contains its own group of objects. This class provides a way to modify the same object group.

introduce

Intent: Group objects into a tree structure to represent a partial-whole hierarchy. The composite pattern enables users to use individual and composite objects consistently.

Main solution: It blur the concept of simple and complex elements in our tree structure problem, and the client can treat the complex elements as if they were simple, thus decoupling the internal structure of the client and the complex elements.

When to Use:

  1. You want to represent a partial-whole hierarchy of objects (a tree structure).
  2. You want the user to ignore the difference between a composite object and a single object, and the user will use all objects in the composite structure uniformly.

How to solve this problem: The branches and leaves implement a unified interface, and the branches combine the interface inside.

Key code: The branch combines the interface internally and contains an internal property List containing the Component.

Application example:

  1. Arithmetic expressions include operands. Operator and another operand, where the other operator can also be an operand. Operator and another operand.
  2. In JAVA AWT and SWING, for buttons and checkboxes are leaves and containers are branches.

Advantages:

  1. High level module calls are simple.
  2. Nodes are added freely.

Disadvantages: When using the composite pattern, its leaves and branches are declared as implementation classes, not interfaces, violating the dependency inversion principle.

Usage scenario: Part. Overall scene, such as tree menu, file. Folder management.

Note: Defined as a concrete class.

Decorator pattern

Decorator patterns allow new functionality to be added to an existing object without changing its structure. This type of design pattern belongs to the structural pattern, which acts as a wrapper around an existing class. This pattern creates a decorative class that wraps around the original class and provides additional functionality while preserving the integrity of the class method signature.

introduce

Intent: Dynamically add additional responsibilities to an object. The decorator pattern is more flexible than subclassing in terms of adding functionality.

Main solution: In general, we often use inheritance in order to extend a class, because inheritance introduces static characteristics to the class, and as the extension function increases, the subclass can become bloated.

When to use: Extend a class without adding many subclasses.

How to fix it: Divide specific functional responsibilities while inheriting the decorator pattern.

Key code:

  1. The Component class plays an abstract role and should not be implemented.
  2. Decorates class references and inherits from the Component class, and the concrete extension class overrides the parent class methods.

Application example:

  1. Sun Wukong has 72 changes. When he becomes a “temple”, he is still a monkey at the root, but he has the function of a temple.
  2. A picture can be hung on the wall whether it is framed or not, but usually it is framed, and it is actually framed on the wall. The picture can be glazed and framed before it is hung on the wall; The picture, the glass and the frame form an object.

Advantages: The decorator and decorated classes can evolve independently and are not coupled to each other. The decorator pattern is an alternative to inheritance. The decorator pattern can dynamically extend the functionality of an implementation class.

Disadvantages: Multi-layer decoration is more complex.

Usage scenario:

  1. Extend the functionality of a class.
  2. Dynamic add function, dynamic undo.

Note: Can replace inheritance.

The appearance model

Facade patterns hide the complexity of the system and provide clients with an interface through which they can access the system. This type of design pattern is a structural pattern that hides the complexity of an existing system by adding an interface to it. This pattern involves a single class that provides simplified methods for client requests and delegate calls to existing system class methods.

introduce

Intent: To provide a consistent interface for a set of interfaces in a subsystem, the facade pattern defines a high-level interface that makes the subsystem easier to use.

Main solutions: reduce the complexity of accessing the internal subsystems of complex systems and simplify the interface between clients and them.

When to Use:

  1. The client does not need to know the complex connections within the system; the whole system only needs to provide a “host”.
  2. Defines the entry point of the system.

How to fix it: The client is not coupled to the system; the facade classes are.

Key code: Add another layer between the client and the complex system, this layer will call the order. Dependencies and so on.

Application example:

  1. Go to the hospital to see a doctor, may have to go to the registration, outpatient service, pricing, take medicine, so that patients or patients’ families feel very complex, if there is a reception staff, only let the reception staff to deal with, it is very convenient.
  2. JAVA’s three-tier development model.

Advantages:

  1. Reduce system interdependence.
  2. Increase flexibility.
  3. Improved security.

Disadvantages: inconsistent with open closed principle, if you want to change things very troublesome, inheritance rewrite is not appropriate.

Usage scenario:

  1. A module that provides external access to a complex module or subsystem.
  2. Subsystems are relatively independent.
  3. Prevent the risk of low level personnel.

Note: In a hierarchical structure, you can use the facade pattern to define the entry at each level in the system.

The flyweight pattern

The Flyweight Pattern is used to reduce the number of objects created to reduce memory footprint and improve performance. This type of design pattern belongs to the structural pattern, which provides a way to reduce the number of objects in order to improve the structure of the objects required by the application. The enjoy element pattern attempts to reuse existing objects of the same class, and if no matching object is found, a new object is created. We will demonstrate this pattern by creating five objects to draw 20 circles in different locations. Since there are only five colors available, the color property is used to check existing Circle objects.

introduce

Intent: Use sharing techniques to effectively support a large number of fine-grained objects.

Main solution: when there is a large number of objects, it may cause memory overflow, we abstracted the common part, if there is the same business request, directly return the existing objects in memory, to avoid re-creation.

When to Use:

  1. There are a lot of objects in the system.
  2. These objects consume a lot of memory.
  3. The state of these objects can be largely externalized.
  4. These objects can be divided into groups according to their intrinsic state, and each group of objects can be replaced by a single object when the externals are removed from the objects.
  5. The system does not depend on the identity of these objects, which are indistinguishable.

How to solve this problem: The object identified by the unique identifier is returned if it is in memory.

Key code: Store these objects in a HashMap.

Application example:

  1. If not, create a String and store it in the String cache pool. 2. Data pool of the database.

Advantages: greatly reduce the creation of objects, reduce the memory of the system, improve efficiency.

Disadvantages: Increase the complexity of the system, need to separate the external state and internal state, and the external state is inherent, should not change with the change of internal state, otherwise it will cause chaos of the system.

Usage scenario:

  1. The system has a lot of similar objects.
  2. Scenarios that require buffer pools.

Notes:

  1. Be careful to divide the external and internal states, otherwise it may cause thread-safety issues.
  2. These classes must have a factory object to control them.

The proxy pattern

In Proxy Pattern, one class represents the functionality of another class. This type of design pattern is a structural pattern. In the proxy pattern, we create objects with existing objects to provide a functional interface to the outside world.

introduce

Intent: Provides a proxy for other objects to control access to this object.

Main solution: when accessing objects directly, such as the object to be accessed on a remote machine. In object-oriented systems, some object for some reason (such as the object creation overhead is very large, or some operations require safety control, or need to access) outside the process, will have direct access to caused a lot of trouble for the user or the system structure, during a visit to this object we can add an object to this access layer.

When to use: Want to have some control over access to a class.

How to fix it: Add a middle tier.

Key code: implementation and the proxy class combination.

Application example:

  1. Windows shortcuts.
  2. Pig eight quit to find gao Cuilan result is sun Wukong changed, can be understood like this: the appearance of Gao Cuilan abstraction, Gao Cuilan himself and Sun Wukong have realized this interface, pig eight quit when visiting Gao Cuilan can not see this is Sun Wukong, so sun Wukong is Gao Cuilan agent class.
  3. You may not buy train tickets at the railway station, but you can also go to the selling point.
  4. A check or a bank certificate of deposit is the agent for the funds in the account. Cheques are used in place of cash in market transactions and provide control over funds in the issuer’s account number.
  5. Spring aop.

Advantages:

  1. Clear responsibilities.
  2. High scalability.
  3. Intelligent.

Disadvantages:

  1. Some types of proxy patterns can cause requests to be processed more slowly due to the addition of proxy objects between the client and the real topic.
  2. Implementing agent patterns requires additional work, and some implementations of agent patterns are quite complex.

Usage scenarios: Divided by responsibilities, there are usually the following usage scenarios:

  1. Remote agent.
  2. Virtual agents.
  3. Copy – on – Write agent.
  4. Protect or Access agent.
  5. Cache agent.
  6. Firewall agent.
  7. Synchronization proxies.
  8. Smart Reference agent.

Notes:

  1. Difference from the adapter pattern: The adapter pattern mainly changes the interface of the object under consideration, whereas the proxy pattern does not change the interface of the proxy class.
  2. Difference from the decorator pattern: The decorator pattern is for enhancement, while the proxy pattern is for control.

Data mapping pattern

Before you look at the data mapping pattern, let’s look at data mapping, which is the data access layer that transfers data bidirectional between the persistent data storage layer (usually a relational database) and the in-memory data presentation layer. The purpose of the data mapping pattern is to make the persistent data storage layer, the in-memory data presentation layer, and the data mapping itself independent and independent of each other. This data access layer consists of one or more mappers (or data access objects) for data transfer. A generic data access layer can handle different entity types, while a dedicated layer can handle one or several. The core of the data mapping pattern is that its data model follows the Single Responsibility Principle, which is also different from the Active Record pattern. The most typical example of a data mapping pattern is the database ORM model (Object Relational Mapper). Specifically, this pattern is an architectural pattern.

Dependency Injection Mode

Dependency Injection is an implementation of Inversion of Control. Let’s take a look at inversion of control first. When the caller needs to be the caller’s help, in the process of the traditional program design, usually by the caller to create the caller instance, but here, created by the caller’s work are done by the caller no longer, but will be the caller to create to the caller’s outside, to reverse created by the caller, eliminates the caller to create control by the caller, So it’s called inversion of control. To achieve inversion of control, the usual solution is to leave the creation of an instance of the called to the IoC container, and then inject the called into the caller (via constructor/method injection), so that we achieve decoupling of the caller and the called, a process known as dependency injection. Dependency injection is not an end in itself; it is a set of tools and means that ultimately help us develop loosely coupled, maintainable, and testable code and programs. The practice of this principle is known as interface-oriented, or abstract oriented programming.

Facade pattern

A Facade, also known as a Facade pattern, is used to provide a consistent interface to a set of interfaces in a subsystem. The facade pattern defines a high-level interface that makes the subsystem easier to use: once the facade role is introduced, the user only needs to interact directly with the facade role, and the complex relationship between the user and the subsystem is implemented by the facade role, thus reducing the coupling of the system.

The sample code

Facade.php


      

namespace DesignPatterns\Structural\Facade;

/** ** *
class Facade
{
    / * * *@var OsInterface
     */
    protected $os;

    / * * *@var BiosInterface
     */
    protected $bios;

    /**
     * This is the perfect time to use a dependency injection container
     * to create an instance of this class
     *
     * @param BiosInterface $bios
     * @param OsInterface   $os
     */
    public function __construct(BiosInterface $bios, OsInterface $os)
    {
        $this->bios = $bios;
        $this->os = $os;
    }

    /** * turn on the system */
    public function turnOn(a)
    {
        $this->bios->execute();
        $this->bios->waitForKeyPress();
        $this->bios->launch($this->os);
    }

    /** * turn off the system */
    public function turnOff(a)
    {
        $this->os->halt();
        $this->bios->powerDown(); }}Copy the code

OsInterface.php


      

namespace DesignPatterns\Structural\Facade;

/** * OsInterface Interface */
interface OsInterface
{
    /** * halt the OS */
    public function halt(a);
}
Copy the code

BiosInterface.php


      

namespace DesignPatterns\Structural\Facade;

/** * BiosInterface Interface */
interface BiosInterface
{
    /** * execute the BIOS */
    public function execute(a);

    /** * wait for halt */
    public function waitForKeyPress(a);

    /**
     * launches the OS
     *
     * @param OsInterface $os
     */
    public function launch(OsInterface $os);

    /** * power down BIOS */
    public function powerDown(a);
}
Copy the code

Flow interface mode

In software engineering, a Fluent Interface is a way to implement an object-oriented API that improves the readability of code. The goal is to write code that is as readable as natural language. We also have a common name for this way of writing code — method chain. The flow interface pattern is widely used in Laravel, such as query builders, mail, and so on.

The sample code

Sql.php


      

namespace DesignPatterns\Structural\FluentInterface;

/** * SQL class */
class Sql
{
    / * * *@var array
     */
    protected $fields = array(a);/ * * *@var array
     */
    protected $from = array(a);/ * * *@var array
     */
    protected $where = array(a);/** * Add select field **@param array $fields
     *
     * @return SQL
     */
    public function select(array $fields = array(a))
    {
        $this->fields = $fields;

        return $this;
    }

    /** * Add FROM clause **@param string $table
     * @param string $alias
     *
     * @return SQL
     */
    public function from($table, $alias)
    {
        $this->from[] = $table . ' AS ' . $alias;

        return $this;
    }

    /** * add WHERE condition **@param string $condition
     *
     * @return SQL
     */
    public function where($condition)
    {
        $this->where[] = $condition;

        return $this;
    }

    /** * Generate query statement **@return string
     */
    public function getQuery(a)
    {
        return 'SELECT ' . implode(', '.$this->fields)
                . ' FROM ' . implode(', '.$this->from)
                . ' WHERE ' . implode(' AND '.$this->where); }}Copy the code

The registration model

Registry is also called the Registry tree pattern, the Registry pattern. The registration pattern creates a central store for objects that are commonly used in your application — usually through an abstract class containing only static methods (or through the singleton pattern).

The sample code

Registry.php


      

namespace DesignPatterns\Structural\Registry;

/** * class Registry */
abstract class Registry
{
    const LOGGER = 'logger';

    / * * *@var array
     */
    protected static $storedValues = array(a);/**
     * sets a value
     *
     * @param string $key
     * @param mixed  $value
     *
     * @static
     * @return void
     */
    public static function set($key, $value)
    {
        self::$storedValues[$key] = $value;
    }

    /**
     * gets a value from the registry
     *
     * @param string $key
     *
     * @static
     * @return mixed
     */
    public static function get($key)
    {
        return self::$storedValues[$key];
    }

    // typically there would be methods to check if a key has already been registered and so on ...
}
Copy the code

Chain of responsibility model

As the name implies, the Chain of Responsibility Pattern creates a Chain of receiver objects for the request. This pattern gives the type of request and decouples the sender and receiver of the request. This type of design pattern is a behavioral pattern. In this pattern, usually each receiver contains a reference to another receiver. If an object cannot handle the request, it passes the same request to the next recipient, and so on.

introduce

Intent: Avoid coupling the request sender with the receiver by making it possible for multiple objects to receive the request, connecting these objects into a chain, and passing the request along the chain until an object processes it.

The main solution: the handler on the chain of responsibility is responsible for processing the request, and the customer only needs to send the request to the chain of responsibility. The customer does not need to care about the processing details of the request and the delivery of the request, so the chain of responsibility decouple the sender of the request and the handler of the request.

When to use: To filter many traces when processing messages.

How to fix it: Intercepting classes all implement the same interface.

Key code: the Handler in the aggregate itself, in the HandlerRequest to determine whether it is appropriate, if not the condition is passed down, to whom before the set.

Application example:

  1. In the Dream of red Mansions, “beating the drum and passing flowers”.
  2. Event bubble in JS.
  3. JAVA WEB Apache Tomcat processing for Encoding, Struts2 interceptor, JSP servlet Filter.

Advantages:

  1. Reduce coupling. It decouples the sender and receiver of the request.
  2. Simplified objects. So that the object does not need to know the chain structure.
  3. Increased flexibility in assigning responsibilities to objects. Allows responsibilities to be added or removed dynamically by changing members in the chain or reordering them.
  4. It is convenient to add a new request handling class.

Disadvantages:

  1. There is no guarantee that the request will be received.
  2. System performance will suffer, and it will be inconvenient to debug your code and may cause looping calls.
  3. Runtime characteristics may not be easy to observe, hindering debugging.

Usage scenario:

  1. There are multiple objects that can handle the same request, and the specific object that handles the request is automatically determined at runtime.
  2. Submit a request to one of multiple objects without explicitly specifying the recipient.
  3. You can dynamically specify a set of objects to handle requests.

Note: You will encounter many applications in JAVA WEB.

Command mode

Command Pattern is a data-driven design Pattern, which belongs to behavioral Pattern. The request is wrapped in the object as a command and passed to the calling object. The call object finds the appropriate object that can handle the command and passes the command to the appropriate object, which executes the command.

introduce

Intent: Encapsulates a request into an object that allows you to parameterize customers with different requests.

Main solution: In software systems, the relationship between the behavior requester and the behavior implementer is usually tightly coupled, but in some cases, such as when the behavior needs to be recorded, revoked or redone, transactions, etc., such a tightly coupled design cannot resist change is not appropriate.

When to use it: In some cases, such as “record, undo/redo, transaction” processing of behavior, such tight coupling with no resistance to change is not appropriate. In this case, how to decouple the “behavior requester” from the “behavior implementer”? By abstracting a set of behaviors into objects, you can achieve loose coupling between the two.

How to solve: the caller calls the receiver to execute the command, in order: caller → receiver → command.

Key code: Define three roles:

  1. Received The actual command execution object
  2. Command
  3. Invoker Uses the entry of a command object

Application instance: The core action controller in Struts 1, ActionServlet, has only one, which is equivalent to Invoker, while the class of model layer has different model classes according to different applications, which is equivalent to specific commands.

Advantages:

  1. The coupling degree of the system is reduced.
  2. New commands can easily be added to the system.

Cons: Using command mode can cause some systems to have too many specific command classes.

Usage scenario: You can use the command mode wherever you think it is a command, for example:

  1. Each button in the GUI is a command.
  2. Simulate the CMD.

Note: The system needs to support Undo and Redo commands. You can also use the command mode. See The extension of command Mode.

Interpreter mode

The Interpreter Pattern, which provides a way to evaluate a language’s syntax or expressions, is a behavior-based Pattern. This pattern implements an expression interface that interprets a particular context. This pattern is used in SQL parsing, symbol processing engines, etc.

introduce

Intent: Given a language, define its grammatical representation, and define an interpreter that uses the identifier to interpret sentences in the language.

Main solution: for some fixed grammar to build a sentence interpretation interpreter.

When to use it: If a particular type of problem occurs frequently enough, it may be worth expressing each instance of the problem as a sentence in a simple language. This allows you to build an interpreter that solves the problem by interpreting these sentences.

How to fix it: Build a syntax tree that defines terminals and non-terminals.

Key code: Build environment classes that contain some global information outside of the interpreter, typically a HashMap.

Application examples: compiler, calculation expression calculation.

Advantages:

  1. Good scalability, flexible.
  2. Added a new way to interpret expressions.
  3. Easy to implement simple grammar.

Disadvantages:

  1. There are few available scenarios.
  2. Difficult to maintain for complex grammars.
  3. Interpreter patterns can cause class bloat.
  4. The interpreter pattern uses recursive invocation methods.

Usage scenario:

  1. A sentence in a language that needs to be interpreted and executed can be represented as an abstract syntax tree.
  2. Some recurring problems can be expressed in a simple language.
  3. A scenario where simple syntax needs to be explained.

Note: available scenarios are less, if encountered in JAVA can use expression4J instead.

Iterator pattern

The Iterator Pattern is a very common design Pattern in Java and.NET programming environments. This pattern is used to access the elements of a collection object sequentially, without knowing the underlying representation of the collection object. The iterator pattern is a behavioral pattern.

introduce

Intent: Provides a way to access the elements of an aggregate object sequentially without exposing the object’s internal representation.

Main solution: different ways to traverse the entire integration object.

When to use: To traverse an aggregate object.

How to fix it: Give iterators the responsibility for moving between elements, rather than aggregating objects.

Key code: define interface: hasNext, next.

Application example: Iterator in JAVA.

Advantages:

  1. It supports traversal of an aggregate object in different ways.
  2. Iterators simplify the aggregation class.
  3. There can be multiple traversals on the same aggregation.
  4. In the iterator pattern, it is easy to add new aggregate and iterator classes without changing the original code.

Disadvantages: Since the iterator pattern separates the responsibility for storing and traversing data, adding new aggregate classes requires adding new iterator classes, and the number of classes increases in pairs, which increases system complexity to some extent.

Usage scenario:

  1. Access the contents of an aggregate object without exposing its internal representation.
  2. You need to provide multiple traversal methods for aggregate objects.
  3. Provides a unified interface for traversing different aggregation structures.

Note: The iterator pattern separates the iterator behavior of a collection object and abstracts an iterator class to take care of it. In this way, the internal structure of the collection is not exposed, and the data inside the collection can be accessed transparently by external code.

The mediator model

Mediator patterns are used to reduce the complexity of communication between multiple objects and classes. This pattern provides a mediation class that typically handles communication between different classes and supports loose coupling, making the code easy to maintain. The intermediary model is a behavioral model.

introduce

Intent: Encapsulate a series of object interactions with a single mediator object. The mediator decouples the objects from the need to refer to each other explicitly, allowing them to change their interactions independently.

Main solution: there are a lot of correlation between objects and objects, which will inevitably lead to the structure of the system becomes very complex. At the same time, if an object changes, we also need to track the object associated with it, and make corresponding processing.

When to use it: Multiple classes are coupled to each other, forming a network structure.

How to fix it: Separate the network into a star.

Key code: Communication between the objects are Colleague encapsulated into a class that is handled separately.

Application example:

  1. Before China joined the WTO, countries used to trade with each other with a complex structure. Now, countries trade with each other through the WTO.
  2. Airport dispatch system.
  3. MVC framework, where C (controller) is the mediator between M (model) and V (view).

Advantages:

  1. Reduced class complexity, converting one-to-many to one-to-one.
  2. Decoupling between classes.
  3. It conforms to the Demeter principle.

Cons: Intermediaries can be large and complex to maintain.

Usage scenario:

  1. There are complex reference relationships between objects in the system, which leads to the confusion of the structure of the dependency relationship between them and the difficulty to reuse the object.
  2. You want an intermediate class to encapsulate the behavior in multiple classes without generating too many subclasses.

Caution: Should not be used when duties are confused.

Memorandum Mode

The Memento Pattern holds some state of an object so that it can be restored at an appropriate time. The memo pattern is a behavioral pattern.

introduce

Intent: To capture the internal state of an object and save that state outside of the object without breaking encapsulation.

Main solution: The so-called memo pattern is to capture the internal state of an object without breaking encapsulation, and save the state outside the object, so that the object can be restored to its original state later.

When to Use it: Many times we need to record the internal state of an object. The purpose of this is to allow the user to cancel uncertain or erroneous actions and return to his original state, so that he has a “medicine” to take.

How to fix this: Use a memo class dedicated to storing object state.

Key code: The customer is not coupled to the memo class, but to the memo management class.

Application example:

  1. Regret medicine.
  2. Save while playing a game.
  3. Ctri + z in Windows.
  4. Back in IE.
  5. Transaction management of database.

Advantages:

  1. The system provides users with a mechanism to restore the state, so that users can easily return to a historical state.
  2. The realization of information encapsulation, so that users do not need to care about the state of the preservation details.

Disadvantages: Resource consumption. If there are too many member variables in the class, it will definitely take up a large amount of resources, and every save will consume a certain amount of memory.

Usage scenario:

  1. Status scenarios where data needs to be saved or restored.
  2. Provides a rollback operation.

Notes:

  1. To comply with the Demeter principle, add a class for managing memos.
  2. To save memory, use prototype mode + memo mode.

Observer mode

When there is a one-to-many relationship between objects, the Observer Pattern is used. For example, when an object is modified, its dependent objects are automatically notified. The observer pattern is a behavioral pattern.

introduce

Intent: Defines a one-to-many dependency between objects so that when an object’s state changes, all dependent objects are notified and automatically updated.

Main solution: notifying one object of state changes to other objects with ease of use and low coupling, ensuring a high degree of collaboration.

When to use: When the state of an object (target object) changes, all dependent objects (observer objects) are notified, broadcast notification.

How to fix it: Using object-oriented techniques, this dependency can be weakened.

Key code: There is an ArrayList of observers in the abstract class.

Application example:

  1. At an auction, the auctioneer watches for the highest bid and informs the other bidders.
  2. In Journey to the West, Wukong asks the Bodhisattva to surrender Red Boy, and the Bodhisattva spills water on the ground and invites an old turtle, who is the observer, to observe the bodhisattva’s action of splashing water.

Advantages:

  1. The observer and the observed are abstractly coupled.
  2. Create a set of triggers.

Disadvantages:

  1. If an observed object has many direct and indirect observers, it will take a long time to notify all the observers.
  2. If there is a cyclic dependency between the observer and the object of observation, the object of observation will trigger a cyclic call between them, which may cause the system to crash.
  3. The observer mode has no mechanism to let the observer know how the object has changed, only that the object has changed.

Usage scenario:

  1. An abstract model has two aspects, one of which depends on the other. Encapsulating these aspects in separate objects allows them to be changed and reused independently.
  2. A change in one object causes one or more other objects to change, and not knowing exactly how many objects will change can reduce the coupling between objects.
  3. An object must notify other objects without knowing who those objects are.
  4. A trigger chain needs to be created in the system. The behavior of object A will affect object B, and the behavior of object B will affect object C… , you can use the observer pattern to create a chain triggering mechanism.

Notes:

  1. JAVA already has classes that support the Observer pattern.
  2. Avoid circular references.
  3. If executed sequentially, an observer error causes the system to jam, usually asynchronously.

The state pattern

In a State Pattern, the behavior of a class changes based on its State. This type of design pattern is a behavioral pattern. In state mode, we create objects representing various states and a context object whose behavior changes as the state object changes.

introduce

Intent: Allows an object to change its behavior when its internal state changes, so that the object appears to have modified its class.

Main solution: The behavior of an object depends on its state (properties), and can change its related behavior as its state changes.

When to Use: The code contains a number of conditional statements related to object state.

How to fix it: Abstract out the various concrete state classes.

Key code: Usually there is only one method in a command mode interface. A state mode interface has one or more methods. Furthermore, the methods of the class that implement the state mode generally return values or change the values of instance variables. In other words, the state pattern is generally related to the state of the object. Methods that implement classes have different functions, overriding methods in the interface. Status mode, like command mode, can also be used to eliminate if… Else conditional selection statements.

Application example:

  1. Players can be normal when playing basketball. Abnormal state and abnormal state.
  2. In Zeng Houyi’s chime bells,’ clock is an abstract interface ‘,’ clock A’, etc., is A concrete state, and ‘Zeng Houyi chime bells’ is A concrete Context.

Advantages:

  1. Encapsulates the transformation rules.
  2. Enumerates possible states. Before enumerating states, you need to determine the type of state.
  3. Put all the behavior associated with a state into one class, and you can easily add new states, changing the object’s behavior simply by changing the object’s state.
  4. Allows the state transition logic to be integrated with the state object rather than a single giant conditional block.
  5. You can share a state object with multiple environment objects to reduce the number of objects in the system.

Disadvantages:

  1. The use of state mode necessarily increases the number of system classes and objects.
  2. The structure and implementation of state pattern are complicated, and improper use will lead to confusion of program structure and code.
  3. State modes do not support the “open closed principle” very well. For state modes that can switch states, adding new state classes requires changing the source code responsible for the transition to the new state, and changing the behavior of a state class requires changing the source code of the corresponding class.

Usage scenario:

  1. A scenario in which behavior changes as states change.
  2. A substitute for a condition or a branch statement.

Note: Use state mode when behavior is constrained by state, and there are no more than five states.

Empty object pattern

In the Null Object Pattern, an empty Object replaces the Null Object instance check. Instead of checking for Null values, a Null object reflects a relationship that does not take any action. Such Null objects can also provide default behavior when data is not available. In the empty object pattern, we create an abstract class that specifies various operations to be performed, and an entity class that extends that class. We also create an empty object class that does nothing to that class, and that empty object class is used seamlessly where we need to check for null values.

The strategy pattern

In a Strategy Pattern, the behavior of a class or its algorithm can change at run time. This type of design pattern is a behavioral pattern. In the policy pattern, we create objects that represent various policies and a context object whose behavior changes as the policy object changes. The policy object changes the execution algorithm of the context object.

introduce

Intent: Define a set of algorithms, encapsulate them one by one, and make them interchangeable.

Main solution: in the case of multiple similar algorithms, use if… Else is complicated and difficult to maintain.

When to Use it: A system has many, many classes, and what distinguishes them is their immediate behavior.

How to fix it: Encapsulate these algorithms into classes and replace them arbitrarily.

Key code: implement the same interface.

Application example:

  1. Each of Zhuge Liang’s tricks up his sleeve is a strategy.
  2. Travel way of travel, choose to ride a bike. By car, every mode of travel is a strategy.
  3. LayoutManager in the JAVA AWT.

Advantages:

  1. The algorithm can be switched freely.
  2. Avoid using multiple conditions.
  3. Scalability is good.

Disadvantages:

  1. Policy classes will grow.
  2. All policy classes need to be exposed.

Usage scenario:

  1. If there are many classes in a system that differ only by their behavior, then the policy pattern allows an object to dynamically choose one behavior among many.
  2. A system needs to dynamically choose one of several algorithms.
  3. If an object has many behaviors, without appropriate patterns, those behaviors can be implemented using multiple conditional selectors.

Note: If a system has more than four policies, consider using mixed mode to address policy class inflation.

Template pattern

In a Template Pattern, an abstract class exposes a mode/Template that defines the methods that execute it. Its subclasses can override the method implementation as needed, but calls will be made as defined in the abstract class. This type of design pattern is a behavioral pattern.

introduce

Intent: Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. The template approach allows subclasses to redefine certain steps of an algorithm without changing the structure of the algorithm.

Main solution: some methods are common, but the method is rewritten in every subclass.

When to Use it: There are some general methods.

How to solve it: Abstract these generic algorithms.

Key code: in the abstract class implementation, other steps in the subclass implementation.

Application example:

  1. When the house is built, the foundation, wiring and plumbing are all the same, and only later in the building do you add closet and fence differences. 2. In the Journey to the West, the Bodhisattva set 81 difficulties, which is a top-level logical skeleton.
  2. The support for Hibernate in Spring encapsulates some of the established methods, such as starting transactions. Get Session. Close Session, programmers do not repeat to write those already standardized code, directly throw an entity can save.

Advantages:

  1. Encapsulate invariant parts and extend variable parts.
  2. Extract common code for easy maintenance.
  3. Behavior is controlled by the parent class and implemented by the child class.

Disadvantages: Each different implementation requires a subclass to implement, increasing the number of classes and making the system larger.

Usage scenario:

  1. There are methods shared by multiple subclasses with the same logic.
  2. Important, complex methods can be considered as template methods.

Note: In order to prevent malicious operations, the final keyword is added to the general template method.

Visitor pattern

In the Visitor Pattern, we use a Visitor class that changes the execution algorithm of the element class. In this way, the element’s execution algorithm can change as the visitor changes. This type of design pattern is a behavioral pattern. According to the pattern, the element object has accepted the visitor object so that the visitor object can handle the operations on the element object.

introduce

Intent: Primarily to separate data structures from data operations.

Main solution: stable data structure and variable operation coupling problem.

When to use: You need to do many different and unrelated operations on objects in an object structure, and you need to avoid “contaminating” the classes of those objects by these operations. Use visitor mode to encapsulate these into classes.

How to solve this problem: Add an interface to the class that is being accessed.

Key code: There is a method in the data base class that accepts the visitor, passing in a reference to itself.

Application example: You are a guest at a friend’s house, you are the visitor, the friend accepts your visit, you through the friend’s description, and then make a judgment about the friend’s description, this is the visitor pattern.

Advantages:

  1. Consistent with the single responsibility principle.
  2. Excellent scalability.
  3. Flexibility.

Disadvantages:

  1. Specific elements publish details to visitors in violation of the Demeter principle.
  2. Specific elements are more difficult to change.
  3. Violates the dependency inversion principle by relying on concrete classes and not on abstractions.

Usage scenario:

  1. The classes corresponding to objects in an object structure rarely change, but it is often necessary to define new operations on this object structure.
  2. There are many different and unrelated operations that need to be performed on objects in an object structure, and you want to avoid “contaminating” the classes of those objects by those operations, and you don’t want to modify those classes when you add new operations.

Note: The visitor can unify the functionality and can do reports, UI, interceptors, and filters.

Specification model

The Specification pattern can be thought of as an extension of the composite pattern. Sometimes there are conditions in a project that determine the business logic, and those conditions can be taken out and combined with some relationship (and, or, or not), giving you the flexibility to customize the business logic. In addition, in applications such as queries and filters, you can simplify the implementation logic by pre-defining multiple conditions and then using the combination of these conditions to process queries or filters rather than using logical judgment statements. Each condition here is a specification, and multiple specifications/conditions form a combined specification in some logical relationship by concatenation.

Visitor pattern

We do business to bank counter, can open counter of a few individual business normally, it is ok that you go among them any counter is dealt with. Our visitor model works well in this scenario: for bank counters, they are unchanged, meaning that there is no need to change the counters that provide personal services today and tomorrow. And we as visitors, today to the bank may be to take consumption water, tomorrow to the bank may be to deal with mobile banking business, these are the operations of our visitors, has been changing. The visitor pattern represents an operation that acts on the elements of an object structure. It allows you to define new operations on elements without changing their classes.


The MVC pattern

The MVC pattern represents the Model-view-Controller pattern. This pattern is used for layered development of applications.

  • Model – A Model represents an object or JAVA POJO that accesses data. It can also have logic to update the controller as the data changes.
  • View – A View represents a visualization of the data that the model contains.
  • Controller – The Controller acts on the model and view. It controls the flow of data to model objects and updates the view as the data changes. It separates the view from the model.

Agent model

The Business Delegate Pattern is used to decouple the presentation layer from the Business layer. It is basically used to reduce communication or remote query capabilities to business-layer code in the presentation layer code. In the business layer we have the following entities.

  • Client-presentation layer code can be JSPS, servlets, or UI Java code.
  • Business Delegate – An entry class for client entities that provides access to Business service methods.
  • LookUp Service – The Service object is responsible for obtaining the relevant business implementation and providing the business object with access to the business representative object.
  • Business Service – Business Service interface. The entity class that implements the business service provides the actual business implementation logic.

Composite entity pattern

Composite Entity patterns are used in the EJB persistence mechanism. A composite entity is an EJB entity bean that represents a diagram of the object. When updating a composite entity, the internal dependent object Beans are automatically updated because they are managed by the EJB entity bean. Here are the participants of the composite entity bean.

  • Composite Entity – This is the primary Entity bean. It can be coarsely grained, or it can contain a coarsely grained object to last the lifecycle.
  • Coarder-grained Object – This Object contains dependent objects. It has its own lifecycle and manages the lifecycle of dependent objects.
  • Dependent Object – A Dependent Object is an Object that depends on a coarser grained Object for its lifetime.
  • Strategies – Strategies represent how composite entities are implemented.

Data access object pattern

The Data Access Object Pattern or DAO Pattern is used to separate low-level Data Access apis or operations from higher-level business services. Here are the participants in the data Access Object pattern.

  • Data Access Object Interface – This Interface defines the standard operations to be performed on a model Object.
  • Data Access Object Concrete Class – This class implements the above interface. This class is responsible for getting data from a data source, which can be a database, XML, or some other storage mechanism.
  • Model Object/Value Object – This Object is a simple POJO that contains get/set methods to store data retrieved using the DAO class.

Front controller mode

The Front Controller Pattern is used to provide a centralized request processing mechanism where all requests are handled by a single handler. The handler can do authentication/authorization/logging, or track the request and then pass the request to the appropriate handler. Here are the entities for this design pattern.

  • Front Controller – a single handler that handles all types of requests from an application, which can be either a Web-based or desktop-based application.
  • Dispatcher – The front controller may use a Dispatcher object to dispatch requests to the appropriate specific handler.
  • View – A View is an object created for a request.

Intercepting filter Mode

Intercepting Filter patterns are used to do some pre-processing/post-processing of an application’s request or response. Filters are defined and applied to requests before they are passed to the actual target application. Filters can do authentication/authorization/logging, or track requests and pass them to the appropriate handler. Here are the entities for this design pattern.

  • Filter – A Filter that performs certain tasks before or after the request handler executes the request.
  • Filter Chain – A Filter Chain takes multiple filters and executes them on Target in the order defined.
  • Target-target objects are request handlers.
  • Filter Manager – The Filter Manager manages filters and Filter chains.
  • Client – A Client is an object that sends requests to a Target object.

Refer to the link

  • Github.com/domnikl/Des…
  • Laravelacademy.org/category/de…
  • www.runoob.com/design-patt…