Home  >  Article  >  Java  >  Summarize the main points of use of 24 common design patterns and their Java implementation

Summarize the main points of use of 24 common design patterns and their Java implementation

php是最好的语言
php是最好的语言Original
2018-08-06 14:09:303006browse

Design patterns are specific solution patterns (routines) that can be used repeatedly for specific problems in specific situations that constantly arise. This article summarizes the key points of using 24 common design patterns according to the three categories of creation, structure, and behavioral, including applicable scenarios, solutions, and their corresponding Java implementations.

1 Overview

1.1 Concept

Design pattern is a solution to a certain "problem" in a certain "Context" that constantly appears. Some kind of "solution":

  • The "problem" must be recurring, and the "solution" must be repeatedly applicable;

  • "Problem" contains "a goal" and "a set of constraints". When the solution strikes a balance between the two, it is a useful pattern;

  • Design patterns are not laws Criteria are just guidelines. You can fine-tune them as needed during actual use. You just need to make notes so that others can understand;

  • Many seemingly new models are actually based on existing models. Variation;

  • Principle of pattern selection: try to design in the simplest way, unless you use design patterns to adapt to possible changes in the future, because design patterns will introduce more classes For more complex relationships, don't use patterns for the sake of using patterns.

1.2 Six Principles

The English initials of the six principles put together are SOLID (stable), so it is also called the SOLID principle.

1.2.1 Single Responsibility Principle

There should never be more than one reason for a class to change.
A class has only one Responsibilities, rather than multiple responsibilities coupled in one class (for example, interface and logic should be separated).

1.2.2 Open Closed Principle

Software entities like classes, modules and functions should be open for extension but closed for modifications.
Open for extension, for modifications Close, use interfaces and abstract classes.

1.2.3 Liskov Substitution Principle

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
Ensure Where the parent class can appear, the subclass can definitely appear. This is the cornerstone of inheritance and reuse.

1.2.4 Least Knowledge Principle

Only talk to your immediate friends.
Low dependency, each entity is as independent as possible, and interactions are minimized.

1.2.5 Interface Segregation Principle

The dependency of one class to another one should depend on the smallest possible interface.
The client should not depend on It doesn't use the method. Try to use multiple interfaces to divide and combine functions instead of coupling multiple functions with a single interface.

1.2.6 Dependency Inversion Principle

High level modules should not depends upon low level modules.
Both should depend upon abstractions.Abstractions should not depend upon details. Details should depend upon abstractions.
Depend on abstraction (interface or abstract class), not concrete (concrete class).

1.3 Value

Design Pattern is a set of classification and cataloging summary of code design experience that is used repeatedly, known to most people. The purpose of using design patterns is to reuse code, make the code easier to understand by others, and ensure code reliability.
Design patterns complicate seemingly simple problems. However, the "simple" design has poor flexibility, is inconvenient to expand in the current project, and cannot be used in other projects, which is equivalent to "one-time code". The code of the design pattern has a clear structure and is easy to expand in the current project. It is also applicable to other projects and is a universal design.
After many programmers come into contact with design patterns, they feel that they have met at a later date. They feel that they have been reborn and have reached a new level. Design patterns can be used as a standard for dividing programmers' levels.
However, we cannot fall into the trap of patterns. If we try to apply patterns in order to use them, we will fall into formalism.

1.4 Selection method

  • Each design pattern implies several OO principles. When there is no suitable design pattern to choose from, you can return to the OO principles. To make a choice;

  • The best way to use patterns is to have various patterns in your mind and see where these patterns can be used in existing designs or codes to reuse experience;

  • The power of shared design pattern vocabulary (including verbal names, naming of classes and methods in the code):
    (1) When communicating with others, mention the name of the design pattern, and it will be hidden. Contains its patterns;
    (2) Using patterns to observe software systems can stay at the design level without being stuck on trivial object details;
    (3) Teams use design patterns to communicate and share their opinions Not easily misunderstood.

1.5 Important Books

Authors: Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, later known as the "Gang" of Four, GoF). There are two books:

1.5.1 "Head First Design Pattern"

Highly recommended reading. The English title is "Head First Design Patterns".
Anyone who believes in Jesus must read the Bible, and anyone who believes in OO (object-oriented) must read "Head First Design Patterns" by the foursome, the official website Head First Design Patterns. 2004 The book won the Jolt Award (similar to the Oscars in the film field).

  • is the hero who classified patterns for the first time, starting a great leap forward in the software field;

  • Pattern template: including name, class Purpose, intention, motivation, applicability, class diagram, participants and their collaboration, results, implementation, sample code, known applications, related patterns, etc.

1.5.2 "Design Patterns: The Foundation of Reusable Object-Oriented Software"

The English title is "Design Patterns: Elements of Reusable Object-Oriented Software" . Also written by the quartet.
is a book about software design in the field of software engineering. It proposes and summarizes standard solutions to some common software design problems, called software design patterns. This book was first published on October 21, 1994, and had printed 40 copies as of March 2012.

2 Classification and Definition

Design patterns can be divided into three major categories, and each category contains a number of specific patterns.
Several patterns that are easily confused: simple factory S / abstract factory A / factory method F / template method T

  • The ones with the word "factory": are only used to create instances , such as S/A/F; without limitation, such as T; with the words

  • "method": with the word "method": without additional client participation, it can operate independently, such as F/T; without it requires additional client calls, such as S/A.

2.1 Creational Patterns

is used for object creation. Put the work of creating an object in another object, or defer it to a subclass.

2.1.1 Singleton

Ensure that a class has only one instance and provide a global access point.
It should be noted that using a singleton under multiple class loaders will result in a singleton instance under each type of loader, because each class loader has its own independent namespace.
The singletons in JDK include Runtime.getRuntime(), NumberFormat.getInstance()
The following summarizes four thread-safe Java implementation methods. Each implementation can be called with Singleton.getInstance().method();.

2.1.1.1 Hungry Man Way

Key idea: As a static global variable of the class, it is instantiated when the class is loaded.
The disadvantage is that the instance has been instantiated before it is actually used (or may not be used at all), which is a waste of resources.
For Hotspot VM, if this class is not involved, it is actually instantiated when getInstance() is called for the first time.

/**
 * @author: kefeng.wang
 * @date: 2016-06-07 10:21
 **/public class Singleton {
    private static Singleton instance = new Singleton();    private Singleton() {
    }    // 基于 classLoader 机制,自动达到了线程安全的效果
    public static Singleton getInstance() {        return instance;
    }    public void method() {
        System.out.println("method() OK.");
    }
}
2.1.1.2 The lazy way

Key idea: achieve synchronization on the method getInstance().
The disadvantage is that every time getInstance() is called, a lock will be locked, but in fact it is only needed for the first instantiation. Subsequent locking is a waste, resulting in a significant performance drop.

/**
 * @author: kefeng.wang
 * @date: 2016-06-07 10:21
 **/public class Singleton {
    private static Singleton instance = null;    private Singleton() {
    }    public static synchronized Singleton getInstance() {        if (instance == null) {
            instance = new Singleton();
        }        return instance;
    }    public void method() {
        System.out.println("method() OK.");
    }
}
2.1.1.3 Lazy way (double check locking)

Key idea: Check to see that it has not been created yet when not synchronized, and then instantiate it after checking to see that it has not been instantiated yet. In order to greatly reduce synchronization situations.
The disadvantage is: JDK5 is required, otherwise many JVM implementations of volatile will cause double locking to fail. However, very few developers now use JDK5, so this shortcoming is not relevant.

/**
 * @author: kefeng.wang
 * @date: 2016-06-07 10:21
 **/public class Singleton {
    private volatile static Singleton instance = null; // 注意 volatile

    private Singleton() {
    }    public static Singleton getInstance() {        if (instance == null) { // 初步检查:尚未实例化
            synchronized (Singleton.class) { // 再次同步(对 Singleton.class)
                if (instance == null) { // 确认尚未实例化
                    instance = new Singleton();
                }
            }
        }        return instance;
    }    public void method() {
        System.out.println("method() OK.");
    }
}
2.1.1.4 Internal static class method (recommended!)

Key idea: Global static members are placed in internal classes and are instantiated only when the internal class is referenced to achieve delay The purpose of instantiation. This is a perfect solution:

  • Ensures delayed instantiation to the call to getInstance();

  • No locking required, good performance;

  • Not limited by JDK version.

/**
 * @author: kefeng.wang
 * @date: 2016-06-07 10:21
 **/public class Singleton {
    private static class InstanceHolder { // 延迟加载实例
        private static Singleton instance = new Singleton();
    }    private Singleton() {
    }    public static Singleton getInstance() {        return InstanceHolder.instance;
    }    public void method() {
        System.out.println("method() OK.");
    }
}

2.1.2 Builder

Encapsulate the object creation process into a generator object, and the customer calls it step by step to complete the creation.
Please refer to the source code of StringBuilder for Java implementation. Here are its usage effects:

StringBuilder sb = new StringBuilder();
sb.append("Hello world!").append(123).append('!');
System.out.println(sb.toString());

2.1.3 Simple Factory ★

is not real "Design Patterns". It is a factory implementation class itself, directly providing creation methods (can be multiple), which can be static methods. There are Boolean.valueOf(String) and Class.forName(String) in the JDK.

/**
 * @author: kefeng.wang
 * @date: 2016-06-09 19:42
 **/public class DPC3_SimpleFactoryPattern {
    private static class SimpleFactory {
        public CommonProduct createProduct(int type) { // 工厂方法,返回“产品”接口,形参可无
            if (type == 1) {                return new CommonProductImplA(); // 产品具体类
            } else if (type == 2) {                return new CommonProductImplB();
            } else if (type == 3) {                return new CommonProductImplC();
            } else {                return null;
            }
        }
    }    private static class SimpleFactoryClient {
        private SimpleFactory factory = null;        public SimpleFactoryClient(SimpleFactory factory) {            this.factory = factory;
        }        public final void run() {
            CommonProduct commonProduct1 = factory.createProduct(1);
            CommonProduct commonProduct2 = factory.createProduct(2);
            CommonProduct commonProduct3 = factory.createProduct(3);
            System.out.println(commonProduct1 + ", " + commonProduct2 + ", " + commonProduct3);
        }
    }    public static void main(String[] args) {
        SimpleFactory factory = new SimpleFactory(); // 工厂实例
        new SimpleFactoryClient(factory).run(); // 传入客户类
    }
}

2.1.4 Abstract factory ★

An abstract class that defines abstract methods for creating objects. Implement methods for creating objects in multiple inherited implementation classes.
The client flexibly selects the implementation class to complete the creation of the object.
The JDK that adopts this mode is NumberFormat.getInstance().

2.1.5 Factory method ★

The division of labor between abstract classes and implementation classes in creating methods is similar to "abstract factory".
The difference is: This mode does not require a client, and its own methods can complete the operations before and after object creation.

2.1.6 Prototype

When the process of creating an instance is complex or expensive, it can be achieved through cloning. For example, Java's Object.clone().

2.2 Structural Patterns

is used for the combination relationship of classes or objects.

2.2.1 Adapter

Adapting one interface to another desired interface can eliminate compatibility problems caused by interface mismatch.
For example, adapt Enumeration1a4db2c2c2313771e5742b6debf617a1 to Iterator1a4db2c2c2313771e5742b6debf617a1, Arrays.asList() to T[] Adapt to List8742468051c85b06f0a0af9e3e506b5c.

2.2.2 Bridge ★

Things are composed of multiple factors, and each factor has an abstract class and multiple implementation classes. In the end, these multiple factors can Free combination.
For example, a variety of remote controls, a variety of TV sets, a variety of car models, a variety of road conditions, and a variety of drivers. JDBC and AWT in the JDK.

2.2.3 Composite ★

Organize the "part/whole" of the object in a tree structure so that a single object or a combination of multiple objects can be treated uniformly.
Such as multi-level menus, binary trees, etc.

2.2.4 Decorator

The runtime dynamically attaches responsibilities to the decorator.
There are two ways to extend functions. Class inheritance is statically determined at compile time, while decorator mode is dynamically determined at runtime, which has unique advantages.
For example, StringReader is decorated with LineNumberReader, and line related interfaces are extended for the character stream.

2.2.5 Facade ★

Provides a unified high-level interface to access a group of interfaces in the subsystem, making the subsystem easier to use.
For example, when a computer starts (or shuts down), it calls the respective startup (or shutdown) interfaces of the CPU/memory/disk.

2.2.6 Flyweight

Use sharing technology to effectively support a large number of fine-grained objects.
For example, a text processor does not need to generate multiple glyph objects for multiple occurrences of each character, but multiple occurrences of the same character in an external data structure share a glyph object.
Integer.valueOf(int) in JDK adopts this mode.

2.2.7 Proxy

The proxy creates and holds a reference to the subject. When the client calls the proxy, the proxy will forward it to the subject.

For example,
Collections in Java, collection views, RMI/RPC remote calls, cache agents, firewall agents, etc.

2.3 Behavioral Patterns

is used for the calling relationship of classes or objects.

2.3.1 Chain of responsibility

A request is passed along a chain until a processor on the chain handles it.

For example, filters in SpringMVC.

2.3.2 Command(Command)

Encapsulate the command as an object, which can be stored/loaded, transferred, executed/undone, queued, logged, etc. at will, and the "requester of the action" Decoupling from the "executor of the action".

Participants include Invoker (caller) => Command (command) => Receiver (executor).
Such as scheduled tasks, thread tasks
Runnable.

2.3.3 Interpreter mode (Interpreter)

is used to create a simple language interpreter that can handle scripting languages ​​and programming languages, creating a class for each rule.

For example,
java.util.Pattern, java.text.Format in JDK.

2.3.4 Iterator (Iterator)

Provides a method to sequentially access each element in an aggregate object without exposing its internal representation.

For example,
java.util.Iterator and java.util.Enumeration in JDK.

2.3.5 Mediator

Use a mediating object to encapsulate a series of object interactions. The mediating object eliminates the need for objects to explicitly reference each other, thus loosening their coupling and The interaction between them can be changed independently.

For example,
java.util.Timer and java.util.concurrent.ExecutorService.submit() in JDK.

2.3.6 Memento

The memento object is used to store a snapshot of the internal state of another object, and can be stored externally, and can be restored to the original state later. Such as Java serialization.

For example,
java.util.Date and java.io.Serializable in JDK.

2.3.7 Observer

One-to-many dependency between objects. When the status of the observed object changes, the observer will receive a notification.

Participants include Observable (observable) / Observer (observer).
For example, events in RMI,
java.util.EventListener.

2.3.8 State

When the internal state of an object changes, its behavior also changes. Its internal implementation is to define a state parent class and extend the state subclass for each state. When the internal state of the object changes, the selected state subclass also switches accordingly, but the outside only needs to interact with the object and does not know The existence of state subclasses.

For example, the stop/play/pause status of the video player.

2.3.9 Strategy

Define a set of algorithms, which are encapsulated separately and are independent of customers. When the algorithm is changed, it will not affect customer use.

For example, different characters in the game can use various equipment, and these equipment can be packaged in a strategic way.
For example,
java.util.Comparator#compare() in JDK.

2.3.10 Template method (Template method) ★

The abstract class defines a top-level logical framework (called "template method"), and some steps (can create instances or other operations) are delayed to subclass implementation , it can operate independently.
When the operation implemented by the subclass is to create an instance, the template method becomes the factory method pattern, so the factory method is a special template method.

2.3.11 Visitor ★

Without modifying the data structure of the visitor, the visitor encapsulates the access operation. The key point is that the visitor provides the accessed Interface.
Applicable scenarios are when the visitors are stable but the visitors are flexible, or the visitors have many different types of operations.

2.4 Compound pattern(Compound)

Combine two or more patterns to form a solution to solve common problems that often occur.
Use case: MVC pattern (Model/View/Controller), using Observer, Strategy, Composite, Factory, Decorator and other patterns.
Use cases: Household appliances = interface + data + logic control, shopping mall = store + warehouse + logic control.

3 Reference Document

Wikipedia: Design Pattern
Wikipedia: Software design pattern
TutorialsPoint: Design Pattern

Design patterns are specific situations that constantly arise Below, specific solution patterns (routines) that can be used repeatedly for specific problems. This article summarizes the key points of using 24 common design patterns according to the three categories of creation, structure, and behavioral, including applicable scenarios, solutions, and their corresponding Java implementations.
Related articles:

Detailed explanation of common Java design patterns - Factory pattern

Detailed explanation of the memo pattern and its implementation in Java design pattern programming

The above is the detailed content of Summarize the main points of use of 24 common design patterns and their Java implementation. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn