《JavaScript应用程序设计》一一3.6 享元模式

本节书摘来华章计算机出版社《JavaScript应用程序设计》一书中的第3章,第3.6节,作者:Eric Elliott 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

3.6 享元模式

比起为每个实例分别创建一组实例数据,享元模式通过将可重复使用的方法与属性保存在一个代理对象中,从而节省了系统资源。特别是当应用中存在大量类型相同的实例时,使用享元模式可以明显提升系统性能并有效减少内存损耗。
在其他语言中,你需要额外的步骤来配置享元模式,比如说首先创建一个代理对象,再将所有方法链接至该对象上做延后执行。在JavaScript中,代理原型是一种天然的内建代理对象,所以你不用自己再花费精力实现一个享元模式。
假设你正在编写一个视频游戏,在游戏中会有成百上千个“敌人”对象,每一个“敌人”对象封装着诸如力量、速度、攻击、防御等一组通用属性与方法,同时包含了当前敌人的位置信息与生命值。在JavaScript中,你可以将这些属性与方法放在对象的原型上维护,让位置信息与生命值的变更仅作用在实例层面,而让所有通用属性与方法的变更作用在原型层面。

var enemyPrototype = {
    name: 'Wolf',
    position: { // Override this with setPosition
      x: 0,
      y: 0
    },
    setPosition: function setPosition (x, y) {
      this.position = {
        x: x,
        y: y
      };
      return this;
    },
    health: 20, // Overrides automatically on change
    bite: function bite() {
    },
    evade: function evade() {
    }
  },

  spawnEnemy = function () {
    return Object.create(enemyPrototype);
  };

test('Flyweight pattern.', function () {
  var wolf1 = spawnEnemy(),
    wolf2 = spawnEnemy();

  wolf1.health = 5;
  ok(wolf2.health = 20,
    'Primitives override automatically.');

  ok(wolf1.setPosition(10, 10)
      .position.x === 10, 'Object override works.');
  equal(wolf2.position.x, 0,
      'The prototype should remain unchanged.');
});

JavaScript天生就具备在原型上存放数据的能力,所以从理论上来说,对象的所有方法都适用于享元模式,所以你会看到类似这样的代码:

MyConstructor.prototype.myMethod = function () {
  // A method to be shared...
};

将实例级别的数据存放在原型上较为少见,一些复用性较强的默认属性值比较适合放在原型上做托管。为了避免在修改实例数据时出现安全性问题,在对数组与对象这类引用类属性操作时,需格外小心,尽量对它们做替换,而不是修改。

    原文作者:javascript设计模式
    原文地址: https://yq.aliyun.com/articles/108026
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞