preface
Programming has a long history, a good programming idea can let us write better logic code. Object-oriented programs should be maintainable, code reusable, extensible, and flexible. In order to achieve the above functions, the leaders have concluded a set of internal work techniques available, that is, design patterns. Design pattern is a set of repeatedly used, most people know, cataloged code Design experience summary. Using design patterns not only facilitates writing more complex business logic, but also increases readability and maintainability of business code.
Long early warning, like in advance, collect 🌹
Design principles
Design principles are the rules that design patterns follow, and design patterns implement these principles to achieve the purpose of code reuse and increase maintainability.
Single responsibility (Single Responsibility Principle - SRP
)
A class is responsible for only one function area, or can be defined as: in the case of a class, there should be only one cause for its change.
A function that does only one thing takes on too much responsibility and means multiple functions are coupled. Multiple functions work together to form complex logic
Open and closed (Open Closed Principle - OCP
)
Open to the outside world, closed to the inside
Being open to extension means that existing code can be extended to accommodate new requirements or changes. Being closed to changes means that once the class is designed, it can do its work independently without making any changes to the class.
Richter substitution (Liskov Substitution Principle - LSP
)
A subclass can extend the functionality of the parent class, but cannot change the functionality of the parent class
- A subclass can implement an abstract method of the parent class, but cannot override a nonabstract method of the parent class.
- Subclasses can add their own special methods.
- When a subclass’s method overrides a parent class’s method, the method’s preconditions (that is, the method’s parameters) are looser than the parent method’s input parameters.
- When a subclass’s method implements an abstract method of the parent class, the method’s postcondition (that is, the method’s return value) is stricter than the parent class’s.
Interface isolation (Interface Segregation Principle - ISP
)
Create a single interface, do not create a large and bloated interface, try to refine the interface, interface methods as few as possible
Use multiple specialized interfaces instead of a single master interface, that is, clients should not rely on interfaces that they do not need. According to the principle of interface isolation, when an interface is too large, we need to split it into smaller interfaces. Clients using the interface need only know the methods associated with it, and interface isolation is all about not forcing client programs to rely on methods they don’t need to use
Dependency inversion (Dependence Inversion Principle - DIP
)
The core idea of dependency inversion principle is to program for interface, not for implementation class.
That is, instead of using concrete classes, use interfaces and abstract classes for variable type declarations, parameter type declarations, method return type declarations, and data type conversions
The principles of design are called SOLID principles for easy memorization. There are also some design principles that are not commonly used. For example: composite/aggregate reuse principle, acyclic dependency principle, common reuse principle
Classification of design patterns
Generally speaking, design patterns fall into three categories
Creation type (5 types)
- Singleton pattern (
Singleton Pattern
) - Factory Method Pattern (
Factory Method Pattern
) - Abstract Factory Pattern (
Abstract Factory Pattern
) - Builder model (
Builder Pattern
) - Prototype pattern (
Prototype Pattern
)
Structural type (7 kinds)
- Adapter mode (
Adapter Pattern
) - Decorator mode (
Decorator Pattern
) - Proxy mode (
Proxy Pattern
) - Appearance mode (
Facade Pattern
) - Bridge mode (
Bridge Pattern
) - Combined mode (
Composite Pattern
) - Premium Mode (
Flyweight Pattern
)
Behavioral type (11 types)
- Strategic Mode (
Strategy Pattern
) - Template method pattern (
Template Method Pattern
) - Observer mode (
Observer Pattern
) - Iterator pattern (
Iterator Pattern
) - Chain of Responsibility Model (
Chain of Responsibility Pattern
) - Command mode (
Command Pattern
) - Memo Mode (
Memento Pattern
) - State mode (
State Pattern
) - Visitor Pattern (
Visitor Pattern
) - The Intermediary Model (
Mediator Pattern
) - Interpreter mode (
Interpreter Pattern
)
Tip:
The illustration
There are actually two more types: syndication mode and thread pool mode. Use a picture to describe the whole picture:
Design pattern specification
Singleton pattern (Singleton Pattern
)
The singleton pattern can ensure that there is only one instance of each class in the system. That is, a class has only one object instance. A singleton class can only allow one instance
The UML class diagram (😯) is used to create the UML class diagram (😯)
-
Usage scenarios
In my previous project, I used the Element-UI Message component. By default, messages can be displayed multiple times, but if the customer is impatient and orders several times, the screen will be full of messages. In this case, we only need one Message to notify
As you all know, database connection pool objects are also designed to be singletons when writing back ends
-
The advantages and disadvantages
Advantages:
1. Only one object is stored in memory, saving memory space.
2. Avoid frequent object creation and destruction to improve performance;
Disadvantages:
1. Not applicable to objects that change frequently;
-
Implementation of singleton pattern
The hungry type LanHanShi
Javascript is single-threaded, so there is no multi-threaded locking concept
The js closure implements the singleton pattern
-
Implementing a single MessageThe current approach above is intended to demonstrate the singleton pattern and is not the best approach
Factory Method Pattern (Factory Method Pattern
)
The factory method pattern, also known as the factory pattern, defines the common interface for creating objects by defining the factory parent class, while the child class is responsible for generating concrete objects.
As you can see from the figure above, the factory method pattern requires four roles
- Abstract factory (
Abstract Factory
) : provides an interface for creating products through which callers access the factory-specific factory method newProduct() to create products. - Specific factory (
ConcreteFactory
) : Mainly to implement abstract methods in abstract factories and complete the creation of concrete products. - Abstract product (
Product
) : Defines the specification of the product, describing the main features and functions of the product. - Specific products (
ConcreteProduct
) : Implements interfaces defined by abstract product roles, created by concrete factories, which correspond to concrete factories.
Usage scenarios
Builder model (Builder Pattern
)
The Builder pattern, also known as the creator pattern, separates the construction of a complex object from its representation so that the same construction process can create different representations. Creator mode hides the creation process of complex objects. It abstracts the creation process of complex objects and dynamically creates objects with compound attributes through subclass inheritance or overloading.
As you can see above, there are four characters in Builder mode
Product
: The final object to be generated.Builder
: The builder’s abstract base class (sometimes replaced with an interface). It defines the abstract steps for building a Product that its entity classes need to implement. It will contain a method to return the final productProduct getProduct()
.ConcreteBuilder
:Builder
Implementation class of.Director
: The algorithm that determines how to build the final product. It will contain a method responsible for assemblyConstruct(Builder builder)
, in this method by callingbuilder
“Can be setbuilder
, and then you can go throughbuilder
thegetProduct()
Method to obtain the final instance.
Usage scenarios
abstract class PhoneBuilder {
public abstract setBrand(): void;
public abstract setSystem(): void;
public abstract getPhone(): Phone;
}
class Phone {
private brand: string = ' ';
private cpu: string = ' ';
private screen: number = 0;
private system: string = ' ';
constructor(cpu: string, screen: number) {
this.cpu = cpu;
this.screen = screen;
}
setBrand(brand: string) {
this.brand = brand;
}
setCPU(cpu: string) {
this.cpu = cpu;
}
setScreen(screen: number) {
this.screen = screen;
}
setSystem(system: string) {
this.system = system; }}class HuaWei extends PhoneBuilder {
private phone: Phone;
constructor(cpu: string, screen: number) {
super(a);this.phone = new Phone(cpu, screen);
}
public setBrand() {
this.phone.setBrand('huawei');
}
public setSystem() {
this.phone.setSystem('hongmeng');
}
public getPhone() {
return this.phone; }}class PhoneDirector {
makeComputer(builder: PhoneBuilder){ builder.setBrand(); builder.setSystem(); }}var director = new PhoneDirector()
var builder = new HuaWei('eight nuclear'.5.8)
director.makeComputer(builder)
var huawei = builder.getPhone()
// Phone {brand: 'huawei', CPU: '8 ', screen: 5.8, system: 'hongmeng'}
Copy the code
Prototype pattern (Prototype Pattern
)
Used to create duplicate objects while maintaining performance. Provides an optimal way to create objects.
Adapter mode (Adapter Pattern
)
Translate the interface of a class into another interface that the customer wants. The Adapter pattern enables classes to work together that would otherwise not work together due to interface incompatibilities.
Usage scenarios
Decorator mode (Decorator Pattern
)
Decorator pattern also known as Wrapper pattern. The decorator pattern dynamically attaches responsibility to objects. To extend functionality, decorators offer a more flexible alternative to inheritance.
Usage scenarios
interface HuaWei {
getMemory(): string
getPrice(): number
}
class HuaWeiPro30 implements HuaWei {
getMemory(){
return '16G'
}
getPrice(){
return 6888}}class HuaWeiPro40 implements HuaWei {
getMemory(){
return '16G'
}
getPrice(){
return 8888
}
}
abstract class ScreenHuaWei implements HuaWei {
abstract huawei: HuaWei;
abstract getScreen(): number;
getPhone(){
return this.huawei
}
setPhone(phone: HuaWei){
this.huawei = phone
}
getMemory(){
return this.huawei.getMemory()
}
getPrice(){
return this.huawei.getPrice()
}
}
class AddScreen extends ScreenHuaWei {
huawei: HuaWei;
constructor(phone:HuaWei){
super(a)this.huawei = phone
}
getScreen(){
return 5.5}}var phoneWithoutScreen = new HuaWeiPro40()
var phoneScreen5 = new AddScreen(phoneWithoutScreen)
console.log(phoneScreen5.getScreen()) / / 5.5
Copy the code
Proxy mode (Proxy Pattern
)
You can provide a proxy for other objects to control access to that object. The so-called proxy refers to a class with the same interface as the proided object. The client must interact with the proided target class through the proxy, and the proxy generally performs some specific processing in the process of interaction (before and after the interaction).
Usage scenarios
Strategic Mode (Strategy Pattern
)
The policy pattern defines a series of algorithms, encapsulates each algorithm and makes them interchangeable, allowing the algorithm to change independently of the customers using it.
Tip:
- Context: The Context in which the policy is manipulated
- Stragety: The abstraction of strategy
- ConcreteStragetyA, ConcreteStragetyB concrete strategy implementation.
Usage scenarios
Observer mode (Observer Pattern
)
Sometimes referred to as the publish/subscribe pattern, the observer pattern defines a one-to-many dependency that allows multiple observer objects to listen on a subject object simultaneously. The topic object notifies all observer objects when their state changes, enabling them to update themselves automatically.
Usage scenarios
class Subject {
private state: number;
private observers: Array<Observer>;
constructor() {
this.state = 0;
this.observers = [];
}
getState() {
return this.state;
}
setState(state: number) {
this.state = state;
this.notifyAllObservers();
}
notifyAllObservers() {
this.observers.forEach((observer) = > {
observer.update();
});
}
attach(observer: Observer) {
this.observers.push(observer); }}// Observer class
class Observer {
name: string;
subject: Subject;
constructor(name: string, subject: Subject) {
this.name = name;
this.subject = subject;
this.subject.attach(this); // Add the observer to the observer list in the theme
}
update() {
console.log(`The ${this.name} update, state: The ${this.subject.getState()}`); }}let sub = new Subject();
let obs1 = new Observer('obs1', sub);
let obs2 = new Observer('obs2', sub);
let obs3 = new Observer('obs3', sub);
sub.setState(1);
sub.setState(2);
sub.setState(3);
Copy the code
State mode (State Pattern
)
The State mode allows an object to change its behavior when its internal State changes, as if the object has changed its class. The state pattern mainly addresses the situation when controlling the conditional representation of an object’s state transition is too complex. Complex decision logic can be simplified by moving the decision logic of states into a series of classes that represent different states.
Usage scenarios
abstract class State {
protected context: Context | undefined;
setContext(context: Context): void {
this.context = context;
}
public abstract handle1(): void;
}
class ConcreteState1 extends State {
handle1(): void {
/ /...
console.log('Handle1 method for ConcreteState1'); }}class Context {
static STATE1: State = new ConcreteState1();
currentState: State | undefined;
getCurrentState(): State | undefined {
return this.currentState;
}
setCurrentState(currentState: State) {
this.currentState = currentState;
this.currentState.setContext(this);
}
handle1(): void {
this.currentState && this.currentState.handle1(); }}let context = new Context();
context.setCurrentState(new ConcreteState1());
context.handle1();
Copy the code
conclusion
The above introduces several commonly used design patterns. In javascript, design patterns are not used much, but it needs a lot of skill to write them out. It needs to help friends ~
If it helps you, please don’t be stingy with your likes 👍
The article recommended
- ✍ source code analysis | see the essence through the appearance, Vue3 come and see what’s inside
- ✍ Use these skills to help improve development efficiency
- ✍ interviewer now ask call, apply, bind. Come on, I’ll write one for you!
- ✍ small white to understand | 15 minutes vue/cli complete server based rendering