浅浅了解设计模式之二 | 结构型

130 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

image.png 结构型模式:组装现有的类的模式,排列组合类

适配器模式

解决两个接口不兼容的情况,通过再封装,实现两个接口的正常协作

  class Plug {
    constructor() {
      this.name = "zhangsan";
    }
    getName() {
      return this.name;
    }
  }
  class Target {
    constructor() {
      this.plug = new Plug();
    }
    // 对getName进行适配,符合Target的功能
    getName() { 
      return "target:" + this.plug.getName();
    }
  }
  let target = new Target();
  console.log(target.getName()); // target:zhangsan

Vue中父组件传给子组件时间戳,子组件再将这个参数转成时间类,这个过程使用了适配器模式。

桥接模式

把抽象的部分和实现分离开,使它们可以独立变化

  function Chef(dishFun) {
    dishFun();
  }
  function Employee(dishFun) {
    dishFun();
  }
  const dish = {
    cook: () => {
      console.log('做料理');
    },
    eat: () => {
      console.log("吃料理");
    }
  }
  let chef = new Chef(dish.cook);
  let employee = new Employee(dish.eat);
  • 抽象的部分:厨师和员工对料理的行为
  • 实现的部分:dish的两个方法
  • 独立变化:chef和employee对料理都有两种选择

装饰者模式

为现有的对象再(装饰)添加新功能

  function Baby() {
    this.live = () => {
      console.log('活着');
    }
  }
  let baby = new Baby();
  baby.say = () => {
    console.log('说话');
  }
  baby.walk = () => {
    console.log('走路');
  }
  console.log(baby); // Baby {live: ƒ, say: ƒ, walk: ƒ}

组合模式

子元素是叶子,父元素是树节点,同时树节点也可以有父节点,形成一个树结构

  class Father {
    constructor(name) {
      this.name = name;
      this.sons = [];
    }
    add(son) {
      this.sons.push(son);
    }
    print() {
      for (let s in this.sons) {
        s.print();
      }
    }
  }
  class Son {
    constructor(name) {
      this.name = name
    }
    print() {
      console.log(this.name);
    }
  }
  let son1 = new Son('son1');
  let son2 = new Son('son2');
  let son3 = new Son('son3');

  let father1 = new Father('father1');
  let father2 = new Father('father2');

  father1.add(son1);
  father1.add(son2);

  father2.add(father1);
  father2.add(son3);
  console.log(father2);

上面的代码组成一个树结构

image.png

外观模式

为复杂的子系统接口提供一个统一可以简单使用的对外接口

function learn () {
  return {
    htmlLearn() {
      // 好多好多复杂逻辑
    },
    cssLearn() {
      // 好多好多复杂逻辑
    },
    jsLearn() {
      // 好多好多复杂逻辑
    }
  }
}

享元模式

它的目标是以相关对象尽可能多的共享数据,来减少应用程序中内存的使用(例如:应用程序的配置、状态等)

比如:设计模式中的单例模式就有享元概念,只创建为一个对象,如果已经存在了,就不再创建

比如:页面只能存在20个dom元素,页面滚动的时候就复用这20个dom元素,节约内存

代理模式

当想要对一个对象进行操作的时候代价特别大,可以通过其他对象对目标对象进行操作

<body>
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
  </ul>
</body>
<script>
  let ul = document.getElementsByTagName("ul")[0].children;
  for (let index = 0; index < ul.length; index++) {
    ul[index].addEventListener('click', () => {
      console.log(index);
    })
  }
</script>

当需要对每个li元素都进行添加事件,ul就作为中间商为每个li添加事件

比如:项目中去请求数据,第一次请求后,缓存中间商将数据保存起来,当第二次请求时,中间商判断是否有缓存,如果有直接返回

参考:

# JavaScript 设计模式

# 前端技术设计模式相关问题--- 适配器模式

# js设计模式【详解】总目录——最常用的20种设计模式