js设计模式简单例子

简介: js设计模式简单例子

目录

工厂模式


方便经常创建某个对象,我们可以把这个对象封装成一个可以调用的函数,可以随时通过调用该函数获得自己需要的对象。

    function factory(type) {
      switch (type) {
        case "type1":
          return { name: "类型1" };
          break;
        case "type2":
          return { name: "类型2" };
          break;
        case "type3":
          return { name: "类型3" };
          break;
        default:
          break;
      }
    }
    const obj = factory("type1");//{ name: "类型1" }

建造者模式


当需要创造一个单一庞大的对象时,把对象各个部分拆成单独的类,然后根据需求组合在一起,由最终类提供需要的对象。

    const head = {
      name: "头部",
    };
    const foot = {
      name: "脚部",
    };
    function final() {
      return {
        head,
        foot,
      };
    }
    const obj = final();//{ head: { name: "头部" }, foot: { name: "脚部" } }

单例模式


某个对象,全局只允许存在一个的时候,即便被重复创建,获得的仍然是原来的对象。

    function single(name) {
      return this.instant ? this.instant : (this.instant = { name });
    }
    const obj1 = single("123");//{name:"123"}
    const obj2 = single("1");//{name:"123"}

桥接模式


把重复的方法抽样出来,每个方法都可以被高度复用,且抽样出来的单位可以独立与桥接函数进行修改,再桥接出去。

有点类似建造者模式?是这样的,但是他们的本质不同。

建造者模式核心是构造对象,而桥接模式是为了简化代码,提高复用性。

区别就是一个关注创建一个关注功能。

    function way(wayName) {
      return {
        wayName,
      };
    }
    function destination(destinationName) {
      return {
        destinationName,
      };
    }
    //由桥接来实现对上述两种抽象方法的利用
    function bridge(wayName, destinationName) {
      const wayObj = way(wayName);
      const destinationObj = destination(destinationName);
      console.log(wayObj.wayName + "去" + destinationObj.destinationName);
    }
    bridge("坐船", "北京");//坐船去北京

享元模式


为了减少对象数量,提取共有部分,私有部分从外部传入。

我们可以结合桥接模式的例子,如果我们交通方式不可变,我们只有一艘船,需要坐船去各个地方。

    function way(wayName) {
      return {
        wayName,
      };
    }
    function destination(destinationName) {
      return {
        destinationName,
      };
    }
    function bridge(wayName, destinationName) {
      const wayObj = way(wayName);
      const destinationObj = destination(destinationName);
      console.log(wayObj.wayName + "去" + destinationObj.destinationName);
    }
    bridge("坐船", "北京"); //坐船去北京
    bridge("坐船", "上海"); //坐船去上海
    bridge("坐船", "湖南"); //坐船去湖南

你会发现这些例子中,在桥接函数中,坐船那个方式对象被重复创建了。

享元模式就是需要避免重复创建不必要的对象。

将共有部分坐船提取出来,而私有部分不同的目的地仍然从外部传入。

意味着我们坐的一直都是同一艘船。

    function way(wayName) {
      return {
        wayName,
      };
    }
    function destination(destinationName) {
      return {
        destinationName,
      };
    }
    function bridge(wayObj, destinationName) {
      const destinationObj = destination(destinationName);
      console.log(wayObj.wayName + "去" + destinationObj.destinationName);
    }
    const wayObj = way("坐船");
    bridge(wayObj, "北京"); //坐船去北京
    bridge(wayObj, "上海"); //坐船去上海
    bridge(wayObj, "湖南"); //坐船去湖南

模板方法模式


这个模式就是有一系列算法,但是有些部分可以在使用时定义,也就是给你模板,你自定义一些部分然后使用。

  function counter() {
    return {
      beforeCounter: [],
      afterCounter: [],
      addBefore: function (fn) {
        this.beforeCounter.push(fn);
      },
      addAfter: function (fn) {
        this.afterCounter.push(fn);
      },
      count: function (num) {
        //结果变量
        var resultnum = num;
        //算法队列数组组装
        function baseCount(num) {
          num *= 2;
          return num;
        }
        var arr = [baseCount];
        arr = this.beforeCounter.concat(arr);
        arr = arr.concat(this.afterCounter);
        //不同部分的相同算法骨架
        //循环执行算法队列
        while (arr.length > 0) {
          resultnum = arr.shift()(resultnum);
          console.log(resultnum)
        }
        return resultnum;
      }
    }
  }
  //使用
  var countObject = counter();
  countObject.addBefore(function (num) {
    num--;
    return num;
  })
  countObject.addAfter(function (num) {
    num++;
    return num;
  })
  countObject.count(10)

这是一个连续计算的计算器,中间维护了一个数组,数组内有自己添加的计算过程(函数),也有中间公共的计算过程。


适配器模式


将不适合我们使用的数据通过适配器转化成我们需要的数据。


         
  const arr = ['月亮', '18', '男']
  const adapter = (arr) => {
    return {
      name: arr[0],
      age: arr[1],
      sex: arr[2]
    }
  }
  console.log(adapter(arr))//{name: '月亮', age: '18', sex: '男'}

例子很简单,只是传达一种思想,实际中的适配器可能会更为复杂,但是目的是一致的。


装饰者模式


js使用装饰者模式没有其他语言那么困难,其实可以直接重写对象,不过这显然不太好,当别人封装了一个函数,你想要在旧的函数基础上装饰上新的内容。

  const test = () => {
    console.log('旧内容')
  }
  const _test = test
  const newTest = () => {
    _test()
    console.log('新内容')
  }
  newTest()//旧内容 新内容

命令模式


将一些方法保存在内部,通过输入指令依次执行。

  const design = (() => {
    const action = {
      triangle: (val) => {
        console.log('画一个边长为' + val + '的三角形')
      },
      circle: (val) => {
        console.log('画一个周长为' + val + '的圆')
      }
    }
    return function excute(actions) {
      actions.forEach(act => {
        const { actName, actVal } = act
        action[actName](actVal)
      });
    }
  })()
  design([
    { actName: 'triangle', actVal: '3' }, 
    { actName: 'circle', actVal: '3' }
  ])
  //画一个边长为3的三角形
  //画一个周长为3的圆

观察者模式


就是事件订阅和绑定,我们可以自己写一个绑定代码

  const Event = {
    on: function (eventName, callback) {
      this.actions = this.actions ? this.actions : {}
      this.actions[eventName] = callback
    },
    emit: function (eventName, val) {
      if (this.actions[eventName]) {
        this.actions[eventName](val)
      }
    }
  };
  Event.on('test', function (result) {
    console.log(result);
  });
  Event.emit('test', 'hello world'); // 'hello world'

这里代码没有考虑Event的拓展性和可复用性,只是为了让人简单了解观察者模式。

职责链模式



使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间 的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

  function cat(type) {
    if (type == "cat") {
      console.log("我是猫猫");
    } else {
      return "nextSuccessor"
    }
  }
  function dog(type) {
    if (type == "dog") {
      console.log("我是狗狗");
    } else {
      return "nextSuccessor"
    }
  }
  function pig(type) {
    if (type == "pig") {
      console.log("我是猪猪");
    } else {
      return "nextSuccessor"
    }
  }
  Function.prototype.after = function (fn) {
    var _self = this;
    return function () {
      var ret = _self.apply(this, arguments);
      if (ret === "nextSuccessor") {
        return fn.apply(this, arguments);
      }
      return ret
    }
  }
  var pet = cat.after(dog).after(pig);
  pet("pig"); //我是猪猪
  pet("dog"); //我是狗狗
  pet("cat"); //我是猫猫

这个例子可能after代码可能很难理解,但是主要传递的是解耦链式的思想。

相关文章
|
1月前
|
设计模式 JavaScript 前端开发
JavaScript设计模式--访问者模式
【10月更文挑战第1天】
31 3
|
3月前
|
设计模式 JavaScript 前端开发
从工厂到单例再到策略:Vue.js高效应用JavaScript设计模式
【8月更文挑战第30天】在现代Web开发中,结合使用JavaScript设计模式与框架如Vue.js能显著提升代码质量和项目的可维护性。本文探讨了常见JavaScript设计模式及其在Vue.js中的应用。通过具体示例介绍了工厂模式、单例模式和策略模式的应用场景及其实现方法。例如,工厂模式通过`NavFactory`根据用户角色动态创建不同的导航栏组件;单例模式则通过全局事件总线`eventBus`实现跨组件通信;策略模式用于处理不同的表单验证规则。这些设计模式的应用不仅提高了代码的复用性和灵活性,还增强了Vue应用的整体质量。
51 1
|
3月前
|
设计模式 JavaScript 前端开发
小白请看 JS大项目宝典:设计模式 教你如何追到心仪的女神
小白请看 JS大项目宝典:设计模式 教你如何追到心仪的女神
|
4月前
|
设计模式 JavaScript Go
js设计模式【详解】—— 状态模式
js设计模式【详解】—— 状态模式
80 7
|
4月前
|
设计模式 JavaScript
js设计模式【详解】—— 桥接模式
js设计模式【详解】—— 桥接模式
71 6
|
4月前
|
设计模式 JavaScript
js设计模式【详解】—— 原型模式
js设计模式【详解】—— 原型模式
50 6
|
4月前
|
设计模式 JavaScript 前端开发
JavaScript进阶 - JavaScript设计模式
【7月更文挑战第7天】在软件工程中,设计模式是解决常见问题的标准解决方案。JavaScript中的工厂模式用于对象创建,但过度使用可能导致抽象过度和缺乏灵活性。单例模式确保唯一实例,但应注意避免全局状态和过度使用。观察者模式实现了一对多依赖,需警惕性能影响和循环依赖。通过理解模式的优缺点,能提升代码质量。例如,工厂模式通过`createShape`函数动态创建对象;单例模式用闭包保证唯一实例;观察者模式让主题对象通知多个观察者。设计模式的恰当运用能增强代码可维护性。
81 0
|
4月前
|
设计模式 缓存 JavaScript
js设计模式实例
【7月更文挑战第2天】JavaScript设计模式包含工厂、单例、建造者、抽象工厂和代理模式等,它们是最佳实践和可重用模板,解决创建、职责分配和通信等问题。例如,工厂模式封装对象创建,单例确保全局唯一实例,建造者模式用于复杂对象构建,抽象工厂创建相关对象集合,而代理模式则控制对象访问。这些模式提升代码质量、可读性和灵活性,是高效开发的关键。
37 0
|
18天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。