您好,登錄后才能下訂單哦!
這篇文章主要介紹了Java工廠模式實例代碼分析的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Java工廠模式實例代碼分析文章都會有所收獲,下面我們一起來看看吧。
看一個具體的需求
看一個披薩的項目 :要便于披薩種類的擴展,要便于維護
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(); } }
基本介紹
1)抽象工廠模式 : 定義了一個interface用于創建相關或有依賴關系的對象簇,而無需指明具體的類
2)抽象工廠模式可以將簡單工廠模式和工廠方法模式進行整合
3)從設計層面看,抽象工廠模式就是對簡單工廠模式的改進(或者稱為進一步的抽象)。
4)將工廠抽象成兩層,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工廠模式實例代碼分析”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“Java工廠模式實例代碼分析”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。