裝飾者模式設(shè)計(jì)

一惧互、設(shè)計(jì)模式

javascript里面給我們提供了很多種設(shè)計(jì)模式:

工廠哎媚、橋、組合喊儡、門面拨与、適配器、裝飾者艾猜、享元买喧、代理、觀察者匆赃、命令淤毛、責(zé)任鏈

在前面我們實(shí)現(xiàn)了工廠模式和橋模式

工廠模式 :

核心:為了生產(chǎn)對(duì)象,實(shí)現(xiàn)解耦算柳。

橋接模式 :

(橋接模式是一種既能把兩個(gè)對(duì)象連接在一起低淡,又能避免二者間的強(qiáng)耦合的方法。通過“橋”把彼此聯(lián)系起來,同時(shí)又允許他們各自獨(dú)立變化)

主要作用:主要作用表現(xiàn)為將抽象與其實(shí)現(xiàn)隔離開來蔗蹋,以便二者獨(dú)立化事期。

組合模式 :

(組合模式是一種專門為創(chuàng)建Web上的動(dòng)態(tài)用戶界面而量身制定的模式。使用這種模式可以用一條命令在多個(gè)對(duì)象上激發(fā)復(fù)雜的或遞歸的行為纸颜。這可以簡化粘合性代碼兽泣,使其更容易維護(hù),而那些復(fù)雜行為則被委托給各個(gè)對(duì)象胁孙。)

優(yōu)點(diǎn) :

1 你可以用同樣的方法處理對(duì)象的集合與其中的特定子對(duì)象唠倦。

2 它可以用來把一批子對(duì)象組織成樹形結(jié)構(gòu),并且使整棵樹都可以被遍歷涮较。

場景 :

1 存在一批組織成某種層次體系的對(duì)象

2 希望對(duì)這批對(duì)象或其中的一部分對(duì)象實(shí)施一個(gè)操作稠鼻。

特點(diǎn) :

1 組合模式中只有兩種類型對(duì)象:組合對(duì)象、葉子對(duì)象

2 這兩種類型都實(shí)現(xiàn)同一批接口

3 一般我們會(huì)在組合對(duì)象中調(diào)用其方法并隱式調(diào)用"下級(jí)對(duì)象"的方法(這里我們一般采用遞歸的形式去做)

門面模式

兩個(gè)作用:

1狂票、簡化類的接口

2候齿、消除類與使用它的客戶代碼之間的耦合

門面模式常常是開發(fā)人員最親密的朋友。它幾乎是所有javascript庫的核心原則

門面模式的目的是為了讓開發(fā)人員用更簡單的方法調(diào)用一些相對(duì)復(fù)雜或組合的方法闺属,主要就是簡化開發(fā)的復(fù)雜性慌盯,提供一個(gè)相對(duì)容易的API去調(diào)用內(nèi)部的方法供外界去使用,這樣程序員開發(fā)會(huì)變得輕松些掂器,編寫一次組合代碼后可以反復(fù)的去使用它亚皂,有助于節(jié)省時(shí)間和精力

注意:

不要濫用門面模式,所以使用你心儀的門面之前一定要三思而定国瓮,搞不好你就會(huì)小題大做

適配器設(shè)計(jì)

1灭必、適配器模式可用來在現(xiàn)有的接口和不兼容的類之間進(jìn)行適配。
使用這種模式的對(duì)象又叫做包裝器(wrapper)乃摹,因?yàn)樗麄兪窃谟靡粋€(gè)新的接口包裝另一個(gè)對(duì)象禁漓。
借助適配器可以處理一些類與API不匹配、不能一同使用的情況孵睬。

2播歼、注意適配器和門面雖然比較類似,但是門面模式只是為了簡化一個(gè)接口肪康,
它并不是提供額外的選擇荚恶,適配器則要把一個(gè)接口轉(zhuǎn)換為另一個(gè)接口,
它并不會(huì)濾除某些能力磷支,也不會(huì)簡化接口谒撼。

裝飾者模式

是一種為對(duì)象添加新特性的技術(shù),它并不適用創(chuàng)建新子類的這種手段。裝飾者模式可以用來透明的把原始對(duì)象包裝在具有同樣接口的另一個(gè)對(duì)象之中雾狈。這樣我們就可以為對(duì)象添加一個(gè)方法或者一些行為廓潜,然后將方法調(diào)用傳遞給原始對(duì)象

特性:

1、實(shí)現(xiàn)同樣的接口
2、需要有子類

講解都在代碼中:

<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8" />
<title>裝飾者設(shè)計(jì)模式</title>
    <!-- 
    @theme: javascript高級(jí) 裝飾者設(shè)計(jì)模式
    @autor:EthanCoco
    @date:2015-11-24
    @email:lijianlin0204@163.com
    -->
</head>
<body>
    <script type=text/javascript charset=utf-8>
    //這個(gè)就不繼續(xù)說了
    var LJL = {};
    LJL.Interface = function(name,methods){
        if(arguments.length !== 2){
            throw new Error("the param must have two");
        }
        this.name = name;
        this.methods = [];
        for(var i=0;i<methods.length;i++){
            if(typeof methods[i] !=='string'){
                throw new Error("the type of param must be string");
            }
            this.methods.push(methods[i]);
        }
    };
    LJL.Interface.checkMethodsIsPass = function(object){
        if(arguments.length < 2){
            throw new Error("the checkMethodsIsPass methods must more then 1 param");
        }
        
        for(var i=1;i<arguments.length;i++){
            var instanceInterface = arguments[i];
            if( instanceInterface.constructor !== LJL.Interface){
                throw new Error("the param is not a Interface");
            }
            for(var j=0;j<instanceInterface.methods.length;j++){
                var methodName = instanceInterface.methods[j];
                if(!object[methodName] || typeof object[methodName] !== 'function'){
                    throw new Error("the methods not come pass!")
                }
            
            }
        }
    };
    LJL.extends = function(sub,sup){
        var F = new Function();
        F.prototype = sup.prototype;
        sub.prototype = new F();
        sub.prototype.constructor = sub;
        sub.superClass = sup.prototype;
        if(sup.prototype.constructor == Object.prototype.constructor){
            sup.prototype.constructor = sup ;
        }
    };
    
    //裝飾者設(shè)計(jì)模式:
    /**
    簡單理解就是:在保證不改變?cè)袑?duì)象的基礎(chǔ)上辩蛋,去擴(kuò)展一些想要的方法或需求
    在子類的基礎(chǔ)上要實(shí)現(xiàn)相同的接口
    
    特性:
    1呻畸、實(shí)現(xiàn)同樣的接口
    2、需要有子類
    */
    
    //裝飾者模式示例
    /**裝飾者概念:
    裝飾者:(decorator)[是一種為對(duì)象添加新特性的技術(shù)],
    它并不適用創(chuàng)建新子類的這種手段悼院。
    裝飾者模式可以用來透明的[把原始對(duì)象包裝在具有同樣接口的另一個(gè)對(duì)象之中]伤为。
    這樣我們就可以為對(duì)象添加一個(gè)方法或者一些行為,
    然后將方法調(diào)用傳遞給原始對(duì)象据途。
    */
    /**
    整體思路講解
    //場景:我要獲得電腦的價(jià)格和電腦的類型=视蕖(裸機(jī))
    創(chuàng)建一個(gè)接口對(duì)象
    var ComputerInterface = new LJL.Interface('ComputerInterface',['getPrice','getType']);
    創(chuàng)建一個(gè)對(duì)象
    var Computer =function(){
        //檢驗(yàn)接口
        LJL.Interface.checkMethodsIsPass(this,ComputerInterface);
    };
    //在原型對(duì)象上添加方法
    Computer.prototype = {
        constructor : Computer,//還原構(gòu)造器
        getPrice : function(){//實(shí)現(xiàn)接口的getPrice方法
            return 4500;
        },
        getType : function(){//實(shí)現(xiàn)接口的getType方法
            document.write("this is a assamable");
        }
    };
    //好了,現(xiàn)在我有一個(gè)新的需求:這個(gè)電腦不滿足我的需求颖医,我還要加個(gè)內(nèi)存條位衩,你給我算算一共要多少錢?
    //你難道要在開始的對(duì)象上加價(jià)格么熔萧?這樣就改變了原始對(duì)象糖驴,如果一個(gè)人就要裸機(jī)呢?你難道又要把原始對(duì)象改回來么佛致?
    //這樣做顯然是不合理的
    //為此我們用裝飾者模式來實(shí)現(xiàn)這一功能贮缕,就是我在原始對(duì)象上在套一層,既不影響原始對(duì)象性晌杰,也不影響后加上的對(duì)象
    //兩者都是獨(dú)立的跷睦,但又是存在關(guān)聯(lián)的
    
    
    //創(chuàng)建一個(gè)新的對(duì)象來裝飾原始對(duì)象
    var CpuDecorator = function(computer){//新的對(duì)象,裝飾誰肋演?我們傳一個(gè)參數(shù),表示原始對(duì)象的實(shí)例對(duì)象
        //借用構(gòu)造函數(shù)繼承原始對(duì)象
        CpuDecorator.superClass.constructor.call(this,computer);
    };
    //既然有了個(gè)參數(shù)烂琴,這個(gè)參數(shù)該如何或者說從哪里獲得爹殊?
    ////////////////////////////////////////
    //我們可以給原始對(duì)象一個(gè)屬性:修改成如下
    var Computer =function(computer){
        //這個(gè)屬性就是為了讓子類繼承的 (讓子類 多一個(gè)父類的引用)
        this.computer = computer;//添加一個(gè)屬性
        //檢驗(yàn)接口
        LJL.Interface.checkMethodsIsPass(this,ComputerInterface);
    };
    /////////////////////////////////////////////////
    
    //然后我們用子類繼承父類
    LJL.extends(CpuDecorator,Computer);//原型繼承   (說明:這個(gè)繼承用來實(shí)現(xiàn)同一個(gè)接口的方法,這是裝飾者模式的特性) 
    //在原型對(duì)象上實(shí)現(xiàn)同樣的方法
    CpuDecorator.prototype = {
        constructor : CpuDecorator,
        getPrice : function(){
            return this.computer.getPrice()+1000;//在原有的對(duì)象上的價(jià)格加上cpu的價(jià)格奸绷,得最終價(jià)格
        },
        getType : function(){
            document.write("this is a plus a cpu"+"<br/>");
        }
    };
    */
    //以下為完整實(shí)例以及測試
    var ComputerInterface = new LJL.Interface('ComputerInterface',['getPrice','getType']);
    
    var Computer =function(computer){
        this.computer = computer;
        LJL.Interface.checkMethodsIsPass(this,ComputerInterface);
    };
    Computer.prototype = {
        constructor : Computer,
        getPrice : function(){
            return 4500;
        },
        getType : function(){
            document.write("this is a assamable");
        }
    };
    var CpuDecorator = function(computer){
        CpuDecorator.superClass.constructor.call(this,computer);
    };
    LJL.extends(CpuDecorator,Computer);
    CpuDecorator.prototype = {
        constructor : CpuDecorator,
        getPrice : function(){
            return this.computer.getPrice()+1000;
        },
        getType : function(){
            document.write("this is a plus a cpu"+"<br/>");
        }
    };
    
    var com = new Computer();
    alert(com.getPrice());
    com.getType();
    
    com = new CpuDecorator(com);
    document.write(com.getPrice()+"<br/>");
    com.getType();
    
    
    
    
    
    
    
    
    
    //裝飾者 不僅可以用在類上梗夸, 還可以用在函數(shù)上
                
    
    //返回一個(gè)當(dāng)前時(shí)間的字符串表示形式
    function getDate(){
        return (new Date()).toString();
    };
    
    // 包裝函數(shù) (裝飾者函數(shù))
    function upperCaseDecorator(fn){
        return function(){
            return fn.apply(this, arguments).toUpperCase();
        }
    };
    
    alert(getDate());
    
    var getDecoratorDate = upperCaseDecorator(getDate);
    
    alert(getDecoratorDate());
    
    
    </script>
</body>
</html>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市号醉,隨后出現(xiàn)的幾起案子反症,更是在濱河造成了極大的恐慌,老刑警劉巖畔派,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铅碍,死亡現(xiàn)場離奇詭異,居然都是意外死亡线椰,警方通過查閱死者的電腦和手機(jī)胞谈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人烦绳,你說我怎么就攤上這事卿捎。” “怎么了径密?”我有些...
    開封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵午阵,是天一觀的道長。 經(jīng)常有香客問我享扔,道長趟庄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任伪很,我火速辦了婚禮戚啥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘锉试。我一直安慰自己猫十,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開白布呆盖。 她就那樣靜靜地躺著拖云,像睡著了一般。 火紅的嫁衣襯著肌膚如雪应又。 梳的紋絲不亂的頭發(fā)上宙项,一...
    開封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音株扛,去河邊找鬼尤筐。 笑死,一個(gè)胖子當(dāng)著我的面吹牛洞就,可吹牛的內(nèi)容都是我干的盆繁。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼旬蟋,長吁一口氣:“原來是場噩夢啊……” “哼油昂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起倾贰,我...
    開封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤冕碟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后匆浙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體安寺,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年吞彤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了我衬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叹放。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖挠羔,靈堂內(nèi)的尸體忽然破棺而出井仰,到底是詐尸還是另有隱情,我是刑警寧澤破加,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布俱恶,位于F島的核電站,受9級(jí)特大地震影響范舀,放射性物質(zhì)發(fā)生泄漏合是。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一锭环、第九天 我趴在偏房一處隱蔽的房頂上張望聪全。 院中可真熱鬧,春花似錦辅辩、人聲如沸难礼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛾茉。三九已至,卻和暖如春撩鹿,著一層夾襖步出監(jiān)牢的瞬間谦炬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來泰國打工节沦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留键思,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓散劫,卻偏偏與公主長得像稚机,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子获搏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • 設(shè)計(jì)模式匯總 一、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用失乾、多...
    MinoyJet閱讀 3,922評(píng)論 1 15
  • 1 場景問題# 1.1 復(fù)雜的獎(jiǎng)金計(jì)算## 考慮這樣一個(gè)實(shí)際應(yīng)用:就是如何實(shí)現(xiàn)靈活的獎(jiǎng)金計(jì)算常熙。 獎(jiǎng)金計(jì)算是相對(duì)復(fù)雜...
    七寸知架構(gòu)閱讀 3,979評(píng)論 4 67
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)碱茁,斷路器裸卫,智...
    卡卡羅2017閱讀 134,637評(píng)論 18 139
  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 10,934評(píng)論 6 13
  • 今晚米其林一星餐廳Caviar Russe,看名字就知道纽竣,主打魚子醬墓贿。目前為止茧泪,已感覺紐約高檔餐廳比其它很多地方都...
    春來花開心亦安閱讀 918評(píng)論 1 0