簡介
1.學(xué)習(xí)本篇文章,了解簡單工廠設(shè)計模式的使用場景。
2.如何使用簡單工廠模式。
3.簡單工廠模式能解決什么問題?
現(xiàn)在有一家外賣小店需要從生產(chǎn)一份外賣開始進(jìn)行考慮設(shè)計,當(dāng)客戶在網(wǎng)上點出不同味道的菜時,外賣小店就將按照不同的訂單進(jìn)行生產(chǎn)出菜品,然后進(jìn)行打包、等待外賣小哥獲取、贈送給客戶等不同的幾道工序,才算完成一單,但是后期由于生意很好,客戶評價很高,有些地方的老板想加盟本店了,那么可能就會出現(xiàn)不同味道的菜單,還有一些本地的特色菜也會加上菜單,這時,客戶就能點到更多的菜品了,為了達(dá)到某些商家快速而且合理的進(jìn)行管理,你是怎么設(shè)計這個方案的呢?
分析一般情況下客戶點餐的時候,都會查看平分高低,還有出貨次數(shù),如果人氣好的,肯定要大量生產(chǎn),而沒有人點的,則可以考慮去除,所以我們通過以上的考慮,需要封裝創(chuàng)建對象的代碼,如將生產(chǎn)商品的對象封裝起來,這樣,我們出掉或者添加的時候,都只修改這部分的代碼,那么是哪個生產(chǎn)商品呢?答案肯定是店家了,所以我們稱這個生產(chǎn)商品的店家為“工廠”。
接下來我們進(jìn)行分析以上代碼該如何展現(xiàn)出來呢?我們將通過兩種方式來進(jìn)行編寫。
如何實現(xiàn)呢?我們先來看看本例的類圖
1.創(chuàng)建一個美食店,MealStore.class
/** * Author Eirunye * Created by on 2018/9/19. * Describe */ public class MealStore { public Meal submitOrderMeal(String type) { Meal meal; //利用靜態(tài)工廠方法生成產(chǎn)品 //重點(靜態(tài)工廠實現(xiàn)代碼) meal = SimpleMealsFactory.createMeal(type); //以下方法是進(jìn)行一些設(shè)計而已不是靜態(tài)工廠方法的模塊,是產(chǎn)品的一些操作而已,無關(guān)緊要的 //店家準(zhǔn)備中... meal.mealPreparation(); //打包 meal.bake(); //獲取 meal.getMeal(); //配送 meal.send(); return meal; } }
2.創(chuàng)建一個靜態(tài)工廠SimpleMealsFactory.class
/** * Author Eirunye * Created by on 2018/9/18. * Describe 建立一個簡單靜態(tài)工廠,該工廠生產(chǎn)不同的菜品(美食) * Tip: 提示:這是不是我們經(jīng)常使用的Util類的編寫方式? */ public class SimpleMealsFactory { //將生產(chǎn)產(chǎn)品(美食放在這里) public static Meal createMeal(String type) { Meal meal = null; if ("crayfish".equals(type)) { meal = new CrayfishMeal(); //創(chuàng)建什么類型的產(chǎn)品(美食)讓子類來操作 } else if ("roastChicken".equals(type)) { meal = new RoastChicken(); } else if ("A".equals(type)) { } else if ("B".equals(type)) { } // ... return meal; //返回的是美食商品 } }
3.創(chuàng)建產(chǎn)品美食抽象基類Meal.class,這樣的話我們就可以交給子類來完成商品的生產(chǎn)。
/** * Author Eirunye * Created by on 2018/9/19. * Describe 定義一個抽象產(chǎn)品接口、這里也可以是抽象類 */ public abstract class Meal { public List mealInfo = new ArrayList(); public void mealPreparation() { System.out.println("您的商品準(zhǔn)備中..."+this.name); System.out.println("adding material..."); System.out.println("adding condiment..."); System.out.println("adding mealInfo..."); for (int i = 0, len = mealInfo.size(); i < len; i++) { System.out.println(" [" + mealInfo.get(i) + "]"); } } public void bake() { System.out.println("進(jìn)行打包,只需1分鐘就能打包完成!"); } public void getMeal() { System.out.println("外賣小哥獲取美食,外賣小哥可能需要花費1~20分鐘來獲取美食!"); } public void send() { System.out.println("配送給客戶,配送需要大概5~40分鐘送達(dá)!"); } }
4.這里模擬具體產(chǎn)品,必須去實現(xiàn)Meal接口或者去派生該抽象類,如下小龍蝦美食:CrayfishMeal.class。
/** * Author Eirunye * Created by on 2018/9/19. * Describe 模擬產(chǎn)品(具體的美食--小龍蝦) */ public class CrayfishMeal extends Meal { public CrayfishMeal() { setName("香辣小龍蝦....."); setMaterial("添加5份小龍蝦..."); setCondiment("添加適量的調(diào)味品..."); mealInfo.add("生成可口的小龍蝦..."); } }
5.測試
/** * Author Eirunye * Created by on 2018/9/19. * Describe */ public class Test { public static void main(String[] args) { //創(chuàng)建一個工廠類(即商品總店) MealStore mealStore = new MealStore(); //這里我們要傳遞在靜態(tài)工廠實例定義的字符串,否則將報空指針。 mealStore.submitOrderMeal("roastChicken"); } }
輸出結(jié)果:
"C:Program FilesJavajdk1.8.0_161injava"... 您的商品準(zhǔn)備中...燒雞..... adding material... adding condiment... adding mealInfo... [生成可口的燒雞...] 進(jìn)行打包,只需1分鐘就能打包完成! 外賣小哥獲取美食,外賣小哥可能需要花費1~20分鐘來獲取美食! 配送給客戶,配送需要大概5~40分鐘送達(dá)! Process finished with exit code 0
注:
首先我們將生產(chǎn)商品創(chuàng)建放在了靜態(tài)工廠中,靜態(tài)工廠處理對象創(chuàng)建的細(xì)節(jié),MealStore 美食店只關(guān)心如何得到美食商品就可以了,并進(jìn)行打包、獲取、派送等操作,而這樣操作起來方便了產(chǎn)品的創(chuàng)建了。
簡單工廠方法我們通過靜態(tài)工廠方法的方式實現(xiàn)了該功能,但是,是否有更好的封裝方式呢?接下來我們來分析一下吧。本例類圖關(guān)系
1.現(xiàn)在我們將MealStore.class,修改為抽象類,并且將生產(chǎn)商品的方法也修改為抽象方法,我們這樣做的目的,為什么呢?
我們這樣做是讓各個分店子類來實現(xiàn)商品的生產(chǎn),擴(kuò)展性更高,封裝性更加完善,而該抽象類并不知道是哪個子類來完成商品的創(chuàng)建,達(dá)到了耦合。代碼如下:
/** * Author Eirunye * Created by on 2018/9/18. * Describe 抽象工廠基類 美食總店 */ public abstract class MealStore { /** * 客戶下單 * * @param type 選擇什么樣的美食 * @return 美食 Meal */ public Meal submitOrderMeal(String type) { Meal meal; //這里是我們將生產(chǎn)的美食 meal = createMeal(type); //店家準(zhǔn)備中... meal.mealPreparation(); //打包 meal.bake(); //獲取 meal.getMeal(); //配送 meal.send(); return meal; } //實現(xiàn)抽象的工廠方法,讓每個分店來完成此生產(chǎn)操作, protected abstract Meal createMeal(String type); }
2.創(chuàng)建分店子類JiangNanMealStore .class派生自MealStore.class,進(jìn)行生產(chǎn)商品
/** * Author Eirunye * Created by on 2018/9/18. * Describe JiangNanMealStore分店,這里是需要增加修改的地方,可能有新的菜品的時候就在這里增加或者刪除*** */ public class JiangNanMealStore extends MealStore { @Override protected Meal createMeal(String type) { return getMeal(type); } //讓子類來創(chuàng)建產(chǎn)品 private Meal getMeal(String type) { if ("crayfish".equals(type)) { return new CrayfishMeal();//小龍蝦 } else if ("roastDuck".equals(type)) { return new RoastDuckMeal(); } else return null; } }
3.創(chuàng)建商品抽象基類Meal.class。
/** * Author Eirunye * Created by on 2018/9/18. * Describe 抽象產(chǎn)品父類 美食抽象類 */ public abstract class Meal { public List mealInfo = new ArrayList(); public void mealPreparation() { System.out.println("您的商品準(zhǔn)備中..."+this.name); System.out.println("adding material..."); System.out.println("adding condiment..."); System.out.println("adding mealInfo..."); for (int i = 0, len = mealInfo.size(); i < len; i++) { System.out.println(" [" + mealInfo.get(i) + "]"); } } public void bake() { System.out.println("進(jìn)行打包,只需1分鐘就能打包完成!"); } public void getMeal() { System.out.println("外賣小哥獲取美食,外賣小哥可能需要花費1~20分鐘來獲取美食!"); } public void send() { System.out.println("配送給客戶,配送需要大概5~40分鐘送達(dá)!"); } }
3.定義具體子類CrayfishMeal.class產(chǎn)品,擴(kuò)展自Meal .class
/** * Author Eirunye * Created by on 2018/9/18. * Describe 具體產(chǎn)品 小龍蝦美食 */ public class CrayfishMeal extends Meal { public CrayfishMeal() { setName("可口的小龍蝦....."); setMaterial("添加幾份小龍蝦+一些材料..."); setCondiment("添加適量的調(diào)味品..."); mealInfo.add("生成可口的小龍蝦..."); } //這里重寫了父類的方法 @Override public void bake() { System.out.println("小龍蝦分成5份打包!"); } }
4.測試
/** * Author Eirunye * Created by on 2018/9/18. * Describe */ public class Test { public static void main(String[] args) { MealStore jiangNanMealStore = new JiangNanMealStore(); jiangNanMealStore.submitOrderMeal("crayfish"); System.out.println("江南店完成一單"); System.out.println("============================== "); MealStore guangDongMealStore = new GuangDongMealStore(); guangDongMealStore.submitOrderMeal("roastDuck"); System.out.println("廣東店完成一單"); } }
輸出結(jié)果
"C:Program FilesJavajdk1.8.0_161injava"... 您的商品準(zhǔn)備中...可口的小龍蝦..... adding material... adding condiment... adding mealInfo... [生成可口的小龍蝦...] 小龍蝦分成5粉打包! 外賣小哥獲取美食,外賣小哥可能需要花費1~20分鐘來獲取美食! 配送給客戶,配送需要大概5~40分鐘送達(dá)! 江南店完成一單 ============================== 您的商品準(zhǔn)備中...江南烤鴨..... adding material... adding condiment... adding mealInfo... [生成可口的烤鴨...] 進(jìn)行打包,只需1分鐘就能打包完成! 外賣小哥獲取美食,外賣小哥可能需要花費1~20分鐘來獲取美食! 配送給客戶,配送需要大概5~40分鐘送達(dá)! 廣東店完成一單 Process finished with exit code 0下載
本篇案例代碼--碼云
本篇案例代碼--GitHub
設(shè)計模式系列--碼云
設(shè)計模式系列--GitHub
總結(jié)我們通過簡單的例子了解了簡單工廠模式的開發(fā)案例,其實,簡單工廠并不是我們常說的23中設(shè)計模式,他只是我們常用的一種編程習(xí)慣罷了,抽象工廠,才是我們常用的設(shè)計模式,接下來我們會講解到抽象工廠模式。
靜態(tài)工廠(簡單工廠)和簡單工廠方法有什么不同呢?
靜態(tài)工廠將生產(chǎn)商品都定義在靜態(tài)工廠的方法內(nèi),而簡單工廠方法是交給子類來完成。但是靜態(tài)工廠(簡單工廠)不具備簡單工廠方法所具有的擴(kuò)展性強。
簡單工廠方法的子類將會出現(xiàn)大量相同的代碼,但是同時它也可以重寫分類的方法,完成自己定義操作。
在Android中也常用到靜態(tài)工廠、或者是工廠方法等編程設(shè)計思路,如AnimationUtils類獲取的各個子類的動畫,BitmapFactory等
大家可以到我的博客https://eirunye.github.io進(jìn)行瀏覽相關(guān)文章,大家一起相互探討技術(shù)。
設(shè)計模式系列大家可以了解相關(guān)知識。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/77287.html
摘要:一簡單工廠定義簡單工廠其實并不屬于種設(shè)計模式之一,該模式是工廠方法模式的弱化或者說是工廠方法模式的一種特例,因為簡單,所以稱為簡單工廠模式,也叫做靜態(tài)工廠模式。 一、簡單工廠 定義 簡單工廠其實并不屬于23種GOF設(shè)計模式之一,該模式是工廠方法模式的弱化(或者說是工廠方法模式的一種特例),因為簡單,所以稱為簡單工廠模式(Simple Factory Pattern),也叫做靜態(tài)工廠模式...
摘要:工廠模式使一個類的實例化延遲到其子類。參考系列源地址系列目錄設(shè)計模式概述設(shè)計模式一簡單工廠模式設(shè)計模式二工廠方法模式設(shè)計模式三抽象工廠模式設(shè)計模式四單例模式 一、什么是簡單工廠模式 簡單工廠 (Simple Factory)又稱靜態(tài)工廠方法模式(Static Factory Method Pattern) 使用的頻率可以說是非常之高,它的官方解釋為:定義一個用于創(chuàng)建對象的接口,讓子...
摘要:基于工廠角色和產(chǎn)品角色的多態(tài)性設(shè)計是工廠方法模式的關(guān)鍵。工廠方法模式之所以又被稱為多態(tài)工廠模式,是因為所有的具體工廠類都具有同一抽象父類。工廠方法模式總結(jié)工廠方法模式是簡單工廠模式的進(jìn)一步抽象和推廣。 JavaScript工廠模式 首先需要說一下工廠模式。工廠模式根據(jù)抽象程度的不同分為三種 簡單工廠模式 工廠方法模式 抽象工廠模式 1.簡單工廠模式 簡單工廠模式:又稱為靜態(tài)工廠方法...
摘要:缺點需要慎重考慮是否增加工廠類進(jìn)行管理,因為會增加代碼的復(fù)雜度使用場景工廠模式是創(chuàng)建型模式的一種,其實就等價于對象,但是否將對象改造成工廠模式,使我們需要衡量的。 前言 最近北京天氣越來越冷了,同在北京的小伙伴大家注意保暖。不扯廢話了,讓我們直接進(jìn)入到工廠模式的學(xué)習(xí). 什么是工廠模式 定義一個用于創(chuàng)建對象的接口,讓子類決定實例化哪一個類。工廠方法使一個類的實例化延遲到子類。 UML類圖...
摘要:寫在前面一些關(guān)于自己在代碼設(shè)計思維方面的學(xué)習(xí)記錄面向?qū)ο蟮囊恍├斫鈱嵗a就不上了就寫一些總結(jié)封裝提供屬性和方法的權(quán)限管理只對外暴露接口具體的功能在內(nèi)部實現(xiàn)繼承子類繼承父類的方法和屬性可以抽離公共代碼減少代碼冗余多態(tài)同一個接口在子類中的不同 寫在前面: 一些關(guān)于自己在代碼設(shè)計思維方面的學(xué)習(xí)記錄 面向?qū)ο蟮囊恍├斫?實例代碼就不上了, 就寫一些總結(jié) 封裝: 提供屬性和方法的權(quán)限管理, ...
閱讀 1876·2021-09-28 09:36
閱讀 2426·2021-09-08 09:35
閱讀 3067·2019-08-30 15:53
閱讀 1554·2019-08-30 14:08
閱讀 665·2019-08-29 18:40
閱讀 2843·2019-08-29 13:57
閱讀 2702·2019-08-29 13:55
閱讀 681·2019-08-26 13:45