[設計モード-🏗👷 作成]🏭 Factory Method Pattern


🏗👷 アレイの作成


🏭 Factory Method Pattern


ファクトリメソッドモード(Factory Method Pattern)は、上位クラスで未知のクラスを生成するモードです。


サブクラスが作成するオブジェクトを決定するモードでもあります。また、親コードに特定のクラス名を隠す方法としても使用できます。



工場は工場という意味です.したがって,工場メソッドモデルは,あるもののための工場と見なすこともできる.
工場の方法パターンを理解するために、まず以下とコードのような靴屋の例を見ます.
// 이름을 통해 신발을 주문 받음
Shoes orderShoes(String name) {
    // 해당 이름의 신발을 찾아서 특정 구상 객체 생성
    Shoes shoes;
    
    if (name.equals("blackShoes"))     shoes = new BlackShoes();
    else if (name.equals("brownShoes"))shoes = new BrownShoes();
    else if (name.equals("redShoes"))  shoes = new RedShoes();
    
    // 신발을 준비하고 포장하는 메소드
    // 모든 신발 공용 메소드
    shoes.prepare(); 
    shoes.packing(); 
 
    return shoes;
}
今、この靴屋では靴が3足しか売っていません.また、将来販売される製品が増加するか、現在の製品が販売されなくなる可能性があります.この部分はいつも変更できます.
しかし、次のprepare()とpacking()の2つの方法は、製品が変化しても変わらない部分です.
上記のコードをShoesFactoryというクラスにカプセル化します.
ShoesFactory.java
public class ShoesFactory {
 
    public Shoes makeShoes(String name) {
 
       Shoes shoes = null;
       if (name.equals("blackShoes"))     shoes = new BlackShoes();
       else if (name.equals("brownShoes"))shoes = new BrownShoes();
       else if (name.equals("redShoes"))  shoes = new RedShoes();
       
       return shoes;
    }
 
}
上のコードを作ることができます.なお、使用は以下のようにすることができる.
ShoesStore.java
public class ShoesStore {
     
    ShoesFactory factory;
 
    public ShoesStore(ShoesFactory factory) {
        this.factory = factory;
    }
   
    Shoes orderShoes(String name) {
        Shoes shoes = factory.makeShoes(name);
        shoes.prepare(); 
        shoes.packing(); 
 
        return shoes;
    }
}
お客様に特定の靴を注文する場合、売り場では工場にその靴を入れて注文することができ、販売する靴が増えたり生産を停止したりすれば、靴屋ではなく靴工場で変化を処理することができます.
上記のサンプルコードは、設計モードに及ばず、プログラミングに用いられる慣用的な古いビューと見なすことができる.
では、工場の方法モデルを見てみましょう.
上に見える新盤売り場は徐々に成長し、他の国に進出し始めた.日本とフランスに進出し、売り場を作った.
   JapanShoesStore jpStore= new JapanShoeStore (new JapanShoesFactory());
   jpStore.order("blackShoes");
    
   FranceShoesStore  frStore = new FranceShoesStore (new FranceShoesFactory());
   frStore.order("blackShoes");
しかし、これらの海外の売り場は本社の指導方針通りに作られていない.現地の状況に応じて、日本ではヒールを少し高くし、フランスでは靴のそばに図案を入れ始めた.
それだけでなく、包装も勝手にしました.
そこで、当社は以下のフレームワークを制定し、売り場全体と靴の生産過程を縛り、すべての売り場がこれらのフレームワークに従うことができるようにしました.
ShoesStore.java
   public abstract class ShoesStore {
 
    public ShoesStore orderShoes(String name) {
        Shoes shoes = makeShoes(name);
        shoes.prepare();
        shoes.packing();
 
        return shoes;
 
    }
 
    abstract Shoes makeShoes(String name);
 
}
ShoesStore抽象レベルを宣言すると、変化する部分は抽象的な方法の靴しか作らない.
現地の状況に応じてmakeshoesの方法を誇張し、日本ではヒールを少し高くし、フランスでは図案を加えて靴を作ればいい.
しかし、制作、準備、包装の流れはShoesStoreを引き継ぐ全世界のすべての売り場で同じシステムを適用することができる.
JapanShoesStore.java
class JapanShoesStore extends ShoesStore {
 
    @Override
    Shoes makeShoes(String name) {
        if (name.equals("blackShoes")) return new JPStyleBlackShoes();  
        else if (name.equals("brownShoes")) return new JPStyleBrownShoes();
        else if (name.equals("redShoes")) return new JPStyleRedShoes();
        else return null;
   }

}
FranceShoesStore.java
class FranceShoesStore extends ShoesStore {
 
    @Override
    Shoes makeShoes(String name) {
        if (name.equals("blackShoes")) return new FRStyleBlackShoes();  
        else if (name.equals("brownShoes")) return new FRStyleBrownShoes();
        else if (name.equals("redShoes")) return new FRStyleRedShoes();
        else return null;
   }

}
ここで最も重要なのは、サブクラスでメソッドが上書きされているため、スーパークラスでのorderShoesメソッドではどのような靴が作られるのか全く分からないことです.
ダイナミックバインドのその方法で与えられた靴を受け入れるだけで、準備と包装ができます.

靴類



生産者クラスで生産される製品クラス


工場メソッドモデルのクラスは,生産者クラスと製品クラスに大別できる.
次に、生産者クラスShoesStoreクラスに使用される製品クラスShowクラスを作成します.
Shoes.java
abstract class Shoes {
 
    String name;
    String bottom;
    String leather;
    boolean hasPattern;
 
    void prepare() {
        System.out.println("주문하신 신발을 준비중입니다.");
    }
 
    void packing() {
        System.out.println("준비 완료된 신발을 포장중입니다.");
    }
 
    public String getName() {
        return name;
    }
 
}
JPStyleBlackShoes.java
class JPStyleBlackShoes extends Shoes {
 
    public JPStyleBlackShoes() { 
        name = "일본 스타일의 검은 구두";
        bottom = "굽이 높은 밑창";
        leather = "스웨이드";
        hasPattern = false;
    }
 
}
FRStyleBlackShoes.java
class FRStyleBlackShoes extends Shoes {
 
    public FRStyleBlackShoes() { 
        name = "프랑스 스타일의 검은 구두";
        bottom = "일반 굽높이 밑창";
        leather = "스웨이드";
        hasPattern = true;
    }
 
}
抽象クラスでShowクラスを設計し、JPSTyleBlackShow、FRStyleBlackShowでメンバー変数を初期化して実現します.
抽象的な方法のない抽象クラスがここに登場する.
showクラスには抽象メソッドは存在しないが、抽象クラスとして宣言されているため、new shows()直接作成オブジェクトを使用できません.
Showクラスを継承するクラスでは、Showを参照変数としてオブジェクトを作成できます.
抽象メソッド存在O->無条件クラスも抽象クラスとして宣言
抽象メソッド存在X->現在のクラスへの直接オブジェクトの作成をブロックする場合は抽象クラスとして宣言
これまでUMLで設計されたクラスの実装は完了していた.
次に、上記の設計したファクトリメソッドモデルをメインクラスでどのように使用するかを見てみましょう.
Main.java
public class Main {
 
    public static void main(String[] args) {
        
        // 일본과 프랑스에 현지 트렌드에 맞춰 매장을 열었음
        ShoesStore jpStore = new JapanShoesStore();
        ShoesStore frStore = new FranceShoesStore();
      
        // 일본 매장에서 검은 신발 주문
        Shoes shoes = jpStore.orderShoes("blackShoes");
        System.out.println("일본 매장에서 주문한 검은 신발 : " + shoes.getName());
        
        System.out.println();
        
        // 프랑스 매장에서 검은 신발 주문
        shoes = frStore.orderShoes("blackShoes");
        System.out.println("프랑스 매장에서 주문한 검은 신발  : " + shoes.getName());
 
    }
 
}

위 코드를 실행해보면 아래와 같이 출력될 것이다.

```text
> 주문하신 신발을 준비중입니다.
> 준비 완료된 신발을 포장중입니다.
> 일본 매장에서 주문한 검은 신발 : 일본 스타일의 검은 구두
> 
> 주문하신 신발을 준비중입니다.
> 준비 완료된 신발을 포장중입니다.
> 프랑스 매장에서 주문한 검은 신발 : 프랑스 스타일의 검은 구두
上記の主な方法の過程を以下に示す.参考までに、日本の売り場とフランスの売り場の流れは同じなので、共通の流れで説明します.
  • 地元の靴屋がオープンしました.(ShoesStoreを参照変数とするローカルShoesStoreオブジェクトを作成)
  • 売場で靴の種類で靴を注文.(ShoesStoreのorderShoesメソッド)
  • ShoesStoreにおいて、OrderShowで作成するオブジェクトに対して動的バインドおよびオーバーライドを実行するmakeShowメソッド
  • .
  • で上書きされたmakeShowメソッドから注文の靴オブジェクトを返すorderShowメソッド
  • prepare()、packing()メソッドが
  • 実行されました.
    作成、準備、パッケージングが完了したShowオブジェクト
  • を返します.
    出力
  • 注文した靴が何の対象なのか、確認
  • 最後に,生成対象の部分をサブクラスに委任するファクトリメソッドモデルを再びまとめた.
    親クラスShoesStoreクラス内には、newキーワードを呼び出す部分が子クラスに委任されているため、newというキーワードは存在しません.
    すなわち、親ではなく子にどのクラスを作成するかをユーザーに決定させる.
    サブクラスでは抽象メソッドmakeshowesメソッドを使用しているので、親クラスでのordershowesメソッドではどのような靴が作られるか全く分かりません.
    私はダイナミックバインドの靴を受け取っただけで、準備ができていて、梱包して提出します.
    対象向けのプログラム設計の世界では、子供は親を理解し、親は子供を理解していない.