4
头图

Preface

When it comes to design patterns, everyone may feel a little lofty. In fact, the concept of this thing is very abstract, but there are still many places where the idea of design patterns can be used in actual development to optimize our code. This article aims to introduce some commonly used design patterns in development, learn through examples, and try to get through the concepts as much as possible. In order to win the front end of 160f5381ac7867, let’s learn together!

image.png

text

1. Adapter Mode

concept: Transform the interface of one class into another interface to meet user needs, so that the incompatibility of interfaces between classes (objects) can be solved through adapters.

In work, sometimes in order to meet the needs, when developing a new module, it is necessary to make a compatibility with the old module. At this time, the adapter mode is needed.

For example:

  1. Methods pass parameters by default
// 参数大于2建议使用对象进行合并
function doSomeThing(obj){
  const adapter = {
    name:"默认姓名",
    color:"red",
    size:200,
    age:20
  }
  for (let i in adapter){
    adapter[i] = obj[i] || adapter[i];
  }
  // do some thing
}

It can be seen that after this processing, we can guarantee that the object has these attributes regardless of the parameters passed in. Avoid subsequent logic errors.

  1. The expansion and compatibility of the global encapsulation method.

In the use of vue, we usually mount api requests on the vue instance, but some old projects encapsulate ajax requests. When refactoring the old projects, we need to put all api requests on axios or fetch. . This can use the adapter mode.

// 对fetch 封装伪代码
export default class FetchApi{
    static get(url){
        return new Promise((resolve,reject)=>{
      fetch(url).then(...).catch(err=>reject(err))
    })
    }
  static post(url,data){
    return new Promise(...)
  }
}
  
// 在使用时我们可以这么使用
  const res = await FetchApi.get(url) || {};
// 或者
  const res = await FetchApi.post(url,params) || {}
  
  
// 再看一下原有的接口封装方式  伪代码
  function Ajax(type,url,data){
    const xhr = new XMLHttpRequest()
    ...
    if(type === 'GET'){
      xhr.open('GET',url+"?"+data,true);
      xhr.send()
    }else if(type === 'POST'){
        xhr.open('POST',url,true);
        xhr.setRequestHeader("Content-type",'application/x-www-form-urlencoded')
        xhr.send(data)
    }
    ...
  }
  
  // 调用方式
  Ajax("GET",url,data)
  

Here we can see that the interface names of the new and old interfaces are different, and the request parameters are also different. It doesn't matter, use the adapter to solve it.

 // 伪代码  
  async function ajaxAdapterr(type,url,data){
    let result
    if(type === 'GET'){
      result = await FetchApi.get(url) || {}
    }else if(type === 'POST'){
      result = await FetchApi.post(url,data) || {}
    }
  }
    
   async function Ajax(type,url,data){
        await ajaxAdapterr(type,url,data);
   }

In this way, the original ajax request can be changed to fetch, avoiding to modify the request in the page one by one. Save a lot of time and can be used to fish.

image.png

2. Strategy Mode

concept: encapsulate a set of defined algorithms so that they can be replaced with each other. The encapsulated algorithm has a certain degree of independence and will not change with changes in the client.

The concept of this thing is to be good at everyone understands as everyone does not understand. Let's look at the actual scene.

At work, I believe you must have written a lot of if else judgments. When there are more and more conditions, this way of writing will become particularly bloated, so use the strategy mode to optimize it.

For example:

function doSomeThing(type){
  if(type === 'pre'){
    return 100
  }else if(type === 'onSale'){
    return 200
  }else if(type === 'back'){
    return 150
  }else if(type === 'fresh'){
    return 250
  }
}

// 逻辑会越来越臃肿 用策略模式优化一下
function doSomeThing(type){
  const priceType = {
    pre(){
      return 100
    },
    onSale(){
      return 200
    },
    back(){
      return 150
    },
    fresh(){
      return 250
    }
  }
  return priceType[type]()
}

It can be seen that after using the strategy mode optimization, the mapping relationship of the code is very clear, and it is more flexible and intuitive. The later maintenance only needs to add methods to the object. Shuai is just one word, I only say it once. Which front-end lady does not say that this kind of code is great?

3. State mode

concept: When the internal state of an object changes, it will cause its behavior to change, which looks like it changes the object.

The concept of the state mode is similar to the strategy mode. Both encapsulate behaviors and realize behavior distribution through delegation. However, the method of distribution in the strategy mode is not dependent, parallel to each other, and flooding does not violate the river. In the state model, each function has a certain relationship with the subject.

For example:

Automatic coffee machine

class Coffee{
  constructor(){
    this.state ='黑咖啡';
  }
  stateProcessor = {
      american: () => {
         console.log("黑咖啡")
      },
      latte: () => {
          this.stateProcessor.american(); // 制作黑咖啡
          console.log("加奶")
      },
      vanillaLatte: () => {
           this.stateProcessor.latte();
           console.log("加香草🌿糖浆")
      },
      mocha: () => {
            this.stateProcessor.latte();
            console.log('加巧克力🍫')
      }
  }
 
  changeState(state){
    this.state = state;
    if(!this.stateProcessor[state]){
      return console.log("暂无此咖啡")
    }
    this.stateProcessor[state]()
  }
}

const coffee = new Coffee();
coffee.changeState("latte")

The state mode mainly solves the when the conditional expression that controls the state of an object is too complicated. By transferring the judgment logic of the state to a series of classes representing different states, the complex judgment logic can be simplified.

4. Agency Mode

concept: Since one object cannot directly refer to another object, it needs to play an intermediary role between these two objects through a proxy object.

Agents may be involved in normal development. The basic types of agents will not be introduced here, but caching agents will be introduced here.

for example:
Sum processing the input parameters

// addAll方法会对你传入的所有参数做求和操作
const addAll = function() {
    console.log('进行了一次新计算')
    let result = 0
    const len = arguments.length
    for(let i = 0; i < len; i++) {
        result += arguments[i]
    }
    return result
}

// 为求和方法创建代理
const proxyAddAll = (function(){
    // 求和结果的缓存池
    const resultCache = {}
    return function() {
        // 将入参转化为一个唯一的入参字符串
        const args = Array.prototype.join.call(arguments, ',')
        // 检查本次入参是否有对应的计算结果
        if(args in resultCache) {
            // 如果有,则返回缓存池里现成的结果
            return resultCache[args]
        }
        return resultCache[args] = addAll(...arguments)
    }
})()

image-20210719122848035.png

It can be seen that when the input parameters are consistent, only one calculation is performed, and the subsequent values are retrieved from the cache for return. This will greatly save time and overhead in the case of particularly large calculations.

5. Decorator Mode

concept: On the basis of not changing the original object, by packaging and extending it (adding attributes or methods), the original object can meet more complex needs.

For example:
In the approval flow, the original requirements that were approved and rejected are all put together for processing. Later, the requirements are added, and a pop-up box needs to be displayed when the rejection is rejected.

// 原有的审批逻辑
function approvalOrReject(){
    // do some thing
}

function rejectShowBox(){
    this.approvalOrReject();
    this.showMessageBox(); // 显示弹框
}

In this way, we have implemented the "add only, don't modify" decorator mode. The decorator mode in actual development is very useful, you can find out with your heart~

summary

Let's summarize these design patterns for the time being, and we will continue to add them later. Please like and collect and follow~

Since I used the design pattern, my little sister has started to nod to me frequently, brothers, let's use it.

Due to my limited level, please contact me if there are any errors in the article.

greet_eason
482 声望1.4k 粉丝

技术性问题欢迎加我一起探讨:zhi794855679