Github source address

Observer model

Introduction to the

  • Solution: Define a one-to-many dependency between objects so that when an object’s state changes, all dependent objects are notified and automatically updated.
  • Use: When an object (target object) changes state, all dependent objects (observer object) are notified, broadcasting notification.
  • Approach: Use object-oriented technology to weaken this dependency.
  • Scene: auction, the auctioneer observes the highest bid, and then notifies other bidders to bid.

The advantages and disadvantages

  • Advantages:
    1. The observer and the observed are abstractly coupled.
    2. Establish a trigger mechanism.
  • Disadvantages:
    1. If an observed object has many direct and indirect observers, it can take a long time to notify all of them.
    2. If there is a cyclic dependency between the observer and the observing target, the observing target will trigger a cyclic call between them, possibly causing the system to crash.
    3. The observer mode has no corresponding mechanism to let the observer know how the observed object has changed, but only that the observed object has changed.

For example,

  • Obtaining data according to changes in data2,8,16Into the system.
class Observer { constructor() { this.subject = null; } update() {}} // 2 base class extends Observer {constructor(subject) {super(); this.subject = subject; this.subject.attach(this) } update() { console.log("Binary String: " + this.subject.getState().toString(2)); }} // class constructor extends Observer {constructor(subject) {super(); this.subject = subject; this.subject.attach(this) } update() { console.log("Octal String: " + this.subject.getState().toString(8)); }} // hexadecimal class extends Observer {constructor(subject) {super(); this.subject = subject; this.subject.attach(this) } update() { console.log("Hexa String: " + this.subject.getState().toString(16)); } } class Subject { constructor(state) { this.state = state; this.list = []; } getState() { return this.state; } setState(state) { this.state = state; this.notifyAllObserver(); } attach(observer) {this.list.push(observer); } // Update all notifyAllObserver() {for (let observer of this.list) {observer.update(); } } } function demo() { const subject = new Subject(); new HexaObserver(subject); new OctalObserver(subject); new BinaryObserver(subject); console.log("First state change: 15"); subject.setState(15); console.log("Second state change: 10"); subject.setState(10); } demo()Copy the code

The state pattern

Introduction to the

  • Solution: : The behavior of an object depends on its state (properties) and can change its related behavior as its state changes.
  • Usage: The code contains a large number of conditional statements related to object state.
  • Method: Abstract out various concrete state classes.
  • Scenario: Status of a service (, not started, Running, stopped).

The advantages and disadvantages

  • Advantages:
    1. Encapsulates the transformation rules.
    2. Enumerates possible states. The type of state needs to be determined before enumerating states.
    3. Put all the behavior associated with a state into a single class, and you can easily add new states by simply changing the object’s state to change its behavior.
    4. Allows state transition logic to be integrated with state objects, rather than some giant block of conditional statements.
    5. You can reduce the number of objects in the system by having multiple environment objects share a state object.
  • Disadvantages:
    1. The use of state patterns inevitably increases the number of system classes and objects.
    2. The structure and implementation of state pattern are complicated, and it will lead to confusion of program structure and code if used improperly.
    3. State mode does not support the “open closed principle” very well.

For example,

  • Start or stop status of the service.
class State {
    doAction(context) { }
}

class StartState extends State {
    doAction(context) {
        console.log('Player is in start state.');
        context.setState(this);
    }
    toString() {
        return "Start State";
    }
}

class StopState extends State {
    doAction(context) {
        console.log('Player is in stop state.');
        context.setState(this);
    }
    toString() {
        return "Stop State";
    }
}
class Context {
    constructor() {
        this.state = null;
    }
    getState() {
        return this.state;
    }
    setState(state) {
        this.state = state;
    }
}

function demo() {
    const context = new Context();

    console.log('context state:', context.getState());
    const startState = new StartState();
    startState.doAction(context);
    console.log('context state:', context.getState().toString());
    const stopState = new StopState(context);
    stopState.doAction(context);
    console.log('context state:', context.getState().toString());
}

demo()

Copy the code

The strategy pattern

Introduction to the

  • Solution: Use when there are multiple similar algorithmsif... elseThe resulting complexity and difficult to maintain.
  • Usage: A system has many, many classes that are distinguished only by their immediate behavior.
  • Method: Encapsulate these algorithms into classes and replace them arbitrarily.
  • Scenario: form verification, travel transportation choice.

The advantages and disadvantages

  • Advantages:
    1. Algorithms can be switched freely.
    2. Avoid using multiple conditional judgments.
    3. Good scalability.
  • Disadvantages:
    1. Policy classes will increase.
    2. All policy classes need to be exposed.

For example,

  • Call addition/subtraction.
class Strategy {
    doOperation(num1, num2) { }
}

class OperationAdd extends Strategy {
    constructor() {
        super();
    }
    doOperation(num1, num2) {
        return num1 + num2;
    }
}
class OperationSubtract extends Strategy {
    constructor() {
        super();
    }
    doOperation(num1, num2) {
        return num1 - num2;
    }
}

class Context {
    constructor(strategy) {
        this.strategy = strategy;
    }
    execStrategy(num1, num2) {
        return this.strategy.doOperation(num1, num2)
    }
}

function demo() {
    let context = new Context(new OperationAdd());
    console.log('10 + 7 = ', context.execStrategy(10, 7));
    context = new Context(new OperationSubtract());
    console.log('10 - 7 = ', context.execStrategy(10, 7));
}

demo()
Copy the code

Template pattern

Introduction to the

  • Solution: Some methods are generic, but the method is rewritten in each subclass.
  • Use: There are some general methods.
  • How: Abstract out these general algorithms.
  • Scenario: Common handling of success and failure in request processing; Several games with similarities.

The advantages and disadvantages

  • Advantages:
    1. Encapsulate invariant parts and extend variable parts.
    2. Extract common code for easy maintenance.
    3. The behavior is controlled by the parent class and implemented by the child class.
  • Disadvantages: Each different implementation requires a subclass to implement, resulting in an increase in the number of classes, making the system larger.

For example,

  • Implement an iterative print of a name.
class Game { initialize() { }; startPlay() { }; endPlay() { }; // play() {this.initialize(); // Start the game this.startPlay(); // End the game this.endplay (); } } class Cricket extends Game { constructor() { super(); } endPlay() { console.log("Cricket Game Finished!" ); } initialize() { console.log("Cricket Game Initialized! Start playing."); } startPlay() { console.log("Cricket Game Started. Enjoy the game!" ); } } class Football extends Game { constructor() { super(); } endPlay() { console.log("Football Game Finished!" ); } initialize() { console.log("Football Game Initialized! Start playing."); } startPlay() { console.log("Football Game Started. Enjoy the game!" ); } } function demo() { const cricket = new Cricket(); cricket.play(); const football = new Football(); football.play(); } demo()Copy the code

Visitor pattern

Introduction to the

  • Solution: Stable data structures and volatile operational coupling problems.
  • Use: You need to do many different and unrelated operations on objects in an object structure, and you need to avoid “contaminating” those objects’ classes by encapsulating them in the visitor pattern.
  • Method: add an interface for receiving visitors to the class being visited.
  • Scenario: You visit a friend, and you make a decision based on what the friend says.

The advantages and disadvantages

  • Advantages:
    1. Consistent with the principle of single responsibility.
    2. Excellent scalability.
    3. Flexibility.
  • Disadvantages:
    1. Specific elements disclose details to visitors, violating the Demeter principle.
    2. Specific element changes are difficult.
    3. Violates the dependency inversion principle by relying on concrete classes instead of abstractions.

For example,

  • Computer, keyboard, mouse access operations.
class computerPart { accept(computerPartVisitor) { } } class KeyBoard extends computerPart { accept(computerPartVisitor)  { computerPartVisitor.visitKeyBoard(this); } } class Mouse extends computerPart { accept(computerPartVisitor) { computerPartVisitor.visitMouse(this); } } class Computer extends computerPart { constructor() { super(); this.parts = [new KeyBoard(), new Mouse()]; } accept(computerPartVisitor) { for (let item of this.parts) { item.accept(computerPartVisitor); } computerPartVisitor.visitComputer(this); } } class ComputerPartVisitor { visitComputer(computer) { }; visitMouse(mouse) { }; visitKeyBoard(keyboard) { }; } class ComputerPartDisplayVisitor extends ComputerPartVisitor { visitComputer(computer) { console.log("Displaying Computer."); } visitMouse(mouse) { console.log("Displaying Mouse."); } visitKeyBoard(keyboard) { console.log("Displaying Keyboard."); } } function demo() { const computer = new Computer(); computer.accept(new ComputerPartDisplayVisitor()); } demo()Copy the code

conclusion

  • Behavioral pattern describes the complex flow control of programs at runtime, that is, how multiple classes or objects cooperate to accomplish tasks that a single object cannot accomplish alone. It involves the assignment of responsibilities between algorithms and objects.
  • The behavior pattern is divided into class behavior pattern and object behavior pattern. The former uses inheritance mechanism to allocate behavior between classes, and the latter uses composition or aggregation to allocate behavior between objects. The object behavior pattern has more flexibility than the class behavior pattern because the combinatorial or aggregative relationship is less coupled than the inheritance relationship and meets the “composite reuse principle”.

More quality articles

  • Behavior Patterns in JavaScript Design Patterns (Part 1)
  • Structural patterns for JavaScript design patterns
  • An introduction to JavaScript design patterns and creative patterns
  • Public account open small program best solution (Vue)
  • Axios you probably don’t know how to use

“Likes, favorites and comments”

❤️ follow + like + favorites + comments + forward ❤️, original is not easy, encourage the author to create a better article, thank 🙏 everyone.