The 23 gof design modes are generally divided into three categories: Creation Mode, structure mode, and behavior mode.
The Creation Mode abstracts the instantiation process, which helps a system to create, combine, and express its objects independently. A class creation mode uses inheritance to change the class to be instantiated, and an object Creation Mode trusts the Instantiation to another object. The creation mode has two main themes. First, they all encapsulate information about the detailed classes used by the system. Second, they hide how instances of these classes are created and put together. All objects in the system know interfaces defined by abstract classes. Therefore, the Creation Mode gives great flexibility in what is created, who creates it, how it is created, and when it is created. They agree to configure a system with a "product" object with a very different structure and function. The configuration can be static (specified during compilation) or dynamic (during execution ).
The structure mode involves how to combine classes and objects to obtain a larger structure. The structure class mode combines interfaces or implementations using the inheritance mechanism. The structured object mode not combines interfaces and implementations, but describes how to combine some objects to implement new functions. Because the object composite relationship can be changed during execution, the object composite method has more flexibility, and such a mechanism is impossible to achieve with static class composite.
The behavior pattern involves the assignment of duties between algorithms and objects. The behavior pattern not only describes the modes of describing objects or classes, but also describes the communication modes between them. These modes depict complex control flows that are difficult to trace during execution. They shift users' attention from the control flow to the contact information between objects. The behavior class mode uses the Inheritance Mechanism to distribute actions among classes. Behavior object mode uses Object combination instead of inheritance. Some behavior object modes describe how a group of peer objects collaborate to complete tasks where any of them cannot be completed separately.
Creation Mode includes: 1. factorymethod (Factory method mode); 2. Abstract Factory (Abstract Factory mode); 3. Singleton (Singleton mode); 4. Builder mode and builder mode ); 5. Prototype (prototype ).
Structural mode inclusion: 6. Bridge (Bridge Mode); 7. adapter (adapter mode); 8. decorator (decoration mode); 9. Composite (combination mode ); 10. flyweight (metadata mode); 11. facade (appearance mode); 12. Proxy mode ).
Behavior pattern includes: 13. templatemethod (template method mode); 14. Strategy (Policy mode); 15. State (State mode); 16. Observer (Observer mode ); 17. Memento (memorandum mode); 18. mediator (intermediary mode); 19. Command (command mode); 20. Visitor (Observer mode ); 21. chain of responsibility (responsible chain mode); 22. iterator (iterator mode); 23. Interpreter (Interpreter mode ).
Factory method: Defines an interface for creating objects, so that the subclass determines which class to instantiate. Factory method delays the instantiation of a class to its subclass.
Abstract Factory: Provides an interface for creating a series of related or mutually dependent objects without specifying their detailed classes.
Singleton: Ensure that a class has only one instance, and provide a global renewal question for a category.
Builder: Separates the construction of a complex object from its representation, so that different representations can be created for the same build process.
Prototype: Use a prototype instance to specify the type of the object to be created, and copy the prototype to create a new object.
Bridge: Separates abstract parts from their implementations so that they can all change independently.
Adapter: Converts an interface of a class to another interface that the customer wants. The adapter mode enables the classes that cannot work together due to the incompatibility of interfaces to work together.
Decorator: Dynamically add some additional responsibilities to an object. In terms of extended functions, the decorator mode is more flexible than the subclass generation method.
Composite: Combine objects into a tree structure to represent the "part-population" hierarchy. Composite makes the customer's use of a single object and composite object consistent.
Flyweight: Use the sharing technology to effectively support a large number of fine-grained objects.
Facade: Provides a consistent interface for a group of interfaces in the subsystem. The facade mode defines a high-level interface, which makes the subsystem easier to use.
Proxy: Provides a proxy for other objects to control the issue of this object.
Template Method: Defines the skeleton of an algorithm in an operation, and delays some steps to the subclass. The template method allows the subclass to redefine certain steps of an algorithm without changing the structure of an algorithm.
Strategy: Define a series of algorithms, encapsulate them one by one, and make them replaceable. This mode makes the algorithm changes independent of the customers who use it.
State: Agree to change the behavior of an object when its internal state changes. The object seems to have changed its class.
Observer: Defines a one-to-many dependency between objects, so that when the status of an object changes, all objects dependent on it are notified and automatically refreshed.
Memento: Capture the internal state of an object without compromising encapsulation, and save the state outside the object. In this way, the object can be restored to the Saved state.
Mediator: Encapsulate a series of object interactions with an intermediary object. The intermediary makes the objects do not need to explicitly reference each other, so that the coupling is loose and the interaction between them can be changed independently.
Command: Encapsulate a request as an object so that you can use different requests to digitize the customer, queue requests or record request logs, and support cancelable operations.
Visitor: Indicates an operation that acts on each element in an object structure. It enables you to define new operations that act on these elements without changing the classes of each element.
Chain of responsibility: To remove the coupling between the request sender and receiver, multiple objects have the opportunity to process the request. Connect these objects into a chain and pass the request along the chain until an object processes it.
Iterator: Provides a method to sequentially ask each element in an aggregate object without exposing the internal representation of the object.
Interpreter: For a given language, define a representation of its syntax and define an interpreter that uses this representation to interpret sentences in the language.
Interpreter: (1) Intention: Define a syntax expression of a language and define an interpreter. This interpreter uses this representation to explain sentences in a language.
(2) Applicability: When a language requires interpretation and execution, and you can represent sentences in the language as an abstract syntax tree, you can use the interpreter mode. In the following situations, this mode has the best effect: A. The grammar is simple for complex grammar, and the class level of grammar becomes huge and cannot be managed. At this time, the syntax analysis program generator is a better tool. They can interpret expressions without building an abstract syntax tree, which saves space and time. B. efficiency is not a key issue. The most efficient interpreter is usually not implemented by directly interpreting the syntax analysis tree. Instead, they are first converted into another form. For example, the regular form is usually converted into a state machine. However, even in this case, the converter can still be implemented in interpreter mode, which is still practical.
(3) Advantages and Disadvantages: A. Easy to change and extend grammar: Because this mode uses classes to represent grammar rules, you can use inheritance to change or expand the grammar. Existing expressions can be incrementally changed, while new expressions can be defined as Variants of old expressions. B. Easy syntax implementation: the implementation of classes on each node in the abstract syntax tree is similar. These classes are easy to write directly. They can also be automatically generated by a compiler or syntax analysis program generator. C. Complicated syntax is difficult to maintain: The Interpreter mode defines at least one class for each rule in the grammar (many other classes are required to use the grammar rules defined by BNF ). Therefore, the syntax containing many rules may be difficult to manage and maintain. Other design patterns can be applied to alleviate this problem. However, when syntax is very complex, other technologies such as syntax analysis programs or compiler generators are more suitable. D. Add a new interpreted expression: the interpreter mode makes it easy to implement the new expression "computation. For example, you can define a new operation in the expression class to support the type check of beautiful prints or expressions. If you often create new interpretation expressions, you can consider using the visitor mode to avoid modifying these classes that represent grammar.
(4) related mode: A. composite mode: the abstract syntax tree is an example of a composite mode. B. flyweight mode: describes how to share terminator in the abstract syntax tree. C. iterator: The interpreter can use an iterator to traverse the structure. D. Visitor: used to maintain the behavior of each node in the abstract syntax tree in a class.
(5) The purpose of interpreter mode is to use an interpreter to provide users with an interpreter that defines the syntax expression of a language, and then use this interpreter to explain sentences in a language. In interpreter mode, the terminalexpression and nonterminalexpression expressions are interpreted. The context class is used to provide additional information (such as Global Information) for the interpretation process)
Sample Code 1:
# Include <iostream> # include <string> # include <vector> using namespace STD; Class context; class implements actexpression {public: Virtual void interpret (Context * context) = 0 ;}; class expression: Public extends actexpression {public: Virtual void interpret (Context * context) {cout <"terminal interpreter" <Endl ;}}; class nonterminalexpression: Public extends actexpression {public: virtual void interpret (Context * context) {cout <"non-terminal interpreter" < <Endl ;}; class context {public: String input; string output ;}; // clientint main () {context * context = new context (); vector <abstractexpression *> express; Express. push_back (new expression (); Express. push_back (New nonterminalexpression (); Express. push_back (New nonterminalexpression (); vector <effecactexpression * >:: iterator P = Express. begin (); While (P! = Express. end () {(* P)-> interpret (context); P ++ ;} /* result terminal interpreter non-terminal interpreter */return 0 ;}
Sample Code 2:
Context. h:
#ifndef _CONTEXT_H_#define _CONTEXT_H_class Context{public:Context();~Context();protected:private:};#endif//~_CONTEXT_H_
Context. cpp:
#include "Context.h"Context::Context(){}Context::~Context(){}
Interpret. h:
#ifndef _INTERPRET_H_#define _INTERPRET_H_#include "Context.h"#include <string>using namespace std;class AbstractExpression{public:virtual ~AbstractExpression();virtual void Interpret(const Context& c);protected:AbstractExpression();private:};class TerminalExpression : public AbstractExpression{public:TerminalExpression(const string& statement);~TerminalExpression();void Interpret(const Context& c);protected:private:string _statement;};class NonterminalExpression : public AbstractExpression{public:NonterminalExpression(AbstractExpression* expression, int times);~NonterminalExpression();void Interpret(const Context& c);protected:private:AbstractExpression* _expression;int _times;};#endif//~_INTERPRET_H_
Interpret. cpp:
#include "Interpret.h"#include <iostream>using namespace std;AbstractExpression::AbstractExpression(){}AbstractExpression::~AbstractExpression(){}void AbstractExpression::Interpret(const Context& c){}TerminalExpression::TerminalExpression(const string& statement){this->_statement = statement;}TerminalExpression::~TerminalExpression(){}void TerminalExpression::Interpret(const Context& c){cout<<this->_statement<<"TerminalExpression"<<endl;}NonterminalExpression::NonterminalExpression(AbstractExpression* expression, int times){this->_expression = expression;this->_times = times;}NonterminalExpression::~NonterminalExpression(){}void NonterminalExpression::Interpret(const Context& c){for (int i = 0; i < _times; i ++)this->_expression->Interpret(c);}
Main. cpp:
#include "Context.h"#include "Interpret.h"#include <iostream>using namespace std;int main(){Context* c = new Context();AbstractExpression* te = new TerminalExpression("hello");AbstractExpression* nte = new NonterminalExpression(te, 2);nte->Interpret(*c);/*resulthelloTerminalExpressionhelloTerminalExpression*/return 0;}
Interpreter mode structure:
Exam documents:
1. Big talk Design Model C ++
2. Design Patterns-Analysis of gof23 Design Patterns
3. Design Patterns-Basics of reusable Object-Oriented Software
Excerpt from the interpreter mode of the Design Pattern