[hard core] 23 design patterns to help you write beautiful code gracefully!

Shallow feather technique 2021-04-08 12:29:16
hard core design patterns help


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 .

版权声明
本文为[Shallow feather technique]所创,转载请带上原文链接,感谢
https://javamana.com/2021/04/20210408114459338v.html

  1. [TTS] AIX - & gt; Linux -- Based on RMAN (real environment)
  2. 为什么学编程大部分人选Java编程语言?
  3. Redis 高可用篇:你管这叫 Sentinel 哨兵集群原理
  4. redis 为什么把简单的字符串设计成 SDS?
  5. [TTS] transfer table space AIX - & gt; Linux based on RMAN
  6. Linux 网卡数据收发过程分析
  7. Redis 高可用篇:你管这叫 Sentinel 哨兵集群原
  8. Redis 6.X Cluster 集群搭建
  9. [TTS] transfer table space AIX ASM - & gt; Linux ASM
  10. [TTS] transfer table space Linux ASM - & gt; AIX ASM
  11. 高性能通讯框架——Netty
  12. Brief introduction and test of orchestrator, a high availability management tool for MySQL
  13. [TTS] transfer table space Linux - & gt; AIX based on RMAN
  14. A love diary about http
  15. [rocketmq source code analysis] in depth message storage (3)
  16. Implementation of service configuration center with spring cloud + Nacos (Hoxton version)
  17. SiCp: abstraction of construction process -- object oriented explanation
  18. springboot网上点餐系统
  19. 【SPM】oracle如何固定执行计划
  20. 用好HugePage,告别Linux性能故障
  21. 3 W word long text, java basic interview questions! It's amazing!!!
  22. Spring cloud upgrade road - 2020.0. X - 3. Accesslog configuration of undertow
  23. Win10 uninstall mysql5.7
  24. CentOS下dotnet Core使用HttpWebRequest进行HTTP通讯,系统存在大量CLOSE_WAIT连接问题的分析,已解决。
  25. MySQL batch insert, how not to insert duplicate data?
  26. K8s cronjob application example
  27. Unconventional method, easy to deal with Oracle database critical exception
  28. How to use sqlplus - prelim in Oracle hang
  29. How to search Oracle official documents in full text
  30. Install mysql8.0 on win10
  31. Oracle OCR的备份与恢复
  32. Oracle kill session相关问题
  33. 《Oracle DBA工作笔记》第二章 常用工具和问题分析
  34. Oracle回收站及flashback drop
  35. Hand in hand to teach you to write a spring IOC container
  36. Exception in Java (1) - basic concept
  37. 3w 字长文爆肝 Java 基础面试题!太顶了!!!
  38. Error 2059 when Navicat connects to win10 mysql8.0
  39. Parameter reminder causing Oracle Performance jitter
  40. 「技术分享」Java线程状态间的互相转换看这个就行了
  41. 国产控件短平快,在Java中以编程形式将 XML 转为 Excel
  42. Oracle RAC high availability failure of risk alert
  43. Process scheduling bugs in running oracle on small computers
  44. Oracle memory over consumption risk alert
  45. 【硬核】23种设计模式娓娓道来,助你优雅的编写出漂亮代码!
  46. springboot整合spring security最完整,只看这一篇就够了
  47. Oracle SQL monitor
  48. Using Bifrost to realize data synchronization of MySQL
  49. Reveal the principle of Oracle database truncate
  50. Read this article, Oracle SQL optimization article does not need to read!
  51. IntelliJ IDEA 2021.1 破解,IDEA 2021.1激活破解,激活持续更新
  52. Kafka performance: why so fast?
  53. Two high frequency design interview questions: how to design HashMap and thread pool
  54. Why most people choose Java programming language to learn programming?
  55. Redis high availability: you call this sentinel cluster principle
  56. Why does redis design simple strings as SDS?
  57. Analysis of data sending and receiving process of Linux network card
  58. Redis high availability: what do you call sentinel cluster
  59. Redis 6. X cluster construction
  60. Netty: a high performance communication framework