装飾者パターン設計

7330 ワード

一、デザインモード
javascriptの中には多くのデザインパターンがあります.
工場、橋、組合せ、外観、アダプター、装飾者、享元、代理、観察者、命令、責任チェーン
前に工場モデルと橋モデルを実現しました.
工場モード:
コア:オブジェクトを生産するために、デカップリングを実現する.
ブリッジモード:
(ブリッジモードは、2つのオブジェクトを一緒に接続したり、強いカップリングを避けたりする方法です.橋を通してお互いを結び付けたり、それぞれが独立して変化することもできます.)
主な役割:抽象とそれを分離し、両者が独立するように表現する.
グループモード:
(コンビネーションモードは、Web上の動的なユーザインターフェースを作成するために、特に量的に制定されたモードである.このようなモードを使用すると、複数のオブジェクトに複雑または再帰的な動作を1つのコマンドで励起することができる.これは、結合性コードを簡単にして、維持が容易になり、それらの複雑な動作は、各オブジェクトに委託される.)
利点:
1つは、同じ方法で対象のセットとその中の特定のサブオブジェクトを処理することができます.
2これは、複数のサブオブジェクトを木の形に組織するために使用することができ、木全体を遍歴することができます.
シーン:
1いくつかの階層体系に組織されたオブジェクトがあります.
2これらのオブジェクトまたは一部のオブジェクトに対して動作を実施したい.
特徴:
1グループモードでは、2つのタイプのオブジェクトしかありません.オブジェクト、オブジェクトの組み合わせです.
2この二つのタイプは全部同じインターフェースを実現します.
3私たちは一般的に、グループのオブジェクトでその方法を呼び出して、「下位オブジェクト」を暗黙的に呼び出す方法があります.(ここでは一般的に再帰的な形で行います.)
オープンモード
二つの役割:
1、簡略類のインターフェース
2、キャンセルクラスとそのユーザーコードの間の結合
見栄は常に開発者の一番親しい友達です.それはほとんどすべてのjavascriptライブラリの核心原則です.
外観モデルの目的は開発者がより簡単な方法で比較的複雑または組み合わせの方法を呼び出させるためで、主に開発の複雑さを簡略化し、比較的容易なAPIを提供して内部の方法を外部に使用させることで、プログラマー開発がより楽になります.時間と精力の節約に役立つ.
注意:
間口モードを乱用しないでください.お気に入りの顔を使う前に、よく考えてみてください.よくないと、大袈裟にします.
アダプター設計
1、アダプターモードは、既存のインターフェースと互換性のないクラスの間で適応するために使用されてもよい.このようなパターンを使う対象は包装器とも言われています.彼らはもう一つの対象を新しいインターフェースで包装しています.いくつかの種類がAPIと一致せず、一緒に使用できない場合は、アダプターを介して処理することができる.
2、アダプターと外観は似ていますが、外観モードは一つのインターフェースを簡略化するためだけで、追加の選択を提供するわけではありません.アダプターは一つのインターフェースを別のインターフェースに変換します.一部の能力をフィルタしたり、インターフェースを簡素化したりしません.
装飾者モード
オブジェクトに新しい特性を追加する技術であり、新しいサブクラスを作成するためのこの手段は適用されません.装飾者モードは、元のオブジェクトを同じインターフェースを持つ別のオブジェクトに透明に包装するために使用されてもよい.このようにして、オブジェクトに方法や行動を追加し、方法を元のオブジェクトに呼び出します.
特性:
1、同じインターフェースを実現する2、サブクラスが必要です.
説明は全部コードの中にあります.




       
    


    
    //        
    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 ;
        }
    };
    
    //       :
    /**
          :              ,             
                   
    
      :
    1、       
    2、     
    */
    
    //       
    /**     :
       :(decorator)[              ],
                   。
                [                      ]。
                          ,
                  。
    */
    /**
          
    //  :               !(  )
            
    var ComputerInterface = new LJL.Interface('ComputerInterface',['getPrice','getType']);
          
    var Computer =function(){
        //    
        LJL.Interface.checkMethodsIsPass(this,ComputerInterface);
    };
    //          
    Computer.prototype = {
        constructor : Computer,//     
        getPrice : function(){//     getPrice  
            return 4500;
        },
        getType : function(){//     getType  
            document.write("this is a assamable");
        }
    };
    //  ,          :           ,        ,           ?
    //               ?          ,          ?              ?
    //          
    //                 ,             ,         ,          
    //       ,        
    
    
    //               
    var CpuDecorator = function(computer){//    ,   ?       ,           
        //            
        CpuDecorator.superClass.constructor.call(this,computer);
    };
    //       ,               ?
    ////////////////////////////////////////
    //             :     
    var Computer =function(computer){
        //               (            )
        this.computer = computer;//      
        //    
        LJL.Interface.checkMethodsIsPass(this,ComputerInterface);
    };
    /////////////////////////////////////////////////
    
    //           
    LJL.extends(CpuDecorator,Computer);//       (  :                ,          ) 
    //             
    CpuDecorator.prototype = {
        constructor : CpuDecorator,
        getPrice : function(){
            return this.computer.getPrice()+1000;//            cpu   ,     
        },
        getType : function(){
            document.write("this is a plus a cpu"+"<br/>");
        }
    };
    */
    //           
    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();
    
    
    
    
    
    
    
    
    
    //            ,         
                
    
    //                
    function getDate(){
        return (new Date()).toString();
    };
    
    //      (     )
    function upperCaseDecorator(fn){
        return function(){
            return fn.apply(this, arguments).toUpperCase();
        }
    };
    
    alert(getDate());
    
    var getDecoratorDate = upperCaseDecorator(getDate);
    
    alert(getDecoratorDate());