工場モード--これを見れば十分です
10905 ワード
最近、会社の業務ニーズに合わせて、普段開発で基本的に使われている基礎業務モジュールをパッケージ化し、その中で最も多く使われているのが各工場モデルであると同時に、この機会に工場モデルを復習しました.この文章では、各工場モデルの長所と短所を詳しく紹介します.以下の3つの例を完全に理解できれば、工場モデルは言うまでもありません.ビジネス・コードは公開できないため、本明細書で使用するインスタンスは他の例で置き換えられます.Javaには23種類の設計モデルがあり、工場モデルは3種類あることを知っています.それらはそれぞれ単純な工場モデル(23中モデルではありません)、工場方法モデル、抽象的な工場モデルです.その中で、私たちが一般的に言っている工場モデルは工場方法モデルで、工場方法モデルは日常開発で最も使用頻度の高い設計モデルです.Androidのソースコードでも随所に見られます.以下では,学習の難易度に応じて,この3つのモードを浅く深く述べると,各モードはまず定義,使用シーン,インスタンスの3つの面から着手する.多くの友达はすべて学习の时に感じて理解したと言って、実例も见てわかることができて、しかし実际の开発の中で运用することができなくて、これはその使用シーンを覚えていないため、各位の友达はきっと実例を结び付けて使用シーンを覚えて、このようにやっと开発の中で融通がきく効果を达成することができます.これも設計モードが思想だけで、固定的なコードがないことを説明しています!まず一番簡単なものを見てみましょう.
単純ファクトリモード
単純な工場モデルは実際には設計モデルではなく、プログラミング習慣であることが多い.
定義:ファクトリクラスを定義し、入力されたパラメータに応じて異なるインスタンスを返します.作成されたインスタンスには共通の親またはインタフェースがあります.
適用シーン:定義によって使用シーンが推測されます.まず、ファクトリクラスが1つしかないため、ファクトリクラスで作成されるオブジェクトは多すぎません.そうしないと、ファクトリクラスのビジネスロジックは複雑すぎます.次に、ファクトリクラスがオブジェクトの作成プロセスをカプセル化しているため、クライアントはオブジェクトの作成に関心を持たないはずです.適用シーンをまとめます:(1)作成するオブジェクトが少ない.(2)クライアントはオブジェクトの作成プロセスに関心を持たない.以上が単純ファクトリモード単純ファクトリモードの適用シーンであり,具体的な例を示す.
例:円形、正方形、三角形を描くことができる異なる形状を描くことができる図形描画ツールを作成します.各図形にはdraw()メソッドがあります.コードを見ずに、このモードでこの機能を設計する方法を考えてみましょう.
円形,正方形,三角形はいずれもグラフィックに属し,drawメソッドを有することが分かるので,まず,これら3つの画像の共通親としてインタフェースまたは抽象クラスを定義し,共通drawメソッドを宣言することができる.
ここで抽象クラスとして定義してもよいが,インタフェースはより高いレベルの抽象であるため,インタフェースとして定義することに慣れており,インタフェースは多実現をサポートし,後で拡張するのに便利である.
次は、それぞれのグラフィックがShapeインタフェースの円形を実現する具体的なグラフィックを作成します.
正方形
さんかくけい
以下は工場類の具体的な実現である.
このファクトリクラスでは異なるtypeを伝達することでnewの異なる形状を変えることができ,結果をShapeタイプに戻すことができ,これが単純なファクトリコアの場所である.クライアント使用
円を描く
正方形を描く
さんかくけいを描く
ShapeFactoryに異なるパラメータを入力するだけで、さまざまな形状の描画が可能になります.以上が簡単な工場方式ですが、仲間たちは分かりましたか?
ファクトリメソッドモード
ファクトリメソッドモデルは単純なファクトリのさらなる深化であり、ファクトリメソッドモデルでは、すべてのオブジェクトを作成するために統一されたファクトリクラスを提供するのではなく、異なるオブジェクトに対して異なるファクトリを提供します.すなわち,各オブジェクトに対応する工場がある.
定義:オブジェクトを作成するインタフェースを定義し、サブクラスがどのクラスをインスタンス化するかを決定します.ファクトリメソッドモードは、クラスのインスタンス化をサブクラスに遅延させます.今回はまずこの定義を実例で詳しく説明し,最後にその使用シーンをまとめた.
例:jpg,png,gif形式のピクチャをロードするための複数のピクチャローダを有するピクチャローダクラスを設計する必要があり、各ローダにはピクチャを読み取るためのread()メソッドがある.次に、この画像のロードクラスを完了します.
まず、ピクチャローダの設計を完了し、ローダの共通インタフェースを作成します.
Readerにはread()メソッドが1つしかなく、各ピクチャローダのコードを完了します.
Jpgピクチャローダ
Pngピクチャローダ
Gifピクチャローダ
抽象的なファクトリインタフェースReader Factoryを定義します
中にはgetReader()メソッドがあります.次に、上で定義した各ピクチャローダにファクトリクラスを提供します.これらのファクトリクラスはReader Factoryを実現します.
Jpgローダ工場
Pngローダ工場
Gifローダ工場
各ファクトリクラスでは,複写getReader()メソッドによりそれぞれのピクチャローダオブジェクトを返す.
クライアント使用
Jpgの読み込み
読み出しPng
Gifを読み込む
上の3つのコードが表示され、それぞれ異なるフォーマットのピクチャが読み込まれます.異なる点は、異なるピクチャフォーマットに対して異なる工場を宣言し、対応するピクチャローダを作成することです.
この例では、皆さんは工場モデルをさらに理解しているのではないでしょうか.単純工場と比較すると、最も根本的な違いは、単純工場には統一的な工場クラスが1つしかないことです.工場メソッドは、作成するオブジェクトごとに1つの工場クラスを提供し、これらの工場クラスは1つの工場ベースクラス(この例のReader Factory)を実現しています.工場法の適用場面をまとめてみます.
適用シーン:
(1)クライアントが作成したオブジェクトのクラスを知る必要はない.例では,各ピクチャローダの具体的な名前が分からず,その工場名を作成するだけでベッドフレームプロセスが完了する.(2)クライアントは,サブクラスを介して対応するオブジェクトを作成することを指定することができる.以上のシーンでは、ファクトリメソッドモードを使用します.
抽象ファクトリモード
このモードは最も理解しにくく,実際の応用においても限界が大きい.このモードは開閉原則に合致しないからである.実際の開発にはまだバランスが必要だ.抽象ファクトリモードはファクトリメソッドのさらなる深化であり、このモードのファクトリクラスはオブジェクトを作成するだけでなく、オブジェクトのセットを作成することができます.これは工場の方法と最大の違いです.
定義:特定のクラスを指定することなく、関連オブジェクトまたは相互依存オブジェクトの一連を作成するインタフェースを提供します.(抽象ファクトリモードでは、各特定のファクトリで複数のファクトリメソッドが提供され、複数の異なるタイプのオブジェクトを生成するために使用されます)抽象ファクトリは、ファクトリメソッドと同様に4つの大部分に分けることができます.AbstractFactory(抽象ファクトリ)は、オブジェクトを作成するためのメソッドのセットを宣言し、1つのグループであることに注意してください.ConcreteFactory(特定のファクトリ):抽象ファクトリで宣言されたオブジェクトの作成方法を実装し、特定のオブジェクトのセットを生成します.AbstraactProduct(抽象製品):各オブジェクトにインタフェースを宣言し、オブジェクトが持つビジネス・メソッドを宣言します.ConcreteProduct(特定の製品):特定の工場で生産される特定のオブジェクトを定義します.次に、具体的な例を見てみましょう.
例:プラットフォームにまたがるゲームを作る必要があります.Android、Ios、Wpの3つのモバイルオペレーティングシステムを互換化する必要があります.このゲームは各システムに対してオペレーティングコントローラ(OperationController)とインタフェースコントローラ(UIcontroller)を設計し、次は暇つぶし工場方式でこのゲームのアーキテクチャ設計を完成します.
問題から分かるように、ゲームの中の各プラットフォームのUIcontrollerとOperationControllerは私たちが最終的に生産した具体的な製品であるべきだ.したがって、2つの抽象製品インタフェースを新規に作成します.
抽象操作コントローラ
抽象インタフェースコントローラ
その後、各システムプラットフォームの具体的な操作コントローラとインタフェースコントローラAndroidを完成します.
Ios
Wp
次に、OperationControllerとUIcontrollerを作成する必要があるアイドルファクトリを定義します.
各プラットフォームの特定のファクトリクラスでコントローラとインタフェースコントローラの作成プロセスを完了
Android
Ios
Wp
クライアントコール:
異なるプラットフォームに対して異なるファクトリオブジェクトを作成するだけで操作とUIコントローラの作成が完了します.皆さんは、もしこのゲームが工場メソッドモードで構築されたら、どのくらいの工場クラスを作成する必要がありますか?抽象工場の適用場面をまとめます.
適用シーン:(1)ファクトリメソッドと同様にクライアントが作成したオブジェクトのクラスを知る必要はありません.(2)1組のオブジェクトが何らかの機能を共に果たす必要がある場合.また、複数のオブジェクトのグループが異なる機能を完了する場合があります.(3)システム構造は安定しており,頻繁にオブジェクトを増やすことはない.(増加すると元のコードを修正する必要があるため、開閉の原則に合致しない)
以上が3つの工場モデルのまとめであり、間違いがあれば、他人を誤解させないようにメッセージを残してほしい.
単純ファクトリモード
単純な工場モデルは実際には設計モデルではなく、プログラミング習慣であることが多い.
定義:ファクトリクラスを定義し、入力されたパラメータに応じて異なるインスタンスを返します.作成されたインスタンスには共通の親またはインタフェースがあります.
適用シーン:定義によって使用シーンが推測されます.まず、ファクトリクラスが1つしかないため、ファクトリクラスで作成されるオブジェクトは多すぎません.そうしないと、ファクトリクラスのビジネスロジックは複雑すぎます.次に、ファクトリクラスがオブジェクトの作成プロセスをカプセル化しているため、クライアントはオブジェクトの作成に関心を持たないはずです.適用シーンをまとめます:(1)作成するオブジェクトが少ない.(2)クライアントはオブジェクトの作成プロセスに関心を持たない.以上が単純ファクトリモード単純ファクトリモードの適用シーンであり,具体的な例を示す.
例:円形、正方形、三角形を描くことができる異なる形状を描くことができる図形描画ツールを作成します.各図形にはdraw()メソッドがあります.コードを見ずに、このモードでこの機能を設計する方法を考えてみましょう.
円形,正方形,三角形はいずれもグラフィックに属し,drawメソッドを有することが分かるので,まず,これら3つの画像の共通親としてインタフェースまたは抽象クラスを定義し,共通drawメソッドを宣言することができる.
public interface Shape {
void draw();
}
ここで抽象クラスとして定義してもよいが,インタフェースはより高いレベルの抽象であるため,インタフェースとして定義することに慣れており,インタフェースは多実現をサポートし,後で拡張するのに便利である.
次は、それぞれのグラフィックがShapeインタフェースの円形を実現する具体的なグラフィックを作成します.
public class CircleShape implements Shape {
public CircleShape() {
System.out.println( "CircleShape: created");
}
@Override
public void draw() {
System.out.println( "draw: CircleShape");
}
}
正方形
public class RectShape implements Shape {
public RectShape() {
System.out.println( "RectShape: created");
}
@Override
public void draw() {
System.out.println( "draw: RectShape");
}
}
さんかくけい
public class TriangleShape implements Shape {
public TriangleShape() {
System.out.println( "TriangleShape: created");
}
@Override
public void draw() {
System.out.println( "draw: TriangleShape");
}
}
以下は工場類の具体的な実現である.
public class ShapeFactory {
public static final String TAG = "ShapeFactory";
public static Shape getShape(String type) {
Shape shape = null;
if (type.equalsIgnoreCase("circle")) {
shape = new CircleShape();
} else if (type.equalsIgnoreCase("rect")) {
shape = new RectShape();
} else if (type.equalsIgnoreCase("triangle")) {
shape = new TriangleShape();
}
return shape;
}
}
このファクトリクラスでは異なるtypeを伝達することでnewの異なる形状を変えることができ,結果をShapeタイプに戻すことができ,これが単純なファクトリコアの場所である.クライアント使用
円を描く
Shape shape= ShapeFactory.getShape("circle");
shape.draw();
正方形を描く
Shape shape= ShapeFactory.getShape("rect");
shape.draw();
さんかくけいを描く
Shape shape= ShapeFactory.getShape("triangle");
shape.draw();
ShapeFactoryに異なるパラメータを入力するだけで、さまざまな形状の描画が可能になります.以上が簡単な工場方式ですが、仲間たちは分かりましたか?
ファクトリメソッドモード
ファクトリメソッドモデルは単純なファクトリのさらなる深化であり、ファクトリメソッドモデルでは、すべてのオブジェクトを作成するために統一されたファクトリクラスを提供するのではなく、異なるオブジェクトに対して異なるファクトリを提供します.すなわち,各オブジェクトに対応する工場がある.
定義:オブジェクトを作成するインタフェースを定義し、サブクラスがどのクラスをインスタンス化するかを決定します.ファクトリメソッドモードは、クラスのインスタンス化をサブクラスに遅延させます.今回はまずこの定義を実例で詳しく説明し,最後にその使用シーンをまとめた.
例:jpg,png,gif形式のピクチャをロードするための複数のピクチャローダを有するピクチャローダクラスを設計する必要があり、各ローダにはピクチャを読み取るためのread()メソッドがある.次に、この画像のロードクラスを完了します.
まず、ピクチャローダの設計を完了し、ローダの共通インタフェースを作成します.
public interface Reader {
void read();
}
Readerにはread()メソッドが1つしかなく、各ピクチャローダのコードを完了します.
Jpgピクチャローダ
public class JpgReader implements Reader {
@Override
public void read() {
System.out.print("read jpg");
}
}
Pngピクチャローダ
public class PngReader implements Reader {
@Override
public void read() {
System.out.print("read png");
}
}
Gifピクチャローダ
public class GifReader implements Reader {
@Override
public void read() {
System.out.print("read gif");
}
}
抽象的なファクトリインタフェースReader Factoryを定義します
public interface ReaderFactory {
Reader getReader();
}
中にはgetReader()メソッドがあります.次に、上で定義した各ピクチャローダにファクトリクラスを提供します.これらのファクトリクラスはReader Factoryを実現します.
Jpgローダ工場
public class JpgReaderFactory implements ReaderFactory {
@Override
public Reader getReader() {
return new JpgReader();
}
}
Pngローダ工場
public class PngReaderFactory implements ReaderFactory {
@Override
public Reader getReader() {
return new PngReader();
}
}
Gifローダ工場
public class GifReaderFactory implements ReaderFactory {
@Override
public Reader getReader() {
return new GifReader();
}
}
各ファクトリクラスでは,複写getReader()メソッドによりそれぞれのピクチャローダオブジェクトを返す.
クライアント使用
Jpgの読み込み
ReaderFactory factory=new JpgReaderFactory();
Reader reader=factory.getReader();
reader.read();
読み出しPng
ReaderFactory factory=new PngReaderFactory();
Reader reader=factory.getReader();
reader.read();
Gifを読み込む
ReaderFactory factory=new GifReaderFactory();
Reader reader=factory.getReader();
reader.read();
上の3つのコードが表示され、それぞれ異なるフォーマットのピクチャが読み込まれます.異なる点は、異なるピクチャフォーマットに対して異なる工場を宣言し、対応するピクチャローダを作成することです.
この例では、皆さんは工場モデルをさらに理解しているのではないでしょうか.単純工場と比較すると、最も根本的な違いは、単純工場には統一的な工場クラスが1つしかないことです.工場メソッドは、作成するオブジェクトごとに1つの工場クラスを提供し、これらの工場クラスは1つの工場ベースクラス(この例のReader Factory)を実現しています.工場法の適用場面をまとめてみます.
適用シーン:
(1)クライアントが作成したオブジェクトのクラスを知る必要はない.例では,各ピクチャローダの具体的な名前が分からず,その工場名を作成するだけでベッドフレームプロセスが完了する.(2)クライアントは,サブクラスを介して対応するオブジェクトを作成することを指定することができる.以上のシーンでは、ファクトリメソッドモードを使用します.
抽象ファクトリモード
このモードは最も理解しにくく,実際の応用においても限界が大きい.このモードは開閉原則に合致しないからである.実際の開発にはまだバランスが必要だ.抽象ファクトリモードはファクトリメソッドのさらなる深化であり、このモードのファクトリクラスはオブジェクトを作成するだけでなく、オブジェクトのセットを作成することができます.これは工場の方法と最大の違いです.
定義:特定のクラスを指定することなく、関連オブジェクトまたは相互依存オブジェクトの一連を作成するインタフェースを提供します.(抽象ファクトリモードでは、各特定のファクトリで複数のファクトリメソッドが提供され、複数の異なるタイプのオブジェクトを生成するために使用されます)抽象ファクトリは、ファクトリメソッドと同様に4つの大部分に分けることができます.AbstractFactory(抽象ファクトリ)は、オブジェクトを作成するためのメソッドのセットを宣言し、1つのグループであることに注意してください.ConcreteFactory(特定のファクトリ):抽象ファクトリで宣言されたオブジェクトの作成方法を実装し、特定のオブジェクトのセットを生成します.AbstraactProduct(抽象製品):各オブジェクトにインタフェースを宣言し、オブジェクトが持つビジネス・メソッドを宣言します.ConcreteProduct(特定の製品):特定の工場で生産される特定のオブジェクトを定義します.次に、具体的な例を見てみましょう.
例:プラットフォームにまたがるゲームを作る必要があります.Android、Ios、Wpの3つのモバイルオペレーティングシステムを互換化する必要があります.このゲームは各システムに対してオペレーティングコントローラ(OperationController)とインタフェースコントローラ(UIcontroller)を設計し、次は暇つぶし工場方式でこのゲームのアーキテクチャ設計を完成します.
問題から分かるように、ゲームの中の各プラットフォームのUIcontrollerとOperationControllerは私たちが最終的に生産した具体的な製品であるべきだ.したがって、2つの抽象製品インタフェースを新規に作成します.
抽象操作コントローラ
public interface OperationController {
void control();
}
抽象インタフェースコントローラ
public interface UIController {
void display();
}
その後、各システムプラットフォームの具体的な操作コントローラとインタフェースコントローラAndroidを完成します.
public class AndroidOperationController implements OperationController {
@Override
public void control() {
System.out.println("AndroidOperationController");
}
}
public class AndroidUIController implements UIController {
@Override
public void display() {
System.out.println("AndroidInterfaceController");
}
}
Ios
public class IosOperationController implements OperationController {
@Override
public void control() {
System.out.println("IosOperationController");
}
}
public class IosUIController implements UIController {
@Override
public void display() {
System.out.println("IosInterfaceController");
}
}
Wp
public class WpOperationController implements OperationController {
@Override
public void control() {
System.out.println("WpOperationController");
}
}
public class WpUIController implements UIController {
@Override
public void display() {
System.out.println("WpInterfaceController");
}
}
次に、OperationControllerとUIcontrollerを作成する必要があるアイドルファクトリを定義します.
public interface SystemFactory {
public OperationController createOperationController();
public UIController createInterfaceController();
}
各プラットフォームの特定のファクトリクラスでコントローラとインタフェースコントローラの作成プロセスを完了
Android
public class AndroidFactory implements SystemFactory {
@Override
public OperationController createOperationController() {
return new AndroidOperationController();
}
@Override
public UIController createInterfaceController() {
return new AndroidUIController();
}
}
Ios
public class IosFactory implements SystemFactory {
@Override
public OperationController createOperationController() {
return new IosOperationController();
}
@Override
public UIController createInterfaceController() {
return new IosUIController();
}
}
Wp
public class WpFactory implements SystemFactory {
@Override
public OperationController createOperationController() {
return new WpOperationController();
}
@Override
public UIController createInterfaceController() {
return new WpUIController();
}
}
クライアントコール:
SystemFactory mFactory;
UIController interfaceController;
OperationController operationController;
//Android
mFactory=new AndroidFactory();
//Ios
mFactory=new IosFactory();
//Wp
mFactory=new WpFactory();
interfaceController=mFactory.createInterfaceController();
operationController=mFactory.createOperationController();
interfaceController.display();
operationController.control();
異なるプラットフォームに対して異なるファクトリオブジェクトを作成するだけで操作とUIコントローラの作成が完了します.皆さんは、もしこのゲームが工場メソッドモードで構築されたら、どのくらいの工場クラスを作成する必要がありますか?抽象工場の適用場面をまとめます.
適用シーン:(1)ファクトリメソッドと同様にクライアントが作成したオブジェクトのクラスを知る必要はありません.(2)1組のオブジェクトが何らかの機能を共に果たす必要がある場合.また、複数のオブジェクトのグループが異なる機能を完了する場合があります.(3)システム構造は安定しており,頻繁にオブジェクトを増やすことはない.(増加すると元のコードを修正する必要があるため、開閉の原則に合致しない)
以上が3つの工場モデルのまとめであり、間違いがあれば、他人を誤解させないようにメッセージを残してほしい.