看一個具體的需求
看一個披薩的項目:要便於披薩種類的擴展,要便於維護
1)披薩的種類很多(如GreekPizz、CheesePizz等)
2)披薩的製作有prepare、bake、cut、box
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)像我們這時要新增加一個Pizza的種類,我們需要如下修改。
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)改進的想法分析
分析:修改程式碼可以接受,但是如果我們在其它的地方也有創建Pizza的程式碼,就意味著,也需要修改,而創建Pizza的程式碼,往往有多處。
想法:把創建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("~~退出程序~~"); } }
看一個新的需求
披薩專案新的需求:客戶在點披薩時,可以點不同口味的披薩,例如北京的起司pizza、北京的胡椒pizza或是倫敦的起司pizza、倫敦的胡椒pizza。
思路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(); } }
interface用於建立相關或有依賴關係的物件簇,而無需指明具體的類別
2)抽象工廠模式可以將簡單工廠模式和工廠方法模式整合
3)從設計層面來看,抽象工廠模式就是簡單工廠模式的改進(或稱為進一步的抽象)。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()); } }
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中文網其他相關文章!