Several common design patterns in the front end (including implementation code)

What is a design pattern

Design mode is to summarize some common problems, and give a set of general solutions for specific problems (emphasis is on the idea of ​​solving problems); in development, as long as you encounter such problems, you can directly use these designs The model solves problems; it originated in the field of architecture, and summarized some problems and experiences in the field of architecture, and formed a set of solutions that can be used to solve most problems in the field of architecture. Later, the computer field borrowed from the design mode of the field of architecture. The problems frequently encountered in the computer field are summarized and summarized, forming 23 design patterns in the computer field.

Traditional singleton pattern

In popular terms, the singleton mode is equivalent to the login window of some software or websites. Click login, then cancel and click login again. The login window that pops up is still the same one, and the window will not be recreated.

Ensure that a class has only one instance, and provide a global access point to it.

Realize the core idea of ​​singleton

A variable is used to mark whether an object has been created for a certain class. If it is, the next time an instance of the class is obtained, the previously created object will be returned directly

Use js code to implement singleton mode

var CreateDiv = function (text) {
    
     //构造函数,初始化一个对象(对象又称为实例)
    this.text = text;
    this.init();
};

CreateDiv.prototype.init = function () {
    
    
    var div = document.createElement('div'); 
    div.innerHTML = this.text; 
    document.body.appendChild(div);
};

var ProxySingletonCreateDiv = (function () {
    
      //实现单例的函数
    var instance;
    return function (text) {
    
    
        if (!instance) {
    
     //若instance实例不存在,则创建
            instance = new CreateDiv(html);
        }
        return instance;
    }
})();

var a = new ProxySingletonCreateDiv('sven1');
var b = new ProxySingletonCreateDiv('sven2');

alert(a === b); //true

Factory mode

Popular for example, it is equivalent to the roadside vending machines we see. As consumers, we can get what we want only by choosing goods and paying. How do vending machines recognize choices and how they work? There is no need to know. Vending opportunities hide its working principle and mechanism, and it is equivalent to a factory.

The factory pattern is a design pattern used to create objects. We do not expose the logic of object creation, but encapsulate the logic in a function, then this function can become a factory.

According to the different degree of abstraction, the factory model can be divided into:

  1. Simple factory

  2. Factory method

  3. Abstract factory

Simple factory pattern

Implement simple factory pattern with js code

let  factory = function (role) {
    
    
    function User(obj) {
    
    
        this.name = obj.name;
        this.role = obj.role;
    }
    switch(role) {
    
    
        case 'superman':
          return new User({
    
     name: '平台用户', role: ['主页', '登录页'] })
          //break;
        case 'man':
          return new User({
    
     name: '游客', role: ['登录页']})
          //break;
        default:
          throw new Error('参数错误')
    }
  }
    
  let superman = factory('superman');
  let man = factory('man');
 factory就是一个简单的工厂,该工厂中有一个构造函数分别对应不同的权限。我们只需要传递相应的参数就可以获取一个实例对象了

The advantages of a simple factory:
Only need to pass a legal parameter, you can get the desired object without knowing the specific details of creation.

But the function contains all the object's constructor and judgment logic code. Every time if we need to add an object, then we need to add a new constructor. When the objects we need to maintain are not the above two, but 20 Or more, then this function will become a super function, making it difficult for us to maintain.

Therefore, the simple factory model is only suitable for situations where the number of objects is small at the time of creation and the logic is simple.

Factory method

The original intention of the factory method pattern is to defer the actual creation of objects to subclasses, so that the core class becomes an abstract class. But it is difficult to implement abstract classes in js like those traditional object-oriented languages, so we only need to refer to his ideas in js.

We can think of the factory function as a factory class. In the simple mode, we need to modify two places to add a new object. After adding the factory method pattern, we only need to modify one place. For the factory class of the factory method, he only does the instantiation. We only need to modify his prototype class.

We use the safe mode to create factory objects.

Implement factory method with js code

let factory = function (role) {
    
    
    if(this instanceof factory) {
    
      //instanceof是一个运算符,用来判断一个对象是否是某个类的实例
        var s = new this[role]();
        return s;
    } else {
    
    
        return new factory(role);
    }
}

factory.prototype = {
    
    
    admin: function() {
    
    
        this.name = '平台用户';
        this.role = ['登录页', '主页']

    },
    common: function() {
    
    
        this.name = '游客';
        this.role = ['登录页']
    },
    test: function() {
    
    
        this.name = '测试';
        this.role =  ['登录页', '主页', '测试页'];
        this.test = '我还有一个测试属性哦'
    }
}

let admin = new factory('admin');
let common = new factory('common');
let test = new factory('test');

Abstract factory pattern

(1) The abstract factory pattern provides a way to encapsulate a group of single factories with the same theme without specifying their specific classes. That is, the factory of the factory; a factory that groups single but related/subordinate factories together, but does not specify its specific category.

(2) An abstract factory creates objects related to a common theme. In object-oriented programming, a factory is an object that creates other objects. An abstract factory has abstracted a theme, which is shared by newly created objects.

(3) You may be wondering why the responsibility of constructing the object is given to others instead of calling the constructor directly with the new keyword.
The reason is: the constructor has limited control over the entire creation process, and sometimes you need to give control to a factory with more extensive knowledge. This includes scenarios involving object caching, object sharing or reuse, complex logic, or maintaining object and type counts during the creation process, and objects interacting with different resources or devices. If your application requires more control over the object creation process, consider using the abstract factory pattern.

Abstract factory pattern function

When there are interrelated dependencies and involve non-simple creation logic, it is recommended to use the abstract factory pattern. The abstract factory pattern is usually considered in the following situations:

  1. A system should be independent of the creation, composition and presentation of its products

  2. The system should be configured with one of multiple product series

  3. A series of related product objects are only used together, so this constraint needs to be enforced

  4. Want to provide product class libraries, and only want to display their interfaces, not their implementations

  5. Conceptually, the lifetime of the dependency is shorter than the lifetime of the consumer.

  6. Need a runtime value to build specific dependencies

  7. I want to decide which product to call from the series at runtime.

  8. You need to provide one or more parameters that are only known at runtime before the dependencies can be resolved.

  9. When consistency between products is needed

  10. When adding a new product or product line to the program, you do not want to change the existing code.

Use js code to implement abstract factory pattern

//员工类
function Employee(name) {
    
    
    this.name = name;

    this.say = function() {
    
    
        log.add("我是员工:" + name);
    };
}
//员工工厂
function EmployeeFactory() {
    
    
    this.create = function(name) {
    
    
        return new Employee(name);
    };
}
//供应商类
function Vendor(name) {
    
    
    this.name = name;

    this.say = function() {
    
    
        log.add("我是供应商:" + name);
    };
}
//供应商工厂
function VendorFactory() {
    
    
    this.create = function(name) {
    
    
        return new Vendor(name);
    };
}

// 日志函数
var log = (function() {
    
    
    var log = "";

    return {
    
    
        add: function(msg) {
    
    
            log += msg + "\n";
        },
        show: function() {
    
    
            console.info("%c%s", "color: red; background: #b4b3b3; font-size: 20px", log);
            log = "";
        }
    }
})();

function run() {
    
    
    var persons = [];
    var employeeFactory = new EmployeeFactory();
    var vendorFactory = new VendorFactory();

    persons.push(employeeFactory.create("张三"));
    persons.push(employeeFactory.create("李四"));
    persons.push(vendorFactory.create("王麻子"));
    persons.push(vendorFactory.create("赵六"));

    for (var i = 0, len = persons.length; i < len; i++) {
    
    
        persons[i].say();
    }

    log.show();
}

Guess you like

Origin blog.csdn.net/PILIpilipala/article/details/113881789