Github source address

Adapter mode

Introduction to the

  • Solution: Put some “existing objects” into a new environment that requires interfaces that existing objects cannot meet
  • Use: The system needs to use existing classes, and this class interface does not meet the needs of the system; To insert a class into another class family by interface transformation.
  • How: The adapter inherits or relies on existing objects to implement the desired target interface.
  • Scenario: Motivated to modify the interface of a functioning system.

The advantages and disadvantages

  • Advantages:
    1. You can have any two unrelated classes run together.
    2. Improved class reuse.
    3. Increased class transparency.
    4. Good flexibility.
  • Disadvantages:
    1. Too much use of adapters can make the system very cluttered and difficult to grasp as a whole.

For example,

  • Do you wantaudio(Audio player) Simultaneous playback of audio format (mp3) and video format (mp4).
class MediaPlayer { play() { console.log('play mp4'); Class MediaAdapter {play() {new MediaPlayer().play(); } } class AudioPlayer { play(type) { if (type === 'mp3') { console.log('play mp3'); } else if (type === 'mp4') { new MediaAdapter().play(); } else { console.log("Invalid media. " + type + " format not supported"); } } } function demo() { const audio = new AudioPlayer(); audio.play('mp3'); audio.play('mp4'); audio.play('avi'); } demo();Copy the code

The bridge model

Introduction to the

  • Solution: When there are multiple possible changes, using inheritance causes class explosion problems and is not flexible to extend.
  • Usage: The implementation system may have multiple Angle classifications, each of which may vary.
  • Approach: Separate these multi-angle categories and allow them to vary independently, reducing coupling between them.
  • Scene: More flexibility between abstract and concrete characters You can mix whatever you want.

The advantages and disadvantages

  • Advantages:
    1. Separation of abstraction and implementation.
    2. Excellent ability to expand.
    3. Implementation details are transparent to the customer.
  • Disadvantages: The introduction of bridge mode will increase the difficulty of understanding and designing the system. Since the aggregation association relationship is established at the abstraction layer, developers are required to design and program for abstraction.

For example,

  • We want to draw a circle of different colors and sizes.
class DrawAPI { drawCircle(radius, x, y) { console.log('drawCircle'); } } class RedCircle extends DrawAPI { drawCircle(radius, x, y) { console.log("Drawing Circle[ color: red, radius: " + radius + ", x: " + x + ", " + y + "]"); } } class GreenCircle extends DrawAPI { drawCircle(radius, x, y) { console.log("Drawing Circle[ color: green, radius: " + radius + ", x: " + x + ", " + y + "]"); } } class Shape { constructor(drawApi) { this.drawApi = drawApi; } draw() { console.log('draw shape! '); } } class Circle extends Shape { constructor(x, y, radius, drawApi) { super(drawApi); this.x = x; this.y = y; this.radius = radius; } draw() { this.drawApi.drawCircle(this.radius, this.x, this.y); } } function demo() { const redCircle = new Circle(10, 10, 10, new RedCircle()); const greenCircle = new Circle(20, 20, 20, new GreenCircle()); redCircle.draw(); greenCircle.draw(); } demo();Copy the code

Portfolio model

Introduction to the

  • Solution: Group objects into a tree structure to represent a partial-whole hierarchy.
  • Use: represents a partial-whole hierarchy (tree structure) of an object; The user is expected to ignore the difference between a composite object and a single object, and the user will use all objects in the composite structure uniformly.
  • Method: Branches and leaves realize a unified interface, and branches combine the interface internally.
  • Scenario: partial or overall scenario, such as tree menu, file and folder management.

The advantages and disadvantages

  • Advantages:
    1. High-level modules are easy to call.
    2. Nodes grow freely.
  • Disadvantages: When using the composite pattern, the leaves and branches are declared as implementation classes, not interfaces, violating the dependency inversion principle.

For example,

  • The company has multiple departments, and each department has multiple employees.
class Employee { constructor(dept, name, age) { this.dept = dept; this.name = name; this.age = age; this.adptEmployeeList = {}; } add(employee) { this.adptEmployeeList[employee.name] = employee; } remove(employee) { delete this.adptEmployeeList[employee.name] } getList() { return this.adptEmployeeList } toEmployeeString() { return ("Employee :[ Name : " + this.name + ", dept : " + this.dept + ", age :" + this.age + " ]"); }} function () {const CEO = new Employee(' CEO ', '小小小 17 ', 25); Const headerHR = new Employee('HR', '小 17 ', 20); Const headerSales = new Employee('sales', '17 ', 31); Const hr1 = new Employee(' CEO ', '7 ', 20); Const hr2 = new Employee(' CEO ', '55 ', 19); Const Sales1 = new Employee(' CEO ', '10 ', 28); Const Sales2 = new Employee(' CEO ', '小 9 ', 30); CEO.add(headerHR); CEO.add(headerSales); headerHR.add(hr1); headerHR.add(hr2); headerHR.remove(hr1); headerSales.add(sales1); headerSales.add(sales2); console.log('ceo', CEO); } demo();Copy the code

Decorator mode

Introduction to the

  • Solution: Dynamically add some extra responsibilities to an object. (Inheritance is often used to extend a class, because inheritance introduces static characteristics to the class, and subclasses can get bloated as you extend more functionality.)
  • Use: Extends a class without adding many subclasses.
  • Approach: Divide specific functional responsibilities and inherit decorator pattern.
  • Scenario: Extend the functionality of a class; Dynamic add function, dynamic undo.

The advantages and disadvantages

  • Advantages: The decorator class and the decorator class can develop independently without coupling with each other. The decorator pattern is an inherited replacement pattern, and the decorator pattern can dynamically extend the functionality of an implementation class.
  • Disadvantages: multi-layer decoration is more complex.

For example,

  • Draw shapes in the same color.
class Shape {
    draw() {
        console.log('draw shape.');
    }
}
class Circle extends Shape {
    draw() {
        console.log('draw circle.');
    }
}

class Rectangle extends Shape {
    draw() {
        console.log('draw rectangle.');
    }
}

class ShapeDecorator {
    constructor(shape) {
        this.shape = shape
    }
    draw() {
        this.shape.draw();
    }
}
class RedShapeDecorator extends ShapeDecorator {
    constructor(shape) {
        super(shape)
    }
    draw() {
        this.shape.draw();
        this.setRedColor(this.shape)
    }
    setRedColor() {
        console.log('add red color');
    }
}
function demo() {
    const circle = new Circle();
    const redCircle = new RedShapeDecorator(new Circle());
    const redRectangle = new RedShapeDecorator(new Rectangle());
    circle.draw();
    console.log('--------red circle--------');
    redCircle.draw();
    console.log('--------red rectangle--------');
    redRectangle.draw();
}

demo();
Copy the code

The appearance model

Introduction to the

  • Solution: Reduce the complexity of accessing the internal subsystem of a complex system and simplify the interface between the client and it.
  • Use: Define system entry.
  • Mode: The client is not coupled to the system, the facade class is coupled to the system.
  • Scenario: complex modules or subsystems modules that provide external access; Subsystems are relatively independent; Prevent risks posed by low-level personnel.

The advantages and disadvantages

  • Advantages:
    1. Reduce system interdependence.
    2. Increase flexibility.
    3. Improved security.
  • Disadvantages: inconsistent with the principle of open and close, if you want to change things is very troublesome, inheritance rewrite are not appropriate.

For example,

  • Draw different shapes
class Shape {
    draw() {
        console.log('draw shape.');
    }
}
class Circle extends Shape {
    draw() {
        console.log('draw circle.');
    }
}

class Rectangle extends Shape {
    draw() {
        console.log('draw rectangle.');
    }
}

class ShapeMaker {
    constructor() {
        this.circle = new Circle();
        this.rectangle = new Rectangle();
    }
    drawCircle() {
        this.circle.draw();
    }
    drawRectangle() {
        this.rectangle.draw();
    }
}
function demo() {
    const shapeMaker = new ShapeMaker();
    shapeMaker.drawCircle();
    shapeMaker.drawRectangle();
}

demo();
Copy the code

The flyweight pattern

Introduction to the

  • Solution: Use sharing technology to efficiently support a large number of fine-grained objects.
  • Use: a large number of objects in the system; These objects consume a lot of memory; Most of the state of these objects can be externalized…
  • Method: Use a unique identifier to judge, if there is in memory, return the object identified by this unique identifier.
  • Scenario: The system has a large number of similar objects. Scenarios where buffer pools are required.

The advantages and disadvantages

  • Advantages: Greatly reduce object creation, reduce system memory, improve efficiency.
  • Disadvantages: The complexity of the system is increased, and the external state needs to be separated from the internal state, and the external state has the nature of inherent, should not change with the change of the internal state, otherwise it will cause the chaos of the system.

For example,

  • You need circles of different colors and coordinates.
class Shape { draw() { console.log('draw shape.'); } } class Circle extends Shape { draw() { console.log('draw'); } } class ShapeFactory { constructor() { this.circleMap = new Map(); } getCircle(color) { this.color = color; let circle = this.circleMap.get(color); if (! circle) { const circle = new Circle(color); this.circleMap.set(color, circle); console.log("Creating circle of color : " + color); } return circle; } setX(x) { this.x = x; } setY(y) { this.y = y; } setRadius(radius) { this.radius = radius; } draw() { console.log("Circle: Draw() [Color : " + this.color + ", x : " + this.x + ", y :" + this.y + ", radius :" + this.radius); } } const colors = ["Red", "Green", "Blue", "White", "Black"]; function getRandomColor() { return colors[parseInt(Math.random() * colors.length)]; } function getRandomX() { return Math.random() * 100; } function getRandomY() { return Math.random() * 100; } function demo() { for (let i = 0; i < 5; ++i) { const circle = new ShapeFactory() circle.getCircle(getRandomColor()); circle.setX(getRandomX()); circle.setY(getRandomY()); circle.setRadius(100); circle.draw(); } } demo();Copy the code

The proxy pattern

Introduction to the

  • Solution: Provide a proxy for other objects to control access to this object.
  • Use: You want some control over access to a class.
  • Method: Add an intermediate layer.
  • Scenario: Remote, virtual,Copy-on-Write, protection,Protect or Access),Cache, firewall (Firewall)… The agent.

The advantages and disadvantages

  • Advantages:
    1. Clear responsibilities.
    2. High scalability.
    3. Intelligent.
  • Disadvantages:
    1. Some types of proxy patterns can slow down the processing of requests due to the addition of proxy objects between the client and the real subject.
    2. Implementing the proxy pattern requires additional work, and some of the proxy pattern implementations are quite complex.

For example,

  • We need to load an image locally.
class Images { constructor(filename) { this.filename = filename; } display() { console.log('display.'); } } class RealImage extends Images { constructor(filename) { super(filename); this.loadFromDisk(filename); } display() { console.log('display ', this.filename); } loadFromDisk(filename) { console.log("Loading " + filename); } } class ProxyImage extends Images { constructor(filename) { super(filename); this.realImage = null; } display() { if (this.realImage === null) { this.realImage = new RealImage(this.filename); } this.realImage.display(); } } function demo() { const images = new ProxyImage("test_10mb.jpg"); // Images load from disk images.display(); console.log('----------'); // Images do not need to be loaded from disk. Display (); } demo();Copy the code

conclusion

  • The structural pattern is how classes or objects are arranged into a larger structure. It is divided into class structure pattern, which uses inheritance mechanism to organize interfaces and classes, and object structure pattern, which uses composition or aggregation to combine objects.
  • In daily development, some methods can be combined with two or more methods through structural design patterns, avoiding the need to implement a complete new method and thus reduce code.
  • Structural patterns increase the coupling degree of code, but the coupling degree of combinatorial or aggregated relationships is lower than that of inheritance relationships, which meets the “composite reuse principle”, so the object structural pattern has more flexibility than the class structural pattern. , we should still have specific options based on the actual development situation.

More quality articles

  • Behavior Patterns in JavaScript Design Patterns (Part 2)
  • Behavior Patterns in JavaScript Design Patterns (Part 1)
  • 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.