js的设计模式

146 阅读2分钟

单例模式

也就是一个类只有一个实例,因为 javascript 没有类的概念,可以认为一个构造函数只能生产一个实例对象。

 var getSingleton= (function fun(){
       let instance;
       return function getSingleton(){
           if(!instance){
               var Fn=arguments[0];
               instance=new Fn(...Array.prototype.slice.call(arguments).slice(1));
           }
           return instance;
       }
  })()

    function Fn(name,age){
       this.name=name;
       this,age=age;
    }
   Fn.prototype.getName=function(){
       return this.name;
   }

    var indstance1=getSingleton(Fn,"sunshine")
   var indstance2=getSingleton(Fn,"liu")
    console.log(indstance1===indstance2)
   console.log(indstance1.getName());
   console.log(indstance2.getName());

策略模式

先定义一组策略模式,然后定义一个context统一管理这个策略,当用户要使用其中一个策略的时候,需要通过context,context根据传入参数决定返回哪个策略结果

let actions={
    'A':function(){
        console.log("这是A策略")
    },
    'B':function(){
        console.log("这是B策略")
    },
    'C':function(){
        console.log("这是C策略")
    },
    'D':function(){
        console.log("这是D策略")z
    }
}
function context(actionType){
  return actions[actionType] ? actions[actionType] : undefined;
}

console.log(context('A'));
console.log(context('B'));

代理模式

在访问真正的对象之前,需要进行一些额外的处理

当用户需要访问实际对象时,首先访问的是代理对象,代理对象做一些操作之后,再去调用真正的对象进行执行。

代理模式主要有以下几种:保护代理,虚拟代理,缓存代理

当用户发送信息时,不是直接发送,而是采用代理发送,以确保发送的信息是有效的

 function sendMsg(name){
       return "send a message---"+name;
   }

   function proxySendMsg(name){
       if(!name){
           return undefined;
       }
      name = name.replace(/\d/g,"0");
       return sendMsg(name);
   }
   console.log(proxySendMsg("你好123"));

迭代器模式

/* JS中数组的map forEach 已经内置了迭代器*/

下面我们来写一个自己的迭代器,这个迭代器乐意遍历数组和对象。

Object.prototype.myForEach = function (fn) {
    var ref = this;
    if (Array.isArray(ref)) {
        ref.forEach((item, index, re) => {
            fn(item, index, re);
        });
    } else {
                for (var item in ref) {
                    if (ref.hasOwnProperty(item)) {
                fn(ref[item], item, ref);
            }
        }
    }
}
let arr = [1, 4, 5, 88, 99, 100];
let fn=(item, index, obj) => {
    console.log(item, index, obj);
}
arr.myForEach(fn)
let obj = {
    name: "sunhine",
    age: 12,
    sex: "女"
}
obj.myForEach(fn)

观察者模式

class Subject {
  constructor() {
    this.state = 0;
    this.obersvers = [];
  }

  subscribe(obersver) {
    this.obersvers.push(obersver);
  }

  pushlish(state) {
    this.state = state;
    this.obersvers.forEach((obersver) => {
      obersver.update(this.state);
    });
  }
}

class Obersver {
  constructor(name) {
    this.name = name;
  }
  update(state) {
    console.log(this.name + '更新了' + state);
  }
}

const obervers1 = new Obersver('小明');
const obervers2 = new Obersver('小李');

const subject = new Subject();
subject.subscribe(obervers1);
subject.subscribe(obervers2);
subject.pushlish('新状态');

发布订阅模式:

一个中间对象Eevent同时维护者发布者和订阅者。

function Eevent(){
    this.name="";
    this.age=0;
    this.subScribes=[];
     this.subScribe=(fn)=>{
         this.subScribes.push(fn);
     }
     this.publish=(name,age)=>{
         this.name=name;
         this.age=age;
         this.subScribes.forEach(item=>{
             item(this.name,this.age);
     })
     }
 }

var ev=new Event();
ev.subScribe(function (name, age) {
    console.log("小明订阅:" + name, age);
})

ev.subScribe(function (name, age) {
    console.log("小张订阅:" + name, age);
})
ev.publish("xioming", 11)
ev.publish("lixiao", 22)
ev.publish("huang", 33)

观察者模式和发布订阅模式的区别就是,观察者模式只有观察者和被观察者,发布订阅模式就像一个邮局,所有的订阅者都通过邮局获取消息,所有的消息都先达到邮局,然后邮局再通知所有的观察者最新消息