Hello everyone , I'm Xiaoyu .

The principle or source code of every technology stack we usually use is more or less related to the concept of design patterns , It can also be said that , Only a better grasp of the design pattern , Our ability to code More normative 、 concise , More efficient .

secondly , Design patterns are mostly based on the experience of our predecessors , Standing on the shoulders of giants , Absorb their experience and lessons , Our way of coding will last longer .

meanwhile , During our interview, too Bonus options , If you can tell the interviewer about the design pattern , The interviewer will certainly look at you with new eyes . In the work , Have a good idea of design patterns , It will also be of great help to the development of the project .

Next , Follow Xiaoyu to see what design patterns we need to know ~

Preface

Generally speaking, design patterns are divided into three categories :

Create pattern : Factory method model 、 Abstract factory pattern 、 The singleton pattern 、 Builder pattern 、 Archetypal model .

Structural mode : Adapter pattern 、 Decorator mode 、 The proxy pattern 、 Appearance mode 、 Bridging mode 、 Portfolio model 、 The flyweight pattern .

Behavioral patterns : The strategy pattern 、 Template method pattern 、 Observer mode 、 Iterative subpattern 、 The chain of responsibility model 、 Command mode 、 Memo mode 、 The state pattern 、 Visitor mode 、 Intermediary model 、 Interpreter mode .

The singleton pattern

Concept

Make sure there is only one instance of a class , and self-instantiation And provide the whole system with this example .

Use scenarios

  • The environment that requires a unique serial number to be generated ;

  • A shared access point or shared data is needed throughout the project , For example, one Web Counters on the page , No need to record every refresh to the database , Use singleton mode to keep the counter value , And make sure it's thread safe ;

  • Creating an object consumes too many resources , To access IO And database resources ;

  • A lot of static constants and static methods need to be defined ( Such as tools ) Environment , You can use the singleton mode ( Of course , It can also be declared directly as static The way ).

Code example

Thread safety :

public class Singleton {
    private static final Singleton singleton = new Singleton();
    // Limit the generation of multiple objects
    private Singleton(){
    }
    // Through this method, the instance object is obtained
    public static Singleton getSingleton(){
        return singleton;
    }
    // Class , Try to be  static
    public static void doSomething(){
    }
}

Thread unsafe :

public class Singleton {
    private static Singleton singleton = null;
    // Limit the generation of multiple objects
    private Singleton(){
    }
    // Through this method, the instance object is obtained
    public static Singleton getSingleton(){
        if(singleton == null){
            singleton = new Singleton();
        }
        return singleton;
    }
}

Unsafe for threads :

stay getSingleton Methods before adding synchronized keyword , It can also be in getSingleton Add... In the method synchronized To achieve .

Factory mode

Concept

Defines an interface for creating objects , Let the subclass decide which class to instantiate . The factory method makes a class Instantiation delay To its subclasses .

Use scenarios

jdbc Connect to database , Hardware access , Reduce the generation and destruction of objects

structure

Simple factory model : A module only needs one factory class , There's no need to produce it , Using static methods

Multiple factory classes : Every race ( Specific product categories ) They all correspond to a Creator , Each creator is responsible for creating the corresponding product object independently , Very consistent with the principle of single responsibility

Instead of singleton mode : The core requirement of singleton mode is that there is only one object in memory , With the factory method pattern, you can also produce only one object in memory

Delay initialization :ProductFactory Responsible for the creation of product class objects , And through prMap Variable produces a cache , Keep... For objects that need to be reused again

Code example

Product Responsible for defining product commonalities for abstract product classes , Realize the most abstract definition of things ;

Creator Create classes for abstractions , It's the abstract factory , How to create a product class is determined by the implementation factory ConcreteCreator Accomplished .

public class ConcreteCreator extends Creator {
    public <T extends Product> T createProduct(Class<T> c){
        Product product=null;
        try {
            product =
                    (Product)Class.forName(c.getName()).newInstance();
        } catch (Exception e) {
        // exception handling
        }
        return (T)product;
    }
}

Abstract factory pattern

Concept

Provides an interface for creating a set of related or interdependent objects , and No need to specify their concrete classes .

Use scenarios

A family of objects ( Or a group of unrelated objects ) All have the same constraints .

When it comes to different operating systems , You can consider using the abstract factory pattern .

Code example

public abstract class AbstractCreator {
    // establish  A  Product family
    public abstract AbstractProductA createProductA();
    // establish  B  Product family
    public abstract AbstractProductB createProductB();
}

Template method pattern

Concept

Define the framework of an algorithm in an operation , Instead, defer some steps to subclasses . So that subclasses can Without changing the structure of an algorithm You can redefine some specific steps of the algorithm .

Use scenarios

  • Multiple subclasses have public methods , And when the logic is basically the same .

  • important 、 Complex algorithms , The core algorithm can be designed as a template method , The peripheral details are implemented by each subclass .

  • Refactoring , Template method pattern is a frequently used pattern , Extract the same code into the parent class , And then through the hook function ( see “ Template method pattern extension ”) Restrain their actions .

structure

Abstract template :AbstractClass For abstract templates , Its methods fall into two categories :

1、 The basic method : It's also called basic operation , Methods implemented by subclasses , And when the template method is called .

2、 Template method : There can be one or more , It's usually a specific method , It's a framework , Realize the scheduling of basic methods , Complete the fixed logic .

Be careful : In order to prevent malicious operation , General template methods add final keyword , Overwriting... Is not allowed .

Specific template : Implement one or more abstract methods defined by the parent class , That is, the basic methods defined by the parent class are implemented in the child class .

Code example

package templateMethod;
public class TemplateMethodPattern
{
    public static void main(String[] args)
    {
        AbstractClass tm=new ConcreteClass();
        tm.TemplateMethod();
    }
}
// abstract class
abstract class AbstractClass
{
    public void TemplateMethod() // Template method
    {
        SpecificMethod();
        abstractMethod1();
        abstractMethod2();
    }
    public void SpecificMethod() // The specific methods
    {
        System.out.println(" Concrete methods in abstract classes are called ...");
    }
    public abstract void abstractMethod1(); // Abstract method 1
    public abstract void abstractMethod2(); // Abstract method 2
}
// Specific subclass
class ConcreteClass extends AbstractClass
{
    public void abstractMethod1()
    {
        System.out.println(" Abstract method 1 The implementation of is called ...");
    }
    public void abstractMethod2()
    {
        System.out.println(" Abstract method 2 The implementation of is called ...");
    }
}

Builder pattern

Concept

Separate the construction of a complex object from its representation , bring The same build process can create different representations .

Use scenarios

  • Same method , Different order of execution , When different event results are produced , You can use builder mode .

  • Multiple components or parts , Can be assembled into an object , But the results are not the same , You can use this mode .

  • The product category is very complex , Or the different calling order in the product class produces different performance , It's a good time to use builder mode .

structure

Product Product class : The template method pattern is usually implemented , There are template methods and basic methods .

Builder Abstract builder : Standardizing the formation of products , It is usually implemented by subclasses .

ConcreteBuilder Specific builder : Implement all methods defined by an abstract class , And return a group created object .

Director Directors : Responsible for arranging the order of existing modules , Then tell Builder Start building

Code example

public class ConcreteProduct extends Builder {
     private Product product = new Product();
     // Set up product parts
     public void setPart(){
             /*
              *  Logical processing within the product class
              */
     }  
     // Build a product
     public Product buildProduct() {
             return product;
     }
}

The proxy pattern

Concept

For other objects Provide a proxy to control Access to this object .

structure

Subject Abstract theme role : Abstract topic classes can be abstract classes or interfaces , Is the most common definition of business type , No special requirements .

RealSubject Specific subject roles : It's also called the delegated role 、 Surrogate role . It's the big loser , Is the concrete executor of business logic .

Proxy Surrogate subject role : It's also called the delegate class 、 proxy class . It's responsible for the application of real characters , Methods that define all abstract topic classes 、 Restrict delegating to real theme role implementations , And do the pre-processing and post-processing work before and after the real theme role processing .

classification

General agent : In this mode , The caller only knows the agent, not who the real role is , Shielding the influence of real role changes on high-level modules , Real theme characters can be modified as they want , No impact on high-level modules , As long as you implement the method corresponding to the interface , This mode is very suitable for the situation with high scalability requirements .

Compulsory agency : The concept of mandatory proxy is to find the proxy role from the real role , No direct access to real characters . High level modules just call getProxy You can access all the methods of the real character , It doesn't need to generate a proxy at all , Agent management has been done by real characters themselves .

  • difference : General agency means that we need to know the existence of agency , Then we can visit ; Forcing a proxy means that the caller calls the real role directly , It doesn't matter if the agent exists , The generation of its agent is determined by the real role .

A dynamic proxy : Generate all methods based on the interface being proxied , That is to say, given an interface , Dynamic agents will claim “ I have implemented all the methods under this interface ”. Two independent development lines . Dynamic agent realizes the responsibility of agent , Business logic realizes the related logic functions , There is no necessary coupling relationship between the two . Notice cuts in from another perspective , Finally, coupling in high-level modules , Complete the task of logic encapsulation .

  • Intention : Cross section programming , Enhance or control the behavior of objects without changing our existing code structure .

  • The first condition : The proxy class must implement an interface .

Code example

public Object getProxy(@Nullable ClassLoader classLoader) {
    if (logger.isTraceEnabled()) {
        logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
    }
    Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
    findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
    return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

Archetypal model

Concept

Using prototype instances to specify the kind of objects to create , also By copying these prototypes Create a new object .

Use scenarios

Resource optimization scenarios : Class initialization needs to digest a lot of resources , This resource includes data 、 Hardware resources, etc .

Performance and security requirements scenarios : adopt new Generating an object requires a lot of data preparation or access rights , You can use prototype mode .

A scene where an object has multiple modifiers : An object needs to be provided for other objects to access , And each caller may need to change its value , Sure 、 Consider using prototype mode to copy multiple objects for callers to use .

advantage

Prototype pattern is actually implementation Cloneable Interface , rewrite clone() Method .

Excellent performance : The prototype pattern is a copy of the binary stream in memory , More than direct new The performance of an object is much better , Especially when a large number of objects are generated in a cycle , Prototype pattern can better reflect its advantages .

Escape the constraints of constructors : This is both its advantage and its disadvantage , Copy directly in memory , Constructors don't execute .

Code example

public class PrototypeClass implements Cloneable{
    // Override parent  Object  Method
    @Override
    public PrototypeClass clone(){
        PrototypeClass prototypeClass = null;
        try {
            prototypeClass = (PrototypeClass)super.clone();
        } catch (CloneNotSupportedException e) {
        // exception handling
        }
        return prototypeClass;
    }
}

Intermediary model

Concept

Encapsulating a series of object interactions with a mediation object , Mediators make objects interact without explicit interaction , To make it Loose coupling , And they can change their interaction independently .

Use scenarios

The mediator pattern is suitable for close coupling between multiple objects , The standard of tight coupling is : There is a spider web structure in the class diagram , That is, each class is directly related to other classes .

structure

Mediator The role of an abstract intermediary : Abstract mediator role defines a unified interface , It is used for communication between colleagues' roles .

Concrete Mediator Specific intermediary role : The specific intermediary role realizes cooperative behavior by coordinating the roles of colleagues , So it has to depend on the role of each colleague .

Colleague Colleague role : Every co-worker role knows the intermediary role , And when communicating with other coworker roles , Be sure to collaborate through the intermediary role . There are two types of behavior for each colleague class : One is the behavior of colleagues themselves , Such as changing the state of the object itself , Dealing with your own behavior, etc , This behavior is called spontaneous behavior (SelfMethod), There is no dependency on other colleagues or mediators ; The second is the behavior that must rely on the intermediary to complete , It's called dependency methods (Dep-Method).

Sample code

public abstract class Mediator {
    // Define the colleague class
    protected ConcreteColleague1 c1;
    protected ConcreteColleague2 c2;
    // adopt  getter/setter  Method to inject the colleague class
    public ConcreteColleague1 getC1() {
        return c1;
    }
    public void setC1(ConcreteColleague1 c1) {
        this.c1 = c1;
    }
    public ConcreteColleague2 getC2() {
        return c2;
    }
    public void setC2(ConcreteColleague2 c2) {
        this.c2 = c2;
    }
    // The business logic of the mediator model
    public abstract void doSomething1();
    public abstract void doSomething2();
}

Command mode

Concept

Encapsulate a request as an object , So you can parameterize the client with different requests , Yes Request queuing or request logging , Can provide command undo and restore function .

Use scenarios

Where you think it's a command, you can use command mode , for example , stay GUI In development , The click of a button is a command , You can use command mode ; simulation DOS When ordered , Of course, command mode should also be adopted ; Trigger - Feedback mechanism, etc .

structure

Receive Receiver role : The role is the role of work , The command passed here should be executed , In our example above, it is Group Three implementation classes of ( Demand group , Art Group , Code group ).

Command Command character : All commands that need to be executed are declared here .

Invoker The role of the caller : Received an order , And execute the command . In the example , I ( project manager ) That's the character .

Code example

public class Invoker {
    private Command command;
    //  Set value injection
    public void setCommand(Command command) {
        this.command = command;
    }
    //  Carry out orders
    public void action() {
        this.command.execute();
    }
}

The chain of responsibility model

Concept

Give multiple objects a chance to process requests , This avoids the coupling between the sender and the receiver of the request . Put these objects In a chain , And pass the request along the chain , Until an object processes it .

duty

The abstract processor implements three responsibilities :

1、 Define the processing method of a request handleMessage, The only way to open up ;

2、 Define a chain arrangement setNext, Set up the next handler ;

3、 It defines two methods that a specific requester must implement : Define the level you can handle getHandlerLevel And specific processing tasks echo.

Code example

public abstract class Handler {
    private Handler nextHandler;
    // Every handler has to deal with the request
    public final Response handleMessage(Request request){
        Response response = null;
        // Determine if it's your own processing level
        if(this.getHandlerLevel().equals(request.getRequestLevel())){
            response = this.echo(request);
        }else{ // Not at your own processing level
            // Determine if there is a next processor
            if(this.nextHandler != null){
                response =
                        this.nextHandler.handleMessage(request);
            }else{
            // There is no proper handler , The business deals with itself
            } }
        return response;
    }
    // Set who the next handler is
    public void setNext(Handler _handler){
        this.nextHandler = _handler;
    }
    // Each processor has a processing level
    protected abstract Level getHandlerLevel();
    // Each processor must implement the processing task
    protected abstract Response echo(Request request);
}

matters needing attention

The number of nodes in the chain needs to be controlled , Avoid super long chains , The general practice is to Handler Set a maximum number of nodes in , stay setNext Method to determine whether it has exceeded its threshold , If it exceeds, the chain is not allowed to establish , Avoid unintentional damage to system performance .

Decoration mode

Concept

Dynamically give an object Add some extra responsibilities . In terms of adding functionality , Decoration patterns are more flexible than subclasses .

Use scenarios

  • Need to extend the function of a class , Or add additional functions to a class .

  • You need to dynamically add functionality to an object , These functions can be revoked dynamically .

  • You need to modify or add features to a group of siblings , Of course, the preferred decoration mode .

structure

Component Abstract component :Component It's an interface or an abstract class , It's about defining our core object , That is, the most primitive object . In decorative mode , There must be a fundamental 、 At the core 、 The most primitive interface or abstract class ACTS as Component Abstract component .

ConcreteComponent The specific components :ConcreteComponent It's the core 、 The most primitive 、 The most basic interface or abstract class implementation , That's what you're going to decorate .

Decorator To decorate a character : It's usually an abstract class , What's the use of it ? Implementing interfaces or abstract methods , It doesn't have to have abstract methods , There must be one of its attributes private Variable pointing to the Component Abstract component .

Specific decorative role : Two specific decoration categories , You have to put your core 、 ancestral 、 The most basic things are decorated with other things .

Code example

/**
 *  To decorate a character
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Log
class BufferedReader implements Reader{
    private  Reader reader;
    @Override
    public void read() {
        reader.read();
    }
    public void readLine(){
        read();
        log.info(" And read only one line ");
    }
}

The strategy pattern

Concept

Define a set of algorithms , take Every algorithm is encapsulated , And make them interchangeable .

Use scenarios

  • Multiple classes have only slightly different scenarios in algorithm or behavior .

  • The algorithm needs to switch freely .

  • Scenarios that need to mask algorithm rules .

  • The number of specific strategies exceeds 4 individual , You need to consider using hybrid mode

structure

Context Encapsulate the character : It's also called contextual roles , Link between the above and the next packaging role , Shield high-level modules against policies 、 Direct access to the algorithm , Encapsulate possible changes .

Strategy Abstract strategy roles : Strategy 、 The abstraction of algorithm family , Usually interface , Define the methods and properties that each policy or algorithm must have .

ConcreteStrategy Specific strategic roles : Implement operations in abstract strategies , This class contains specific algorithms .

Code example

public enum Calculator {
    // Addition operation
    ADD("+"){
        public int exec(int a,int b){
            return a+b;
        }
    },
    // Subtraction
    SUB("-"){
        public int exec(int a,int b){
            return a - b;
        }
    };
    String value = "";
    // Define member value types
    private Calculator(String _value){
        this.value = _value;
    }
    // Gets the value of the enumeration member
    public String getValue(){
        return this.value;
    }
    // Declare an abstract function
    public abstract int exec(int a,int b);
}

Adapter pattern

Concept

Interface of a class Transform to another interface expected by the client , So that the two classes that could not work together due to interface mismatch can work together .

Use scenarios

When you have an incentive to modify an interface that is already in production , The adapter mode is probably the best for you . For example, the system has expanded , You need to use an existing or newly created class , But this class does not conform to the interface of the system , What do I do ? Don't think about using adapter patterns in the detailed design phase , The main scenario is in the extended application .

The class adapter

Target The target character : This role defines what interfaces the other classes are converted to , That's our expected interface .

Adaptee The source role : Who do you want to turn into the target character , This “ who ” That's the source role , It's already there 、 A well-functioning class or object , Through the packaging of the adapter role , It's going to be a brand new 、 Beautiful characters .

Adapter Adapter role : The core role of the adapter pattern , The other two roles are existing roles , The adapter role needs to be newly created , Its duties are very simple : Converts the source role to the target role , How to convert ? By inheritance or class Association .

Object adapter

Don't use multiple inheritance or inheritance , Instead, use direct correlation , Or the way of delegation .

The difference between object adapter and class adapter :

Class adapters are inter class inheritance , An object adapter is a composite relationship of an object , It can also be said to be the association of classes , This is the fundamental difference between the two . In the actual project, the object adapter uses a relatively large number of scenarios .

Code example

public class Adapter extends Target
{
    private Adaptee adaptee;
    public Adapter(Adaptee adaptee)
    {
        this.adaptee=adaptee;
    }
    public void request()
    {
        adaptee.specificRequest();
    }
}

Iterator pattern

Concept

It provides a way Access elements in a container object , Without exposing the internal details of the object .

structure

Iterator Abstract iterator : Abstract iterators are responsible for defining interfaces to access and traverse elements , And it's basically fixed 3 A way :first() Get the first element ,next() Access the next element ,isDone() Have you visited the bottom (Java be called hasNext() Method ).

ConcreteIterator Specific iterators : The specific iterator role should implement the iterator interface , Complete the traversal of container elements .

Aggregate Abstract container : The container role is responsible for providing an interface to create a specific iterator role , There must be a similar createIterator() This way , stay Java In general iterator() Method .

Concrete Aggregate Specific containers : The concrete container implements the method of container interface definition , Create an object to hold the iterator .

Code example

/**
 *  Specific iterators
 */
public class ConcreteIterator<T> implements Iterator<T> {
    private List<T> list = new ArrayList<>();
    private int cursor = 0;
    public boolean hasNext() {
        return cursor != list.size();
    }
    public T next() {
        T obj = null;
        if (this.hasNext()) {
            obj = this.list.get(cursor++);
        }
        return obj;
    }
}

Portfolio model

Concept

Combine objects into a tree structure to represent “ part - whole ” Hierarchical structure , Make the use of single object and composite object consistent .

Use scenarios

  • Maintenance and display part - The whole relationship scenario , Like a tree menu 、 File and folder management .

  • A scenario in which some modules or functions can be separated from the whole .

  • As long as it's a tree structure , Just consider using the composite pattern .

structure

Component Abstract component roles : Define the common methods and properties of the composite objects , You can define some default behaviors or properties .

Leaf Leaf component : Leaf object , There are no other branches under it , The smallest unit of traversal .

Composite Tree branches : Branch object , Its function is to combine branch nodes and leaf nodes to form a tree structure .

Code example

public class Composite extends Component {
    // Component containers
    private ArrayList<Component> componentArrayList = new
            ArrayList<Component>();
    // Add a leaf or branch component
    public void add(Component component){
        this.componentArrayList.add(component);
    }
    // Delete a leaf or branch component
    public void remove(Component component){
        this.componentArrayList.remove(component);
    }
    // Get all the leaf and branch components under the branch
    public ArrayList<Component> getChildren(){
        return this.componentArrayList;
    } 
}

Observer mode

Concept

Define a one to many dependency between objects , Make every time an object changes state , Then all objects that depend on it will Be notified and automatically updated .

Use scenarios

  • Associated behavior scenarios . It should be noted that , Association behavior is divisible , instead of “ Combine ” Relationship .

  • Event multi-level trigger scenario .

  • Cross system message exchange scenario , Such as the processing mechanism of message queue .

structure

Subject Observed : Define the responsibilities that must be fulfilled by the observed , It has to be able to dynamically increase 、 Cancel the observer . It is usually an abstract class or an implementation class , Only fulfill the duties that must be fulfilled as the observed : Manage the observer and inform the observer .

Observer The observer : After the observer receives the message , That is to say update( Update method ) operation , Process the received information .

ConcreteSubject The specific observed : Define the business logic of the observed , It also defines which events are notified .

ConcreteObserver Specific observer : Each observation has a different processing response after receiving the message , Each observer has its own processing logic .

Code example

public abstract class Subject {
    // Define an array of observers
    private Vector<Observer> obsVector = new Vector<Observer>();
    // Add an observer
    public void addObserver(Observer o){
        this.obsVector.add(o);
    }
    // Delete an observer
    public void delObserver(Observer o){
        this.obsVector.remove(o);
    }
    // Notify all observers
    public void notifyObservers(){
        for(Observer o:this.obsVector){
            o.update();
        }
    } 
}

Facade mode

Concept

The communication between the outside and the inside of a subsystem is required Through a unified object . The facade pattern provides a high-level interface , Makes the subsystem easier to use .

Use scenarios

  • Provide an interface for external access to a complex module or subsystem

  • Subsystem is relatively independent —— The access to the subsystem from the outside world only needs black box operation

  • Prevent the spread of risk from low-level personnel

structure

Facade The role of the facade : The client can call the methods of this role . This role knows all the functions and responsibilities of the subsystem . In general , This role will delegate all requests sent from the client to the corresponding subsystem , In other words, the role has no actual business logic , It's just a delegate class .

subsystem Subsystem role : There can be one or more subsystems at the same time . Each subsystem is not a separate class , It's a collection of classes . The subsystem does not know the presence of facade . For subsystems , Facade is just another client .

Code pattern

public class Client {
    // The subsystem object of the delegate
    private A a= new A();
    private B b= new B();
    private C c= new C();
    // Methods of providing external access
    public void methodA(){
        this.a.doSomething();
    }
    public void methodB(){
        this.b.doSomething();
    }
    public void methodC(){
        this.c.doSomething();
    }
}

Memo mode

Concept

Without breaking encapsulation , Capture the internal state of an object , And save the state outside the object . In this way, the object can be restored to the original saved state later .

Use scenarios

  • Relevant state scenarios that need to save and recover data .

  • Provide a rollback (rollback) The operation of .

  • In the replica scenario that needs to be monitored .

  • The transaction management of database connection is the memo mode .

structure

Originator Initiator role : Record the internal state of the current moment , Responsible for defining which States belong to the backup scope , Responsible for creating and restoring memo data .

Memento Memo role : Responsible for the storage Originator The internal state of the originator object , Provide the internal state the sponsor needs when needed .

Caretaker Memo administrator role : Manage memos 、 Keep and provide memos .

Code example

public class BeanUtils {
    // hold  bean  Put all the attributes and values of into  Hashmap  in
    public static HashMap<String,Object> backupProp(Object bean){
        HashMap<String,Object> result = new
                HashMap<String,Object>();
        try {
            // get  Bean  describe
            BeanInfo
                    beanInfo=Introspector.getBeanInfo(bean.getClass());
            // Get the property description
            PropertyDescriptor[]
                    descriptors=beanInfo.getPropertyDescriptors();
            // Traverse all properties
            for(PropertyDescriptor des:descriptors){
                // The attribute name
                String fieldName = des.getName();
                // Methods to read properties
                Method getter = des.getReadMethod();
                // Read property values
                Object fieldValue=getter.invoke(bean,new
                        Object[]{});
                if(!fieldName.equalsIgnoreCase("class")){
                    result.put(fieldName, fieldValue);
                } } } catch (Exception e) {
                // exception handling
        }
        return result;
    }
    // hold  HashMap  The value of is returned to  bean  in
    public static void restoreProp(Object bean,HashMap<String,Object>
            propMap){
        try {
            // get  Bean  describe
            BeanInfo beanInfo =
                    Introspector.getBeanInfo(bean.getClass());
            // Get the property description
            PropertyDescriptor[] descriptors =
                    beanInfo.getPropertyDescriptors();
            // Traverse all properties
            for(PropertyDescriptor des:descriptors){
                // The attribute name
                String fieldName = des.getName();
                // If you have this property
                if(propMap.containsKey(fieldName)){
                    // The way to write properties
                    Method setter = des.getWriteMethod();
                    setter.invoke(bean, new
                            Object[]{propMap.get(fieldName)});
                } } } catch (Exception e) {
            // exception handling
            System.out.println("shit");
            e.printStackTrace();
        }
    }
}

Visitor mode

Concept

Package some Operations that act on the elements of a data structure , It can define new operations on these elements without changing the data structure .

Use scenarios

  • An object structure contains many class objects , They have different interfaces , And you want to do something with these objects that depends on their specific classes , In other words, it's a situation that can't be competent with iterator mode .

  • Many different and unrelated operations need to be performed on the objects in an object structure , And you want to avoid having these operations “ Pollution ” Classes for these objects .

structure

Visitor—— Abstract Visitor : Abstract class or interface , Declare which elements visitors can access , To be specific to the procedure is visit The parameters of the method define which objects can be accessed .

ConcreteVisitor—— Specific visitors : It affects what visitors do when they visit a class , What are you going to do .

Element—— Abstract elements : Interface or abstract class , State what kind of visitors are allowed to visit , The procedure is through accept Method .

ConcreteElement—— Specific elements : Realization accept Method , Usually visitor.visit(this), Basically, a pattern has been formed .

ObjectStruture—— The structure of the object : The element producer , Generally, it can be accommodated in many different types 、 Containers with different interfaces , Such as List、Set、Map etc. , In the project , This character is rarely abstracted .

Code example

public class CompensationVisitor implements Visitor {
    @Override
    public void Visit(Element element) {
        // TODO Auto-generated method stub
        Employee employee = ((Employee) element);
        System.out.println(
                employee.getName() + "'s Compensation is " + (employee.getDegree() * employee.getVacationDays() * 10));
    }
}

The state pattern

Concept

Be an object When the inner state changes, allow it to change behavior , This object looks like it changed its class .

Use scenarios

  • A scene in which behavior changes as states change , This is also the starting point of the model , For example, permission design , The state of people is different, even if they perform the same behavior, the results will be different , In this case, you need to consider using state patterns .

  • Conditions 、 A substitute for a branch judgment statement

structure

State—— Abstract state role : Interface or abstract class , Responsible for object state definition , And encapsulate the role of the environment to achieve state switching .

ConcreteState—— Specific status role : Each specific state must fulfill two responsibilities : Behavior management of this state and trend state processing , In layman's terms , It's what we have to do in this state , And how this state transitions to other states .

Context—— Environmental roles : Define the interface required by the client , And responsible for the specific state switching .

Code example

// Abstract state role
public abstract class State {
     // Define an environmental role , Provide subclass access to
     protected Context context;
     // Setting up environment roles
     public void setContext(Context _context){
             this.context = _context;
     }
     // Behavior 1
     public abstract void handle1();
     // Behavior 2
     public abstract void handle2();
}

Interpreter mode

Concept

Give a language , A representation of the grammar that defines it , And define an interpreter , The interpreter Use this representation to explain sentences in a language .

Use scenarios

  • Recurring problems can use interpreter mode

  • A simple grammar needs to explain the scene

structure

AbstractExpression—— abstract interpreter : The specific interpretation task is completed by each implementation class , The specific interpreter is composed of TerminalExpression and Non-terminalExpression complete .

TerminalExpression—— Terminator expression : Implement the interpretation operations associated with elements in grammar , Usually there is only one terminator expression in an Interpreter pattern , But there are multiple instances , Corresponding to different terminators .

NonterminalExpression—— Nonterminal expression : Each rule in grammar corresponds to a non terminal expression , Nonterminal expressions increase based on the complexity of the logic , In principle, each grammar rule corresponds to a nonterminal expression .

Context—— Environmental roles : In general, it is used to store the specific value corresponding to each terminator in grammar , This information needs to be stored in environmental roles , In many cases, we use Map It's enough to play an environmental role .

Code example

/**
 *  Terminator expression
 */
public class TerminalExpression extends AbstractExpression {
    @Override
    public void interpret(Context ctx) {
        //  Implements the interpretation operation associated with the terminator in the grammar rule
    }
}
/**
 *  Nonterminal expression
 */
public class NonterminalExpression extends AbstractExpression {
    @Override
    public void interpret(Context ctx) {
        //  Implement the interpretation operation associated with the non terminal character in the grammar rule
    }
}

The flyweight pattern

Concept

Using shared objects can effectively Supports a large number of fine-grained objects .

Object information is divided into two parts : Internal state (intrinsic) And the external state (extrinsic).

Internal state : Internal state is the information that an object can share , It is stored inside the enjoy object and does not change with the environment .

External state : An external state is a token that an object can depend on , It changes with the environment 、 Unshareable state .

Use scenarios

  • There are a large number of similar objects in the system .

  • Fine-grained objects have a similar external state , And the internal state is independent of the environment , That is, the object has no specific identity .

  • Scenarios where a buffer pool is required .

structure

Flyweight—— Abstract meta roles : It is simply an abstract class of a product , An interface or implementation that defines both the external and internal state of an object .

ConcreteFlyweight—— Specific enjoy yuan role : A specific product class , Implement the business of abstract role definition . It's important to note in this role that internal state processing should be environment independent , There shouldn't be an operation that changes the internal state , The external state was also modified , This is absolutely not allowed .

unsharedConcreteFlyweight—— Shareable role : There are no external states or security requirements ( Such as thread safety ) Objects that can't be shared , This object does not normally appear in the Heyuan factory .

FlyweightFactory—— The flyweight factory : The duties are very simple , That is to construct a pool container , It also provides methods to get objects from the pool .

Code example

public class FlyweightFactory {
    // Define a pool container
    private static HashMap<String,Flyweight> pool= new
            HashMap<String,Flyweight>();
    // The flyweight factory
    public static Flyweight getFlyweight(String Extrinsic){
        // The object that needs to be returned
        Flyweight flyweight = null;
        // There is no object in the pool
        if(pool.containsKey(Extrinsic)){
            flyweight = pool.get(Extrinsic);
        }else{
            // Create a share object based on the external state
            flyweight = new ConcreteFlyweight1(Extrinsic);
            // Put it in the pool
            pool.put(Extrinsic, flyweight);
        }
        return flyweight;
    }
}

Bridge mode

Concept

take Abstraction and implementation decoupling , So that the two can change independently .

Use scenarios

  • Scenarios where inheritance is not expected or applicable

  • Unstable interface or class abstraction

  • Scenarios that require high reusability

structure

Abstraction—— Abstract character : Its main responsibility is to define the behavior of the character , Also save a reference to the implemented role , The role is generally an abstract class .

Implementor—— Realize the role : It's an interface or an abstract class , Define the necessary behaviors and attributes of a character .

RefinedAbstraction—— Fixed abstract character : It refers to the implementation role to modify the abstract role .

ConcreteImplementor—— Concrete realization role : It implements methods and properties defined by interfaces or abstract classes .

Code example

public abstract class Abstraction {
    // Define a reference to an implemented role
    private Implementor imp;
    // The constraint subclass must implement the constructor
    public Abstraction(Implementor _imp){
        this.imp = _imp;
    }
    // Their own behavior and attributes
    public void request(){
        this.imp.doSomething();
    }
    // Get realized roles
    public Implementor getImp(){
        return imp;
    }
}

summary

When you're learning design patterns , Don't make it hard , in the final analysis , It's a summary of some generalities . We need to study and work constantly at ordinary times , Take time to understand its underlying principles , In this way, each design pattern can be applied flexibly .

The design pattern is based on the summary of predecessors , A solution to the problems in some scenarios , Design patterns are not formulas , There's no need to memorize every pattern , It's more important to understand it Abstract ideas , And how application design patterns Better problem solving , What can be achieved . There are many theories , But if we want to master it , For our actual development, it will solve many problems .

Of course, we will continue to update about Design principles The content of , It is convenient for you to further understand the design pattern .