[設計模式][裝飾模式][Javascript]

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_patternjavascript

定義

裝飾模式力圖解決的問題是:過分使用了繼承來擴展對象的功能。繼承引入的是靜態特質,這種擴展方式缺少靈活性,而且隨着子類的增多,各類子類的組合會致使更多的子類膨脹html

裝飾模式力圖動態的給一個對象添加一些額外的職責java

裝飾模式是類繼承的另一種選擇,類繼承在編譯時候增長行爲,而裝飾模式是在運行時增長行爲。當有幾個互相獨立的功能須要擴展時,這個區別就變得很重要。node

需求

請輸入圖片描述

簡單的用戶登錄框,需求是這樣的:git

  • 固定部分:用戶輸入部分,用戶名輸入和密碼輸入
  • 可選部分:頂部的活動推薦條和底部的廣告

需求:根據服務端的數據和類型返回決定顯示Banner和Advertisement,作到能夠動態的添加和配置github

類圖

請輸入圖片描述

角色

  • 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 Docsegmentfault

參考

相關文章
相關標籤/搜索