【JavaScript設計モード】作成型設計モード:単純工場、工場方法、抽象工場

5471 ワード

タイトルに作成型設計モードが記載されている以上、まず作成型設計モードとは何かを説明します.作成型設計モードは、オブジェクトの作成を処理する設計モードであり、基本オブジェクトの作成時に設計上の問題が発生したり、設計上の複雑さが増大したりすることを回避するために、オブジェクトの作成を何らかの方法で制御します.--張栄銘の【JavaScriptデザインモード】から引用
あるブログでは、ブロガーが工場モデルを書くために、文章の中で簡単な質問の陳述を始めました.次は私もこの話を書きます.
テキスト「一つの場面を想像してみてください.もしあなたが何かを買いに行くことを要求したら、鶏の足のハンバーガー、コーラ、ポテトチップスを焼くと、人々はとても自然にマクドナルドに行って買いますよね.どうして私たちはマクドナルドに行きたいのですか.これらのものはすべて食べ物で、麦は「工場」として、消費者に提供することができます.マクドナルドがなければ、コーラ、ポテトチップス、鶏の足を焼く必要があります.ハンバーガーの店でこれらの食べ物を別々に買うと、購入効率が低くなります.マクドナルドは食べ物を販売する工場モデルと言える」と話した.
ファクトリモードには、単純ファクトリモード、ファクトリメソッドモード、抽象ファクトリモードの3種類の実装方式もあります.それらはそれぞれそれぞれの基礎の上で一定の改善があります.この3つのパターンの説明を見てみましょう.
1、単純工場モデル
単純ファクトリモードは、どのクラスのインスタンスを作成するかを決定する方法ですが、これらのインスタンスは常に同じインタフェースを持っています.このモードは,主にインスタンス化されたタイプがコンパイル期間では決定されず,実行期間で決定される場合に用いられる.オブジェクトの作成とオブジェクトの使用を分離するだけなので、新しい製品が追加されると、単純なファクトリでのオブジェクトの作成方法を変更する必要があります.このように、変更の閉鎖、拡張の開放の原則を遵守していません.だからこのモードの抽象と分離はまだ徹底していない.一般的に言えば、会社のお茶の間の飲み物機のように、コーヒーにしますか、牛乳にしますか.どのボタンを押すかによって決まります.
例えば、スポーツ用品店があります.中にはスポーツ器材がたくさん売っています.スポーツ用品店にバスケットボールを買いに行くとき、店員に聞くだけで、バスケットボールを見つけてくれます.もし今度バドミントンを買うなら、店員にバドミントンを買うように伝えるだけで、どうやって実現しますか?
var Basketball = function(){
    this.name = 'Basketball';
}
Basketball.prototype = {
    getIntro : function (){
        console.log("This is Basketball ……");
    },
    getPrice : function (){
        console.log("The price of Basketball is $60");
    }
}

var Football = function(){
    this.name = 'Football';
}
Football.prototype = {
    getIntro : function (){
        console.log("This is Football ……");
    },
    getPrice : function (){
        console.log("The price of Football is $60");
    }
}

var Tennis = function(){
    this.name = 'Tennis';
}
Tennis.prototype = {
    getIntro : function (){
        console.log("This is Tennis ……");
    },
    getPrice : function (){
        console.log("The price of Tennis is $60");
    }
}

var SportsFactory = function(name){
    switch(name){
        case 'NBA':
            return new Basketball();
            break;
        case 'wordCup':
            return new Football();
            break;
        case 'FrenchOpen':
            return new Tennis();
            break;
    }
}

次に、次のテストを行います.
var tennis = SportsFactory("FrenchOpen");
console.log(tennis);
console.log(tennis.name);
tennis.getPrice();
出力結果:
{ name: 'Tennis' } Tennis The price of Tennis is $60
2、工場方法モード
ファクトリメソッドモデルは「ファクトリ」概念を実現するオブジェクト向け設計モデルである.実質的には、オブジェクトを作成するインタフェースを定義しますが、このインタフェースを実装するクラスに、どのクラスをインスタンス化するかを決定させます.ファクトリメソッドはクラスのインスタンス化をサブクラスに遅らせる.オブジェクトを作成するには、複雑なプロセスが必要になることが多いため、複雑なオブジェクトには適していません.オブジェクトを作成すると、コードが大量に重複したり、十分なレベルの抽象が提供されない可能性があります.ファクトリメソッドモードは、オブジェクトを個別に作成する方法を定義することによってこれらの問題を解決し、サブクラスによってこの方法を実装して特定のタイプのオブジェクトを作成します.
単純な工場モデルに基づいて、入口が統一されていない問題を解決しましたが、もう一つの問題が解決されていません.
新しいクラスに追加するには、複数の部分を修正する必要があります.まず、SportsFactory工場の内部に実装方法を追加し、switch部分に追加する必要があります.だからこれは修正の需要で、私たちは多くの場所を修正する必要があります.では、もっと抽象的に試して、できるだけ修正が必要な場所を減らすことができるかどうかを見てみましょう.
var SportsFactory = function(type,content){
    this.name = content.name; //         
    return this[type](content);
};

SportsFactory.prototype = {
    football:function(content){
        console.log("     football       " +this.name);
    },
    basketball:function(content) {
        console.log("     basketball       " +this.name);
    }
};
var football = new SportsFactory("football",{name:"football"}); //football in the prototype
だからここにreturn this[type](content)が入っています.の方法は以前のswitchの方法に自動的に代わった.後でコンテンツを追加する必要があるのは修正だけです
SportsFactoryのprototypeでいいです.
安全のために、セキュリティモードクラスを採用する必要がありますが、このモードは、コンストラクション関数の前にnewを付けないと、エラーが発生する問題を解決するために使用されます.解決策はnewを構造関数にカプセル化することです.
var SportsFactory = function(type,content){
    if(!(this instanceof SportsFactory)){
        return new SportsFactory(type,content); //      :     new,     new      ;
    }
    this.name = content.name;
    return this[type](content);
};
SportsFactory.prototype = {
    football:function(content){
        console.log("     football       " +this.name);
    },
    basketball:function(content) {
        console.log("     basketball       " +this.name);
    }
};
var football = SportsFactory("football",{name:"football"}); //      new      ;
まとめ:我々は単純な工場モデルを用いて入口が統一されていない問題を解決し、その後、工場モデルを用いて修正場所が統一されていない問題を解決した.
3、抽象工場モデル
抽象ファクトリは、関連オブジェクトまたは相互依存オブジェクトのセットを作成するために使用されるファクトリモデルのアップグレード版です.前節では、ファクトリ・モード、クラスの作成はファクトリ・クラスに依存し、プログラムが拡張する必要がある場合は、新しいファクトリ・クラスを作成する必要があります.工場類は製品を生産するために使われているので、私たちも「工場類を私たちが生産する製品と見なす」ことができるので、抽象的な工場は「工場の工場」、つまり工場を生産する工場です.
var Ball = function(){};
Ball.prototype = {
    getPrice:function(){ throw new Error("        ")},
    getSpeed:function(){ throw new Error("        ")}
};
//    Object.create()  ,                Temp(){};      prototype    ;      
var basketball= Object.create(Ball.prototype);
    
basketball.getPrice();  //         
basketball.getPrice = function(){
    console.log("I am getting price");
};
basketball.getPrice(); //I am getting price

抽象ファクトリモデルはファクトリメソッドモデルの利点に加えて,クラスの内部で製品ファミリーを制約できることが最も主要な利点である.プロダクトファミリーとは、一般的には多かれ少なかれ関連がある(例えば、異なるメーカーがCPUを生産する).
4、まとめ
単純な工場モデルは入口の不統一の問題を解決し、工場モデルは修正場所の不統一の問題を解決し、抽象的な工場モデルはサブクラスの実現の不規範の問題を解決した.