一連の記事
23のデザインパターン-デザインパターンの目的と
23のデザインパターンに従う7つの原則-シングルトンモード[空腹、怠惰、ダブルチェック、静的内部クラス、列挙]
23のデザインパターン-ファクトリモード[シンプルファクトリ、ファクトリメソッド、抽象ファクトリ]
23のデザインモード-プロトタイプモード[クローンシープ、浅いコピー、深いコピー]
記事のディレクトリ
2.工場モデル
そのようなピザプロジェクトの需要があります:
- ピザには、GreekPizza、CheessPizzaなど多くの種類があります
- ピザ作りには、準備、焼き、カット、箱が含まれます
- ピッツェリア注文機能を完了します
従来の方法では、最初にピザを抽象クラスにする必要があります。ピザには、準備、焼き、カット、ボックスの各メソッドが含まれます。ピザが異なれば、準備方法も異なるため、準備は抽象メソッドです。GreekPizzaとCheessPizzaはPizzaクラスを継承し、独自のメソッドを実装しますが、ピザを注文するストアは、Pizza、CheessPizza、GreekPizzaに依存します。
ただし、これは明らかにOCP(開閉の原則)に準拠していません。新しい種類のピザを追加する場合、OrderPizza1はピザに依存し、通常は複数のOrderPizzaがあるため、ユーザーを変更します。したがって、それを最適化する必要があります。
2.1、単純なファクトリモデル
-
シンプルファクトリモデルは、ファクトリモデルの一種であるクリエーションモデルに属しています。単純なファクトリパターンは、ファクトリオブジェクトによって決定され、製品クラスが作成されるインスタンスが作成されます。ファクトリパターンで使用するのが最も簡単なパターンです。
-
単純なファクトリパターン:オブジェクトを作成するためのクラスを定義します。このクラスは、インスタンス化されたオブジェクトの動作iをカプセル化します。
-
開発において、特定の、特定のタイプを作成するために、または批判しようとするために多数のオブジェクトを使用する場合、ファクトリモデルを使用する必要があります。
SimpleFactoryを追加して、ピザを均一に生産します。他の注文は、ピザに直接依存するのではなく、工場に渡すだけで済みます。工場は、注文ごとに異なる種類のピザを返品できるため、開閉の原則を満たします。
ピザカテゴリ
public abstract class Pizza {
public abstract void prepare();
public void bake(){
System.out.println("烤披萨");
}
public void cut(){
System.out.println("切披萨");
}
public void box(){
System.out.println("装盒");
}
}
public class CheesePizza extends Pizza {
@Override
public void prepare() {
System.out.println("准备奶酪披萨材料");
}
}
public class GreekPizza extends Pizza {
@Override
public void prepare() {
System.out.println("准备希腊披萨材料");
}
}
シンプルなファクトリ
public class SimpleFactory {
//根据不同订单,返回不同的披萨
public static Pizza createPizza(String orderType){
Pizza pizza = null;
System.out.println("使用简单工厂模式");
if (orderType.equals("greek")){
System.out.println("希腊披萨");
pizza = new GreekPizza();
}
else if(orderType.equals("cheese")){
System.out.println("奶酪披萨");
pizza = new CheesePizza();
}
return pizza;
}
}
注文クラス
public class OrderPizza {
Pizza pizza = null;
public OrderPizza(){
String orderType = "";
do{
orderType = getType();
pizza = SimpleFactory.createPizza(orderType);
if (pizza != null){
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.bake();
}
else{
System.out.println("订购披萨失败!");
break;
}
}while (true);
}
private String getType(){
Scanner scanner = new Scanner(System.in);
System.out.println("输入披萨类型:");
String string = scanner.nextLine();
if (string != null)
return string;
return "";
}
public static void main(String[] args) {
OrderPizza orderPizza = new OrderPizza();
}
}
2.2。ファクトリメソッドパターン
現在、ピザプロジェクトには新しい需要があります。顧客がピザを注文すると、北京のチーズピザ、北京のギリシャピザ、ロンドンのチーズピザなど、さまざまなフレーバーのピザを注文できます。
アイデア1:引き続き単純なファクトリモデルを使用しますが、地域が異なると、BJPizzaSimpleFactoryやLDPizzaSimpleFactoryなどの複数のファクトリを作成する必要があります。ただし、プロジェクトの規模、ソフトウェアの保守性とスケーラビリティを考慮すると、このアプローチは特に優れていません。
アイデア2:ファクトリメソッドパターンを使用する-オブジェクトのインスタンス化をサブクラスの実装に延期します。ピザプロジェクトでは、ピザプロジェクトのインスタンス化関数が抽象メソッドとして抽象化され、さまざまなフレーバーのさまざまな順序のサブカテゴリで実装されます。
4種類のピザはすべてPizzaクラスから継承され、BJOrderとLDOrderは抽象クラスOrderPizzaから継承され、createPizzaは具象クラスによって実装されます。
ピザ
//Pizza抽象类
public abstract class Pizza {
public abstract void prepare();
public void bake(){
System.out.println("烤披萨");
}
public void cut(){
System.out.println("切披萨");
}
public void box(){
System.out.println("装盒");
}
}
//北京奶酪披萨
public class BJCheesePizza extends Pizza {
@Override
public void prepare() {
System.out.println("准备北京奶酪披萨原材料");
}
}
//北京希腊披萨
public class BJGreekPizza extends Pizza {
@Override
public void prepare() {
System.out.println("准备北京希腊披萨原材料\"");
}
}
//伦敦奶酪披萨
public class LDCheesePizza extends Pizza {
@Override
public void prepare() {
System.out.println("准备伦敦奶酪披萨原材料");
}
}
//伦敦希腊披萨
public class LDGreekPizza extends Pizza {
@Override
public void prepare() {
System.out.println("准备伦敦希腊披萨原材料\"");
}
}
抽象ファクトリ:抽象クラスを注文する
public abstract class OrderPizza {
//抽象方法,具体由子类工厂实现
public abstract Pizza createPizza(String orderType);
//抽象类的构造方法,在子类实例化时因为有super(),所以会先被执行。
public OrderPizza(){
Pizza pizza = null;
String orderType = "";
do{
orderType = getType();
pizza = createPizza(orderType);//根据子类的不同,返回不同披萨
if (pizza != null){
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.bake();
}
else{
System.out.println("订购披萨失败!");
break;
}
}while (true);
}
//获得用户输入的披萨类型
private String getType(){
Scanner scanner = new Scanner(System.in);
System.out.println("输入披萨类型:");
String string = scanner.nextLine();
if (string != null)
return string;
return "";
}
}
ロンドンと北京の特定の工場
//北京的订单工厂
public class BJOrderPizza extends OrderPizza {
@Override
public Pizza createPizza(String orderType) {
Pizza pizza = null;
if (orderType.equals("cheese"))
pizza = new BJCheesePizza();
else if (orderType.equals("greek"))
pizza = new BJGreekPizza();
return pizza;
}
}
//伦敦的订单工厂
public class LDOrderPizza extends OrderPizza {
@Override
public Pizza createPizza(String orderType) {
Pizza pizza = null;
if (orderType.equals("cheese"))
pizza = new LDCheesePizza();
else if (orderType.equals("greek"))
pizza = new LDGreekPizza();
return pizza;
}
}
テスト
public class Test {
public static void main(String[] args) {
//订购北京的披萨
BJOrderPizza bjOrderPizza = new BJOrderPizza();
//订购伦敦的披萨
LDOrderPizza ldOrderPizza = new LDOrderPizza();
}
}
2.3、抽象的なファクトリパターン
- 抽象ファクトリパターン:特定のクラスを指定せずに、関連オブジェクトまたは依存オブジェクトのクラスタを作成するためのインターフェイスを定義します。
- 抽象ファクトリパターンは、単純ファクトリパターンとファクトリメソッドパターンを統合できます。これは、単純ファクトリパターンの改良版です。
- ファクトリは、AbsFactory(抽象ファクトリ)と具象実装クラスファクトリの2つの層に抽象化されます。プログラマは、作成されたオブジェクトのタイプに応じて対応するファクトリを使用するため、単一の単純なファクトリクラスがファクトリクラスタに変換され、コードのメンテナンスに役立ちます。と拡張。
インターフェースAbsFactoryにはピザ製造メソッドがあり、BJFactoryとLDFactoryはこのインターフェースを実装して、独自のピザを生産する特定のメソッドを実装します。他の注文クラスは、実装クラスBJFactoryとLDFactoryを使用するために、インターフェースAbsFactoryに集約するだけで済みます。単一の単純な工場ではありません。
ピザカテゴリ(以前と同じ)
抽象ファクトリとコンクリートファクトリ
//一个抽象工厂模式的抽象层(接口)
public interface AbsFactory {
//由具体的工厂实现类完成
Pizza creatPizza(String orderType);
}
//工厂子类
public class BJFactory implements AbsFactory {
@Override
public Pizza creatPizza(String orderType) {
Pizza pizza = null;
if (orderType.equals("cheese"))
pizza = new BJCheesePizza();
else if (orderType.equals("greek"))
pizza = new BJGreekPizza();
return null;
}
}
//工厂子类
public class LDFactory implements AbsFactory {
@Override
public Pizza creatPizza(String orderType) {
Pizza pizza = null;
if (orderType.equals("cheese"))
pizza = new LDCheesePizza();
else if (orderType.equals("greek"))
pizza = new LDGreekPizza();
return null;
}
}
注文クラス
package design_partten.factory.absfactory;
import java.util.Scanner;
public class OrderPizza {
//聚合的方式使用工厂
AbsFactory absFactory;
public OrderPizza(AbsFactory absFactory){
setAbsFactory(absFactory);
}
//设置工厂,订购披萨
private void setAbsFactory(AbsFactory absFactory){
Pizza pizza = null;
String orderType = "";
this.absFactory = absFactory;
do {
orderType = getType();
//absFactory可能是北京的工厂子类,也可能是伦敦的工厂子类
pizza = absFactory.creatPizza(orderType);
if (pizza != null){
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.bake();
}
else{
System.out.println("订购披萨失败!");
break;
}
}while (true);
}
//获取用户输入类型
private String getType(){
Scanner scanner = new Scanner(System.in);
System.out.println("输入披萨类型:");
String string = scanner.nextLine();
if (string != null)
return string;
return "";
}
}
テスト
public class Test {
public static void main(String[] args) {
//北京披萨
new OrderPizza(new BJFactory());
//伦敦披萨
new OrderPizza(new LDFactory());
}
}
2.4.JDK-Calendarのファクトリモードのソースコード
getInstance()
地区と地域が原因で合格しなかった場合に、Calendarインスタンスを取得するための静的メソッドのカレンダー。したがって、デフォルトのタイムゾーンと地域を使用getInstance()
するように呼び出さcreateCalendar()
れます。
この方法では、以前のピザの注文と同様に、単純なファクトリモデルが使用され、さまざまな種類の注文が行われ、さまざまなピザが返されます。createCalendar()
さまざまなタイムゾーンに応じて、さまざまなカレンダーに戻ります。
2.5まとめ
-
ファクトリーモデルの重要性:
インスタンス化されたオブジェクトのコードを抽出し、それを統一された管理と保守のためのファクトリクラスに入れて、メインプロジェクトの依存関係の分離を実現し、それによってコードのスケーラビリティと保守性を向上させます。
-
3つのファクトリパターン:単純なファクトリパターン、ファクトリメソッドパターン、抽象的なファクトリパターン
-
デザインパターン依存の抽象的な原理:
- オブジェクトを作成するときは、newで直接作成するのではなく、新しいクラスのアクションをファクトリクラスのメソッドに入れると、このメソッドによってオブジェクトが返されます。
- クラスに具象クラスを継承させないでください。抽象クラスを継承するか、インターフェースを実装してください。
- 基本クラスのメソッドを再実装しないでください。