こんにちは!今日も皆さんと一緒にデザインパターンを勉強していきます。この講義ではファクトリーについて話します。このテンプレートを使用してどのような問題が解決されるかについて説明し、工場がコーヒー ショップのオープンにどのように役立つかの例を見ていきます。また、工場を作成するための 5 つの簡単な手順も説明します。 全員と同じ認識を持ち、本質を簡単に理解するには、次のトピックに精通している必要があります。
- Java での継承
- Java での参照型の縮小と拡張
- 異なるクラスとオブジェクト間の相互作用
工場とは何ですか?
Factory デザイン パターンを使用すると、オブジェクトの作成を制御できます。新しいオブジェクトを作成するプロセスはそれほど単純ではありませんが、それほど複雑でもありません。新しいオブジェクトを作成するには、 を使用する必要があることは誰もが知っていますnew
。ここでは管理できるものが何もないように見えるかもしれませんが、そうではありません。アプリケーションに多数の子孫を持つ特定のクラスがあり、条件によっては特定のクラスのインスタンスを作成する必要がある場合、問題が発生する可能性があります。 ファクトリは、条件に応じて異なるオブジェクトを作成するという問題の解決に役立つデザイン パターンです。抽象的ですね。以下の例を見ると、より具体的で明確になります。
さまざまな種類のコーヒーを作っています
コーヒーショップを自動化したいとします。私たちはさまざまな種類のコーヒーの作り方を学ぶ必要があります。これを行うために、アプリケーションでコーヒー クラスとその派生品、つまりアメリカーノ、カプチーノ、エスプレッソ、ラテ - 準備する種類のコーヒーを作成します。一般的なコーヒーのクラスから始めましょう。public class Coffee {
public void grindCoffee(){
// перемалываем кофе
}
public void makeCoffee(){
// делаем кофе
}
public void pourIntoCup(){
// наливаем в чашку
}
}
次に、その継承者を作成しましょう。
public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
顧客はある種のコーヒーを注文するため、この情報をプログラムに渡す必要があります。これは、たとえば を使用するなど、さまざまな方法で行うことができますString
。しかし、これらの目的にはこれが最適ですenum
。enum
その中で、注文を受け付けるコーヒーの種類を 作成して定義しましょう。
public enum CoffeeType {
ESPRESSO,
AMERICANO,
CAFFE_LATTE,
CAPPUCCINO
}
わかりました。コーヒー ショップのコードを書いてみましょう。
public class CoffeeShop {
public Coffee orderCoffee(CoffeeType type) {
Coffee coffee = null;
switch (type) {
case AMERICANO:
coffee = new Americano();
break;
case ESPRESSO:
coffee = new Espresso();
break;
case CAPPUCCINO:
coffee = new Cappucсino();
break;
case CAFFE_LATTE:
coffee = new CaffeLatte();
break;
}
coffee.grindCoffee();
coffee.makeCoffee();
coffee.pourIntoCup();
System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
return coffee;
}
}
この方法はorderCoffee
2 つのコンポーネントに分けることができます。
- ブロック内に特定のコーヒー インスタンスを作成します
switch-case
。ここで、ファクトリーは条件に応じて特定のタイプを作成します。 - 準備自体は、粉砕し、調理し、カップに注ぐだけです。
- 準備アルゴリズム自体 (挽き、調理し、カップに注ぐ) は変更されません (少なくとも私たちはそう願っています)。
- ただし、コーヒーの種類は変更される可能性があります。もしかしたら、モカを作り始めようかな…モカ…モカチ…新しいタイプのコーヒー、彼に神のご加護を。
switch-case
。私たちのコーヒーショップでは、この方法orderCoffee
だけがさまざまな種類のコーヒーを作るわけではない可能性もあります。したがって、いくつかの場所で変更を加える必要があります。おそらくあなたは私が何を言いたいのかすでに理解しているでしょう。リファクタリングする必要があります。コーヒーの作成を担当するブロックを別のクラスに移動する理由は次の 2 つです。
- コーヒーを作成するロジックを他の場所で再利用できるようになります。
- 範囲が変更された場合、コーヒー作成が使用されるすべての場所でコードを編集する必要はありません。コードを 1 か所だけ変更するだけで十分です。
私たちは最初の工場を製材しています
これを行うには、コーヒー クラスの必要なインスタンスの作成のみを担当する新しいクラスを作成しましょう。public class SimpleCoffeeFactory {
public Coffee createCoffee (CoffeeType type) {
Coffee coffee = null;
switch (type) {
case AMERICANO:
coffee = new Americano();
break;
case ESPRESSO:
coffee = new Espresso();
break;
case CAPPUCCINO:
coffee = new Cappucino();
break;
case CAFFE_LATTE:
coffee = new CaffeLatte();
break;
}
return coffee;
}
}
おめでとう!Factory デザイン パターンを最も単純な形で実装しました。ただし、メソッドをcreateCoffee
静的にすれば、すべてがさらに単純になる可能性があります。しかし、そうなると次の 2 つの可能性が失われます。
- を継承し
SimpleCoffeeFactory
てオーバーライドしますcreateCoffee
。 - 必要なファクトリ実装をクラスに実装します。
コーヒーショップに工場を導入
ファクトリを使用してコーヒー ショップ クラスを書き直してみましょう。public class CoffeeShop {
private final SimpleCoffeeFactory coffeeFactory;
public CoffeeShop(SimpleCoffeeFactory coffeeFactory) {
this.coffeeFactory = coffeeFactory;
}
public Coffee orderCoffee(CoffeeType type) {
Coffee coffee = coffeeFactory.createCoffee(type);
coffee.grindCoffee();
coffee.makeCoffee();
coffee.pourIntoCup();
System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
return coffee;
}
}
素晴らしい。ここで、Factory デザイン パターンの構造を図式的かつ簡潔に説明してみましょう。
自分の工場を開くための 5 つのステップ
ステップ 1. 以下の図に示すように、プログラム内に複数の子孫を持つクラスがあります。 ステップ 2.各子孫クラスの enum 変数を定義する クラスを作成します。enum
enum CatType {
LION,
TIGER,
BARSIK
}
ステップ 3. 工場を構築します。これを と呼びますMyClassFactory
。コードは以下のとおりです。
class CatFactory {}
createMyClass
ステップ 4.変数 - を受け取る メソッドをファクトリ内に作成しますenum
MyClassType
。以下のコード:
class CatFactory {
public Cat createCat(CatType type) {
}
}
ステップ 5. メソッドの本体にブロックを記述し、すべての列挙値を反復処理し、値 switch-case
に対応するクラスのインスタンスを作成します。enum
class CatFactory {
public Cat createCat(CatType type) {
Cat cat = null;
switch (type) {
case LION:
cat = new Barsik();
break;
case TIGER:
cat = new Tiger();
break;
case BARSIK:
cat = new Lion();
break;
}
return cat;
}
}
偉ぶって。
GO TO FULL VERSION