preface

Here’s a few minutes to explain a few design patterns and how they apply. This can help you apply design patterns to your daily development

  • Decorator mode
  • Iterator pattern
  • Publish and subscribe model
  • The factory pattern
  • The singleton pattern
  • The proxy pattern
  • The appearance model

Without further ado, let’s go straight to the demo

Decorator mode

A decorator DEMO
<! --index.js-->function decoratorHoc(target){
    target.customerName = 'xuqiang';
}

@decoratorHoc
class Person{}

console.log(Person.customerName);
Copy the code
Decorator query 🤔️
  • DecoratorHoc is a function. Why support @decoratorHoc? Don’t take this for granted. You can try to copy the code to vscode, and then the code runner finds out that it’s reporting this error

So the next three steps are to get the Babel environment going

  • Install global Babel
<! -- in the current index.js directory --> yarn add Babel -cli -g yarn add babel-plugin-transform-decorators-legacyCopy the code
  • Configuration. Babelrc
<! Babelrc --> {plugins: ['transform-decorators-legacy']}Copy the code
  • Compile the index. Js
<! -- in the current directory --> Babel index.js -- out-of-file compiledCopy the code

Here we compile index.js to compiled compiled. Then code runner Compiled. Js and find “xuqiang”

Decorator mode application scenario

The decorator pattern can be said to extend an object very conveniently. Are there any classes of code that are similar to the decorator pattern in normal development

  • React advanced components
  • Dva @ the connect

Here are just two examples and more scenarios to discover for yourself

Iterator pattern

Iterators are called iterators when iterating over an object. We’ll start with es6 iterators

The for – traverse json

This is a DEMO of es6’s custom iterator. How to write an iterator to iterate over ordinary objects, because iterator groups are already built in

let obj = {
    name: 'xuqiang',
    age: 20,
    [Symbol.iterator]: () => {
        let props = Object.keys(obj), i = props.length;
        return {
            next() {if(i > 0){
                    i = i - 1;
                    return {
                        value: obj[props[props.length - i - 1]],
                        done: false
                    };
                }else{
                    return {
                        value: ' '.done: true}; }}}; }}for(let prop of obj){
    console.log(prop);
}
Copy the code

Code Runner found that an Object can be traversed correctly

Publish and subscribe model

Publish subscription scenarios

Use a cliche scenario to explain publishing subscriptions first, that is to order milk in school days, to sort out the demand first

  • There is a factory, there is a let products = {}, there is a property called milk. This property corresponds to an array that stores data for each subscriber.
  • The factory has a timer that starts to traverse the products at 8 o ‘clock every morning for milk distribution
  • There are a lot of consumers ordering milk from the factory

Requirements sorted out, the following with a DEMO to achieve the next

Class Puber{constructor(name){this.name = name; this.products = {}; this.startInterval(); }startInterval() {setInterval(() => {
            for(let prop in this.products){
                if(this.products.hasOwnProperty(prop)){ this.emit(prop); }}}, 3000); } sub(evt, cb){if(! this.products[evt]){ this.products[evt] = []; } this.products[evt].push(cb); } emit(evt){if(this.products[evt]){
            let cbs = this.products[evt];
            for(let cb of cbs){
                cb && cb();
            }
        }
    }
}

class Suber{
    constructor(name){
        this.name = name;
        this.puber = new Puber(Penny ur (');
    }

    getPuber() {the console. The log (` I am${this.name}My milkman is${this.puber.name}`); } sub(evt, cb){ this.puber.sub(evt, cb); }}let customer1 = new Suber('Liu Siqi');
customer1.getPuber();
customer1.sub('milk', () => {console.log(' now time is${+new Date}, milk sent to future Science and Technology City, recipient: Liu Siqi '); });let customer2 = new Suber(Big Xu);
customer2.getPuber();
customer2.sub('milk', () => {console.log(' now time is${+new Date}, milk to Airport New Town, addressee: Big Xu '); });Copy the code

The factory pattern

class jQuery{ constructor(name){ this.name = name; }}function $(name){
    return new jQuery(name);
}

let obj1 = $('xuqiang');
let obj2 = $('liusiqi');
console.log(obj1);
console.log(obj2);
Copy the code
Summary of Factory Model

The $function of jquery uses factory mode. What are the benefits of factory mode?

  • You don’t need to call new jQuery yourself. It’s very convenient to use $directly
  • CreateElement, like React. CreateElement, blocks developers from using the new VNode directly. The implementation of VNode is invisible to developers

The singleton pattern

The singleton pattern alone is a little bit simple and doesn’t feel very exciting, so let’s write a singleton pattern with the decorator pattern, okay

Write a decorator mode + singleton mode SAO operation
function getInstanceHoc(target){
    target.getInstance = (() => {
        let instance;
        return() = > {if(! instance){ instance = new Function(`return new ${target}`) () (); }return instance;
        }
    })();
}

@getInstanceHoc
class Person{
    eat(){
        console.log('i am eating'); }}let obj = Person.getInstance();
console.log(obj);
obj.eat();

let obj1 = Person.getInstance();
console.log(obj === obj1);
Copy the code

After code Runner finds that both obj and obj1 can eat, and then compares obj===obj1 and finds that it is true, indicating that the singleton mode has succeeded

The proxy pattern

Use es6 Proxy to talk about Proxy

class Vue{
    constructor(data){
        let _data =  data;

        return new Proxy(this, {
            get(target, key){
                return _data[key];
            },
            set(target, key, val){
                _data[key] = val;
                return true; }}); }}let obj = new Vue({
    name: Penny ur (',
    age: 20
});
console.log(obj.name);
obj.name = 'Liu Siqi';
console.log(obj.name);
Copy the code

The appearance model

Appearance mode is common in jquery. In our peacetime development also feel very easy to use

function winAlert(title, message, buttons, cb){
    if(cb === undefined){
        cb = buttons;
        buttons = null;
    }

    console.log(title);
    console.log(message);
    console.log(buttons);
    console.log(cb);
}

winAlert('tip'.'Operation completed'['confirm'.'cancel'], () = > {}); winAlert('tip'.'Operation completed', () = > {});Copy the code

Running results:

This reminds me that in the current business, all the back-end interfaces are APP/htmlgateway. do, only version, RD and other parameters are different, which conforms to the appearance mode from a certain point of view. Close the internal implementation of the back-end API, open htmlGetway to the front end call

The problem with this approach is that it’s not very friendly to mock platforms like YAPI and RAP2. Because the API path is consistent, it will not be good to mock, or because I did not find a solution, so I think it is not good to mock

Ok, we’ve done the demo for all of these design patterns. We can talk about problems together.