ホームページ >Java >&#&チュートリアル >Java ファクトリ パターンのサンプル コード分析
特定の要件を確認してください
ピザ プロジェクトを確認してください: ピザの種類の拡張を促進し、メンテナンスを容易にするために
1) ピザにはたくさんの種類があります (GreekPizz、CheesePizz など)
2) ピザ作りには、準備、焼き、カット、箱詰めが含まれます
3) ピザショップの注文機能を完了します。
package com.example.demo.simplefactory.pizzastore.pizza; /** * 将Pizza 类做成抽象 * @author Administrator * */ public abstract class Pizza { /** * 名字 */ protected String name; /** * 准备原材料,不同的披萨不一样,因此,我们做成抽象方法 */ public abstract void prepare(); public void bake() { System.out.println(name + " baking;"); } public void cut() { System.out.println(name + " cutting;"); } public void box() { System.out.println(name + " boxing"); } public void setName(String name) { this.name = name; } } package com.example.demo.simplefactory.pizzastore.pizza; public class GreekPizza extends Pizza{ @Override public void prepare() { System.out.println(" 给希腊披萨 准备原材料"); } } package com.example.demo.simplefactory.pizzastore.pizza; public class CheesePizza extends Pizza{ @Override public void prepare() { System.out.println(" 给制作奶酪披萨,准备原材料"); } } package com.example.demo.simplefactory.pizzastore.order; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import com.example.demo.simplefactory.pizzastore.pizza.CheesePizza; import com.example.demo.simplefactory.pizzastore.pizza.GreekPizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class OrderPizza { /** * 构造器 */ public OrderPizza() { Pizza pizza = null; // 订购披萨的类型 String orderType; do { orderType = getType(); if (orderType.equals("greek")) { pizza = new GreekPizza(); pizza.setName(" 希腊披萨 "); } else if (orderType.equals("cheese")) { pizza = new CheesePizza(); pizza.setName(" 奶酪披萨 "); } else { break; } // 输出pizza 制作过程 pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } while (true); } /** * 写一个方法,可以获取客户希望订购的披萨种类 * @return */ private String getType() { try { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza type : "); String string = bufferedReader.readLine(); return string; } catch(IOException e) { e.printStackTrace(); return ""; } } } package com.example.demo.simplefactory.pizzastore.order; /** * 相当于一个客户端,发出订购 * @author Administrator * */ public class PizzaStore { public static void main(String[] args) { new OrderPizza(); } }
従来の方法の長所と短所:
1) 利点は、理解しやすく、操作が簡単であることです。
2) 欠点は、拡張が可能で変更が禁止されているデザイン パターンの OCP 原則に違反していることです。つまり、クラスに新しい関数を追加するときは、コードを変更しないようにするか、コードの変更を最小限に抑えるようにします。
3) たとえば、現時点で新しいピザの種類を追加したい場合は、次のように変更する必要があります。
package com.example.demo.simplefactory.pizzastore.pizza; public class PepperPizza extends Pizza{ @Override public void prepare() { System.out.println(" 给胡椒披萨准备原材料 "); } } package com.example.demo.simplefactory.pizzastore.order; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import com.example.demo.simplefactory.pizzastore.pizza.CheesePizza; import com.example.demo.simplefactory.pizzastore.pizza.GreekPizza; import com.example.demo.simplefactory.pizzastore.pizza.PepperPizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class OrderPizza { /** * 构造器 */ public OrderPizza() { Pizza pizza = null; // 订购披萨的类型 String orderType; do { orderType = getType(); if (orderType.equals("greek")) { pizza = new GreekPizza(); pizza.setName(" 希腊披萨 "); } else if (orderType.equals("cheese")) { pizza = new CheesePizza(); pizza.setName(" 奶酪披萨 "); } else if (orderType.equals("pepper")) { pizza = new PepperPizza(); pizza.setName("胡椒披萨"); } else { break; } // 输出pizza 制作过程 pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } while (true); } /** * 写一个方法,可以获取客户希望订购的披萨种类 * @return */ private String getType() { try { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza type : "); String string = bufferedReader.readLine(); return string; } catch(IOException e) { e.printStackTrace(); return ""; } } }
4) 改善されたアイデアの分析
分析: コードの変更は許容されますが、他の場所にもピザを作成するコードがある場合、それも変更する必要があることを意味します。 create Pizza コード内には複数の場所が存在することがよくあります。
アイデア: Pizza オブジェクトの作成をクラスにカプセル化することで、新しいピザ タイプを作成したときに、クラスを変更するだけで済み、Pizza オブジェクトを作成する他のコードを変更する必要がなくなります
基本的な紹介
1) シンプル ファクトリ パターンは作成パターンであり、ファクトリ パターンの一種です。単純なファクトリ パターンでは、ファクトリ オブジェクトを使用して、どの製品クラス インスタンスを作成するかを決定します。シンプル ファクトリ パターンは、ファクトリ パターン ファミリの中で最も単純で実用的なパターンです。
2) シンプル ファクトリ パターン: オブジェクトを作成するクラスを定義し、このクラスはインスタンス化されたオブジェクトの行 (コード) をカプセル化します。
3) ソフトウェア開発では、特定の種類、タイプ、またはバッチのオブジェクトを多数作成する場合、ファクトリ パターンを使用します。
package com.example.demo.simplefactory.pizzastore.order; import com.example.demo.simplefactory.pizzastore.pizza.CheesePizza; import com.example.demo.simplefactory.pizzastore.pizza.GreekPizza; import com.example.demo.simplefactory.pizzastore.pizza.PepperPizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; /** * 简单工厂类 * @author Administrator * */ public class SimpleFactory { public Pizza createPizza(String orderType) { Pizza pizza = null; System.out.println("使用简单工厂模式"); if (orderType.equals("greek")) { pizza = new GreekPizza(); pizza.setName(" 希腊披萨 "); } else if (orderType.equals("cheese")) { pizza = new CheesePizza(); pizza.setName(" 奶酪披萨 "); } else if (orderType.equals("pepper")) { pizza = new PepperPizza(); pizza.setName("胡椒披萨"); } return pizza; } } package com.example.demo.simplefactory.pizzastore.order; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import com.example.demo.simplefactory.pizzastore.pizza.CheesePizza; import com.example.demo.simplefactory.pizzastore.pizza.GreekPizza; import com.example.demo.simplefactory.pizzastore.pizza.PepperPizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class OrderPizza { /** * 构造器 */ /* * public OrderPizza() { Pizza pizza = null; // 订购披萨的类型 String orderType; do { * orderType = getType(); if (orderType.equals("greek")) { pizza = new * GreekPizza(); pizza.setName(" 希腊披萨 "); } else if (orderType.equals("cheese")) * { pizza = new CheesePizza(); pizza.setName(" 奶酪披萨 "); } else if * (orderType.equals("pepper")) { pizza = new PepperPizza(); * pizza.setName("胡椒披萨"); } else { break; } // 输出pizza 制作过程 pizza.prepare(); * pizza.bake(); pizza.cut(); pizza.box(); } while (true); } */ /** * 构造器 * @param simpleFactory */ public OrderPizza(SimpleFactory simpleFactory) { setFactory(simpleFactory); } /** * 定义一个简单工厂对象 */ private SimpleFactory simpleFactory; private Pizza pizza = null; private void setFactory(SimpleFactory simpleFactory) { // 用户输入的 String orderTypeString = ""; // 设置简单工厂对象 this.simpleFactory = simpleFactory; do { orderTypeString = getType(); pizza = this.simpleFactory.createPizza(orderTypeString); // 输出pizza // 订购成功 if (pizza != null) { pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } else { System.out.println(" 订购披萨失败 "); break; } } while (true); } /** * 写一个方法,可以获取客户希望订购的披萨种类 * @return */ private String getType() { try { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza type : "); String string = bufferedReader.readLine(); return string; } catch(IOException e) { e.printStackTrace(); return ""; } } } package com.example.demo.simplefactory.pizzastore.order; /** * 相当于一个客户端,发出订购 * @author Administrator * */ public class PizzaStore { public static void main(String[] args) { //new OrderPizza(); // 使用简单工厂模式 new OrderPizza(new SimpleFactory()); System.out.println("~~退出程序~~"); } }
新しい要件を見てください
ピザ プロジェクトの新しい要件: 顧客がピザを注文するとき、さまざまなことができます北京チーズピザ、北京ペッパーピザ、ロンドンチーズピザ、ロンドンペッパーピザなどのピザのフレーバー。
アイデア 1
単純なファクトリ パターンを使用して、BJPizzaSimpleFactory、LDPizzaSimpleFactory などのさまざまな単純なファクトリ クラスを作成します。現在のケースでは、次のようになります。これもはいですが、プロジェクトの規模とソフトウェアの保守性と拡張性を考慮すると、特に良いとは言えません
アイデア 2
ファクトリーを使用するメソッド パターン
ファクトリ メソッド パターンの概要
ファクトリ メソッド パターン設計計画: ピザ プロジェクトのインスタンス化関数を、食べ物を注文するための抽象メソッドに抽象化します。さまざまなフレーバー 特にサブクラスで実装されます。
ファクトリ メソッド パターン: オブジェクトを作成するための抽象メソッドを定義し、サブクラスによってインスタンス化されるクラスが決定されます。ファクトリ メソッド パターンは、 オブジェクトのインスタンス化をサブクラス に延期します。
package com.example.demo.factorymethod.pizzastore.order; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; import com.fasterxml.jackson.databind.deser.ValueInstantiator.Gettable; public abstract class OrderPizza { public OrderPizza() { Pizza pizza = null; // 订购披萨的类型 String orderType; do { orderType = getType(); createPizza(orderType); // 输出Pizza 制作过程 pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } while (true); } /** * 定义一个抽象方法,createPizza,让各个工厂子类自己实现 * @param orderType * @return */ abstract Pizza createPizza(String orderType); /** * 写一个方法,可以获取客户希望订购的披萨种类 * @return */ private String getType() { try { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza type : "); String string = bufferedReader.readLine(); return string; } catch(IOException e) { e.printStackTrace(); return ""; } } } package com.example.demo.factorymethod.pizzastore.order; import org.apache.tomcat.util.security.Escape; import com.example.demo.factorymethod.pizzastore.pizza.LDCheesePizza; import com.example.demo.factorymethod.pizzastore.pizza.LDPepperPizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class LDOrderPizza extends OrderPizza{ @Override Pizza createPizza(String orderType) { Pizza pizza = null; if (orderType.equals("cheese")) { pizza = new LDCheesePizza(); } else if (orderType.equals("pepper")) { pizza = new LDPepperPizza(); } return pizza; } } package com.example.demo.factorymethod.pizzastore.order; import com.example.demo.factorymethod.pizzastore.pizza.BJCheesPizza; import com.example.demo.factorymethod.pizzastore.pizza.BJPepperPizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class BJOrderPizza extends OrderPizza{ @Override Pizza createPizza(String orderType) { Pizza pizza = null; if (orderType.equals("cheese")) { pizza = new BJCheesPizza(); } else if (orderType.equals("pepper")) { pizza = new BJPepperPizza(); } return pizza; } } package com.example.demo.factorymethod.pizzastore.pizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class BJCheesPizza extends Pizza{ @Override public void prepare() { setName("北京的奶酪pizza"); System.out.println(" 北京的奶酪pizza 准备原材料 "); } } package com.example.demo.factorymethod.pizzastore.pizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class BJPepperPizza extends Pizza{ @Override public void prepare() { setName(" 北京的胡椒pizza "); System.out.println(" 北京的胡椒pizza 准备原材料 "); } } package com.example.demo.factorymethod.pizzastore.pizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class LDCheesePizza extends Pizza{ @Override public void prepare() { setName(" 伦敦的奶酪pizza "); System.out.println(" 伦敦的奶酪pizza 准备原材料 "); } } package com.example.demo.factorymethod.pizzastore.pizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class LDPepperPizza extends Pizza{ @Override public void prepare() { setName(" 伦敦的胡椒pizza "); System.out.println(" 伦敦的胡椒pizza 准备原材料 "); } } package com.example.demo.factorymethod.pizzastore.order; public class PizzaStore { public static void main(String[] args) { // 创建北京口味的各种Pizza new BJOrderPizza(); } }
基本的な概要
1) 抽象ファクトリ パターン: 関連または依存するリレーショナル オブジェクトの作成に使用される インターフェイス を定義します。特定のクラスを指定せずにクラスターを作成します。
2) 抽象ファクトリ パターンは、単純なファクトリ パターンと ファクトリ メソッド パターン
3) 設計から観点から見ると、抽象ファクトリ パターンは、単純なファクトリ パターンを改良 (またはさらに抽象化) したものです。
4) ファクトリを 2 つの層、AbsFactory (抽象ファクトリ) と具体的に実装されたファクトリ サブクラスに抽象化します。プログラマは、作成するオブジェクトのタイプに基づいて、対応するファクトリ サブクラスを使用できます。これにより、単一の単純なファクトリ クラスがファクトリ クラスタに変わり、コードのメンテナンスと拡張がより容易になります。
package com.example.demo.absfactory.pizzastore.order; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; /** * 一个抽象工厂模式的抽象层(接口) * @author Administrator * */ public interface AbsFactory { /** * 让下面的工厂子类来 具体实现 * @param orderType * @return */ Pizza createPizza(String orderType); } package com.example.demo.absfactory.pizzastore.order; import com.example.demo.absfactory.pizzastore.pizza.BJCheesPizza; import com.example.demo.factorymethod.pizzastore.pizza.BJPepperPizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; /** * 这是工厂子类 * @author Administrator * */ public class BJFactory implements AbsFactory{ @Override public Pizza createPizza(String orderType) { System.out.println("~使用的是抽象工厂模式~"); Pizza pizza = null; if (orderType.equals("cheese")) { pizza = new BJCheesPizza(); } else if (orderType.equals("pepper") ) { pizza = new BJPepperPizza(); } return pizza; } } package com.example.demo.absfactory.pizzastore.order; import com.example.demo.absfactory.pizzastore.pizza.LDCheesePizza; import com.example.demo.absfactory.pizzastore.pizza.LDPepperPizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class LDFactory implements AbsFactory{ @Override public Pizza createPizza(String orderType) { System.out.println("~使用的是抽象工厂模式~"); Pizza pizza = null; if (orderType.equals("cheese")) { pizza = new LDCheesePizza(); } else if (orderType.equals("pepper")) { pizza = new LDPepperPizza(); } return pizza; } } package com.example.demo.absfactory.pizzastore.order; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class OrderPizza { private AbsFactory factory; /** * 构造器 * @param factory */ public OrderPizza(AbsFactory factory) { setFactory(factory); } private void setFactory(AbsFactory factory) { Pizza pizza = null; // 用户输入 String orderTypeString = ""; this.factory = factory; do { orderTypeString = getType(); pizza = factory.createPizza(orderTypeString); if (pizza != null) { pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } else { System.out.println("~订购失败~"); break; } } while (true); } /** * 写一个方法,可以获取客户希望订购的披萨种类 * @return */ private String getType() { try { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza type : "); String string = bufferedReader.readLine(); return string; } catch(IOException e) { e.printStackTrace(); return ""; } } } package com.example.demo.absfactory.pizzastore.pizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class BJCheesPizza extends Pizza{ @Override public void prepare() { setName("北京的奶酪pizza"); System.out.println(" 北京的奶酪pizza 准备原材料 "); } } package com.example.demo.absfactory.pizzastore.pizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class BJPepperPizza extends Pizza{ @Override public void prepare() { setName(" 北京的胡椒pizza "); System.out.println(" 北京的胡椒pizza 准备原材料 "); } } package com.example.demo.absfactory.pizzastore.pizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class LDCheesePizza extends Pizza{ @Override public void prepare() { setName(" 伦敦的奶酪pizza "); System.out.println(" 伦敦的奶酪pizza 准备原材料 "); } } package com.example.demo.absfactory.pizzastore.pizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class LDPepperPizza extends Pizza{ @Override public void prepare() { setName(" 伦敦的胡椒pizza "); System.out.println(" 伦敦的胡椒pizza 准备原材料 "); } } package com.example.demo.absfactory.pizzastore.order; public class PizzaStore { public static void main(String[] args) { new OrderPizza(new BJFactory()); } }
JDK-Calendar アプリケーションのファクトリ モードのソース コード分析
1) シンプル ファクトリ モードは、JDK の Calendar クラスで使用されます
public static Calendar getInstance() { return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT)); } private static Calendar createCalendar(TimeZone zone, Locale aLocale) { CalendarProvider provider = LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale) .getCalendarProvider(); if (provider != null) { try { return provider.getInstance(zone, aLocale); } catch (IllegalArgumentException iae) { // fall back to the default instantiation } } Calendar cal = null; if (aLocale.hasExtensions()) { String caltype = aLocale.getUnicodeLocaleType("ca"); if (caltype != null) { switch (caltype) { case "buddhist": cal = new BuddhistCalendar(zone, aLocale); break; case "japanese": cal = new JapaneseImperialCalendar(zone, aLocale); break; case "gregory": cal = new GregorianCalendar(zone, aLocale); break; } } } if (cal == null) { // If no known calendar type is explicitly specified, // perform the traditional way to create a Calendar: // create a BuddhistCalendar for th_TH locale, // a JapaneseImperialCalendar for ja_JP_JP locale, or // a GregorianCalendar for any other locales. // NOTE: The language, country and variant strings are interned. if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") { cal = new BuddhistCalendar(zone, aLocale); } else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja" && aLocale.getCountry() == "JP") { cal = new JapaneseImperialCalendar(zone, aLocale); } else { cal = new GregorianCalendar(zone, aLocale); } } return cal; }
以上がJava ファクトリ パターンのサンプル コード分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。