继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

中介者模式

为爱心太软
关注TA
已关注
手记 151
粉丝 1.4万
获赞 860

中介者模式

解除对象与对象之间的紧耦合关系,就叫做中介者模式。

使用场景

比如我们要做一个购买手机的页面,正常的购买流程是:选择了储存容量和套餐类型之后,才会展示手机价格。

例子:

<label>储存容量:</label>
<select id="setStorage">
  <option value="-">——</option>
  <option value="8+128">8+128G</option>
  <option value="8+256">8+256G</option>
</select>
<br />
<label>套餐类型:</label>
<select id="setMeal">
  <option value="-">——</option>
  <option value="normal">官方标配</option>
  <option value="one">套餐一</option>
</select>
<br />
<br />
<span style="color: red;"></span>
<p>价格:<strong></strong></p>

<script>
  /**
    * 8+128G 官方标配 2999
    * 8+128G 套餐一 3199
    * 8+256G 官方标配 3999
    * 8+256G 套餐一 4199
    */
  const telephones = [
    { storageType: '8+128', mealType: 'normal', price: '2999' },
    { storageType: '8+128', mealType: 'one', price: '3199' },
    { storageType: '8+256', mealType: 'normal', price: '3999' },
    { storageType: '8+256', mealType: 'one', price: '4199' },
  ];

  const storage = document.querySelector('#setStorage');
  const meal = document.querySelector('#setMeal');
  const message = document.querySelector('span');
  const price = document.querySelector('strong');

  // 监听‘储存容量’事件处理程序
  storage.addEventListener('change', () => {
    const storageValue = storage.value;
    const mealValue = meal.value;

    if (storageValue === '-') {
      message.innerHTML = '请选择储存容量!';
      price.innerHTML = '';
      return false;
    }

    if (mealValue === '-') {
      message.innerHTML = '请选择套餐类型!';
      price.innerHTML = '';
      return false;
    }

    const _arr = telephones
      .filter((item) => {
        return item.storageType === storageValue;
      })
      .filter((item) => {
        return item.mealType === mealValue;
      });
    message.innerHTML = '';
    price.innerHTML = _arr[0]['price'];
  });

  // 监听‘套餐类型’事件处理程序
  meal.addEventListener('change', () => {
    const storageValue = storage.value;
    const mealValue = meal.value;

    if (storageValue === '-') {
      message.innerHTML = '请选择储存容量!';
      price.innerHTML = '';
      return false;
    }

    if (mealValue === '-') {
      message.innerHTML = '请选择套餐类型!';
      price.innerHTML = '';
      return false;
    }

    const _arr = telephones
      .filter((item) => {
        return item.storageType === storageValue;
      })
      .filter((item) => {
        return item.mealType === mealValue;
      });
    message.innerHTML = '';
    price.innerHTML = _arr[0]['price'];
  });
</script>

上面的例子中,尽管我们实现了功能,但是两个下拉框的联系很密切,试想,如果此时又增加了一个下拉框,代表手机的颜色,那么原有的两个事件处理程序,都要面临修改。
此时,就比较适合引入中介者模式,让两个下拉框解耦,而它们的依赖关系交由中介者去维护。

例子:

<label>储存容量:</label>
<select id="setStorage">
  <option value="-">——</option>
  <option value="8+128">8+128G</option>
  <option value="8+256">8+256G</option>
</select>
<br />
<label>套餐类型:</label>
<select id="setMeal">
  <option value="-">——</option>
  <option value="normal">官方标配</option>
  <option value="one">套餐一</option>
</select>
<br />
<br />
<span style="color: red;"></span>
<p>价格:<strong></strong></p>

<script>
  /**
    * 8+128G 官方标配 2999
    * 8+128G 套餐一 3199
    * 8+256G 官方标配 3999
    * 8+256G 套餐一 4199
    */
  const telephones = [
    { storageType: '8+128', mealType: 'normal', price: '2999' },
    { storageType: '8+128', mealType: 'one', price: '3199' },
    { storageType: '8+256', mealType: 'normal', price: '3999' },
    { storageType: '8+256', mealType: 'one', price: '4199' },
  ];

  const storage = document.querySelector('#setStorage');
  const meal = document.querySelector('#setMeal');
  const message = document.querySelector('span');
  const price = document.querySelector('strong');

  const Mediator = (() => {
    const changed = () => {
      const storageValue = storage.value;
      const mealValue = meal.value;

      if (storageValue === '-') {
        message.innerHTML = '请选择储存容量!';
        price.innerHTML = '';
        return false;
      }

      if (mealValue === '-') {
        message.innerHTML = '请选择套餐类型!';
        price.innerHTML = '';
        return false;
      }

      const _arr = telephones
        .filter((item) => {
          return item.storageType === storageValue;
        })
        .filter((item) => {
          return item.mealType === mealValue;
        });
      message.innerHTML = '';
      price.innerHTML = _arr[0]['price'];
    };

    return { changed };
  })();

  // 监听‘储存容量’事件处理程序
  storage.addEventListener('change', () => {
    Mediator.changed();
  });

  // 监听‘套餐类型’事件处理程序
  meal.addEventListener('change', () => {
    Mediator.changed();
  });
</script>

重构后的代码,无论是新增下拉框还是修改下拉框,我们仅仅需要改动中介者方法里的代码即可。


如有错误,欢迎指正,本人不胜感激。

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP