js设计模式

203 阅读2分钟

工厂模式

<!-- 批量生产具有相同属性的产品 -->

简单工厂模式

/**
  * @description: 制造咖啡
  * @param { dom:咖啡豆  water:水 }
   * @return: 咖啡  */
class makeCoffe{ 
     constructor(dom,water){ 
         this.obj = new Object()
         this.obj.dom = dom
         this.obj.water = water
         this.obj.bili = dom/water
    }
    make(){
         return this.obj
   }
}

const coffee = new makeCoffe(2,3)
console.log( coffee.make() )

复杂工厂模式 - es5

/**
  * @description: 制造咖啡
  * @param { dom:咖啡豆  water:水 }
  * @return: 咖啡*/
function FruitMater(){}
FruitMater.prototype.make = function( type,meta ) { 
     /* 判断是否具备生产能力 */
     if ( typeof this[type] === 'function' ) { 
          let func = this[type]
          func.prototype = FruitMater.prototype     /* 改变this指向 */
          return new func( meta ) 
     } else {
          throw  new Error('很抱歉,工厂不能生产该产品')   /* 抛出异常 */       
     }
}
FruitMater.prototype.extend = function( obj ) {      /* 生产线扩展 */
        for ( let key in obj ) {
             this[key] = obj[key] 
        }
} 
FruitMater.prototype.extend({                  /* 设计生产线 */  
       "Apple":function(meta){   
               console.log("生产一杯苹果汁",meta)
         },  
       "Pear":function(meta){ 
             console.log("生产一杯梨子汁",meta) 
        }
 })
const maker = new FruitMater(), 
      apple = maker.make( 'Apple', "一个苹果一杯水")

单例模式

整个程序中一个类只有一个实例对象

  1. 全局只有一个对象

  2. 避免重复删除、创建

一:全局变量

let instance = null
function Tool(){
    if( instance ) return instance 
    /* 第一次会走下面语句     * 第二次及以后,直接return instance */
    instance = this
    this.name = "sjx"
}​
const t1 = new Tool(), 
      t2 = new Tool()
​console.log( t1===t2)  // true

缺点:任何人都可以访问和修改 instance

二:即时函数

( function(w){
     let instance = null
     function Tool(){ 
           if( instance ) return instance
           instance = this 
           this.name = "sjx"
     }  
     w.Tool = Tool
})(window)

三:惰性函数

function Tool(){
      let instance = this, 
          oldPrototype = Tool.prototype

       this.name = "sjx"​
       Tool =  function(){   // 第一次执行赋值,修改函数指向,以后返回instance  
                   return instance 
       }
       Tool.prototype = oldPrototype  // Tool的原型指向旧的 prototype 
       instance = new Tool()
       instance.constructor = Tool // 新建实例 instance.__proto__constructor 指向Tool 
       return instance  
} 
const t1 = new Tool(),
      t2 = new Tool()
Tool.prototype.run = () => console.log("hhh")

console.log( t1===t2)
t1.run()

策略模式

/*  * @Description: 根据后台返回字段,确定商城劵的类型
    * @Autor: 孙佳星
    * @params: 字段 interestFreeEffect | amountEffect | rateEffect
    */
const strategies = {
        "interestFreeEffect": () => <span>免息券</span>,
        "amountEffect": () =>  <span>满减券</span>, 
        "rateEffect":() => <span>折扣券</span>
},calculateBonus =  mode => strategies[mode]()​

<Descriptions.Item label="优惠券类型">{ 
    detail.discountEffectSelect && calculateBonus(detail.discountEffectSelect)
} </Descriptions.Item>

发布订阅模式

const lk = {
   typeTargetAction:{}, 
   // 添加用户
   addUser: function ( type, target, action ) { 
        if( typeof this.typeTargetAction[type] === "undefined"){  // 判断用户有没有该类型
           this.typeTargetAction[type] = []    // 之所以为数组,是因为一个类型,可能有多个用户
        }
        // 创建对象
        const obj = { target, action}
        this.typeTargetAction[type].push( obj )
     },
     // 发布订阅
     publishMsg: function( type, msgContent ) {
         const targetAction = this.typeTargetAction[type] || []
         for ( const i = 0,len = targetAction.length; i<len; i++ ) {
            const obj = targetAction[i],
                  target = obj.target,
                  action = obj.action
            action.call( target, msgContent)
         }
     }
}
// 新建两个对象
  const stu1 = { name:"sjx" },
        stu2 = { name:"lj" }
 
  lk.addUser("React", stu1, function( msgContent){
      console.log( this.name,msgContent,"推送消息")
  })
  lk.addUser("Vue", stu2, function(msgContent ){
      console.log( this.name, msgContent,"推送消息" )
  })

  lk.publishMsg("React","React框架")



const Admin = function() {}
Admin.prototype.start = function() {}
Admin.prototype.end = function() {}

const myAdmin = new Admin()
myAdmin.start()

const Admin = function () {}
Admin.prototype = { 
     start: function() {},
     end: function () {}
}

Function.prototype.method = function( name , fn ) {   /* 为类添加方法 */
     this.prototype[name] = fn
}

const Admin = function () {}
Admin.method( "start", function(){

})
Admin.method( "end", function(){ 

})

Function.prototype.method = function( name , fn ) {   /* 为类添加方法 */
     this.prototype[name] = fn
     return this
}
const Admin = function () {}

Admin.method( "start", function(){

}).method( "end", function(){

})