1

The Decorator Pattern is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.
From http://en.wikipedia.org/wiki/Decorator_pattern

定义

装饰模式力图解决的问题是:过度使用了继承来扩展对象的功能。继承引入的是静态特质,这种扩展方式缺乏灵活性,并且随着子类的增多,各种子类的组合会导致更多的子类膨胀

装饰模式力图动态的给一个对象添加一些额外的职责

装饰模式是类继承的另外一种选择,类继承在编译时候增加行为,而装饰模式是在运行时增加行为。当有几个互相独立的功能需要扩展时,这个区别就变得很重要。

需求

请输入图片描述

简单的用户登陆框,需求是这样的:

  • 固定部分:用户输入部分,用户名输入和密码输入
  • 可选部分:顶部的活动推荐条和底部的广告

需求:根据服务端的数据和类型返回决定显示Banner和Advertisement,做到可以动态的添加和配置

类图

请输入图片描述

角色

  • Component (LoginPanel) 接口定义
  • ConcreteComponent (SimpleLoginPanel) 需要动态添加功能的具体对象
  • Decorator (LoginPanelDecorator) 拥有Component对象,定义一组与Component一致的接口

实现

var prototype = require('prototype');

var LoginPanel = {
  render: function(){
    throw new Error('method must be override!');
  }
};

var SimpleLoginPanel = prototype.Class.create(LoginPanel, {
  render: function(){
    // @todo 渲染基础的LoginPanel,加入用户输入框
    console.log('渲染用户输入框');
  }
});

var LoginPanelDecorator = prototype.Class.create(LoginPanel, {

  initialize: function (panel) {
    this.panel = panel;
  },

  render: function () {
    // @todo 做基础内容的渲染
    this.panel.render();
  }
});

var BannerDecorator = prototype.Class.create(LoginPanelDecorator, {
  render: function ($super) {
    $super();
    this.setBanner();
  },

  setBanner: function () {
    // @todo 渲染添加的活动Banner
    console.log('渲染添加的活动Banner');
  }
});

var AdvertisementDecorator = prototype.Class.create(LoginPanelDecorator, {
  render: function ($super) {
    $super();
    this.setAd();
  },

  setAd: function () {
    // @todo 渲染广告
    console.log('渲染广告');
  }
});

var Main = function () {

  // 声明一个简单的LoginPanel
  var simpleLoginPanel = new SimpleLoginPanel();

  // 加入广告
  var adDecorator = new AdvertisementDecorator(simpleLoginPanel);
  adDecorator.render();

  console.log('--------------------------------')

  // 加入Banner
  var bannerDecorator = new BannerDecorator(adDecorator);
  bannerDecorator.render();

}

Main();

注:继承采用了PrototypeJS提供的Class来做的,使用了Prototype.Node,关于prototype如何使用参考Prototype Doc

参考


leewind
800 声望31 粉丝

顺丰海淘 -- 是我最近在做的项目