1.学习本篇文章,了解简单工厂设计模式的使用场景。
2.如何使用简单工厂模式。
3.简单工厂模式能解决什么问题?java
如今有一家外卖小店须要从生产一份外卖开始进行考虑设计,当客户在网上点出不一样味道的菜时,外卖小店就将按照不一样的订单进行生产出菜品,而后进行打包、等待外卖小哥获取、赠送给客户等不一样的几道工序,才算完成一单,可是后期因为生意很好,客户评价很高,有些地方的老板想加盟本店了,那么可能就会出现不一样味道的菜单,还有一些本地的特点菜也会加上菜单,这时,客户就能点到更多的菜品了,为了达到某些商家快速并且合理的进行管理,你是怎么设计这个方案的呢?git
通常状况下客户点餐的时候,都会查看平分高低,还有出货次数,若是人气好的,确定要大量生产,而没有人点的,则能够考虑去除,因此咱们经过以上的考虑,须要封装建立对象的代码,如将生产商品的对象封装起来,这样,咱们出掉或者添加的时候,都只修改这部分的代码,那么是哪一个生产商品呢?答案确定是店家了,因此咱们称这个生产商品的店家为“工厂”。
接下来咱们进行分析以上代码该如何展示出来呢?咱们将经过两种方式来进行编写。github
如何实现呢?咱们先来看看本例的类图编程
1.建立一个美食店,MealStore.class
设计模式
/** * Author Eirunye * Created by on 2018/9/19. * Describe */ public class MealStore { public Meal submitOrderMeal(String type) { Meal meal; //利用静态工厂方法生成产品 //重点(静态工厂实现代码) meal = SimpleMealsFactory.createMeal(type); //如下方法是进行一些设计而已不是静态工厂方法的模块,是产品的一些操做而已,可有可无的 //店家准备中... meal.mealPreparation(); //打包 meal.bake(); //获取 meal.getMeal(); //配送 meal.send(); return meal; } }
2.建立一个静态工厂SimpleMealsFactory.class
ide
/** * Author Eirunye * Created by on 2018/9/18. * Describe 创建一个简单静态工厂,该工厂生产不一样的菜品(美食) * Tip: 提示:这是否是咱们常用的Util类的编写方式? */ public class SimpleMealsFactory { //将生产产品(美食放在这里) public static Meal createMeal(String type) { Meal meal = null; if ("crayfish".equals(type)) { meal = new CrayfishMeal(); //建立什么类型的产品(美食)让子类来操做 } else if ("roastChicken".equals(type)) { meal = new RoastChicken(); } else if ("A".equals(type)) { } else if ("B".equals(type)) { } // ... return meal; //返回的是美食商品 } }
3.建立产品美食抽象基类Meal.class
,这样的话咱们就能够交给子类来完成商品的生产。学习
/** * Author Eirunye * Created by on 2018/9/19. * Describe 定义一个抽象产品接口、这里也能够是抽象类 */ public abstract class Meal { public List mealInfo = new ArrayList(); public void mealPreparation() { System.out.println("您的商品准备中..."+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("进行打包,只需1分钟就能打包完成!"); } public void getMeal() { System.out.println("外卖小哥获取美食,外卖小哥可能须要花费1~20分钟来获取美食!"); } public void send() { System.out.println("配送给客户,配送须要大概5~40分钟送达!"); } }
4.这里模拟具体产品,必须去实现Meal
接口或者去派生该抽象类,以下小龙虾美食:CrayfishMeal.class
。测试
/** * Author Eirunye * Created by on 2018/9/19. * Describe 模拟产品(具体的美食--小龙虾) */ public class CrayfishMeal extends Meal { public CrayfishMeal() { setName("香辣小龙虾....."); setMaterial("添加5份小龙虾..."); setCondiment("添加适量的调味品..."); mealInfo.add("生成可口的小龙虾..."); } }
5.测试动画
/** * Author Eirunye * Created by on 2018/9/19. * Describe */ public class Test { public static void main(String[] args) { //建立一个工厂类(即商品总店) MealStore mealStore = new MealStore(); //这里咱们要传递在静态工厂实例定义的字符串,不然将报空指针。 mealStore.submitOrderMeal("roastChicken"); } }
输出结果:this
"C:\Program Files\Java\jdk1.8.0_161\bin\java"... 您的商品准备中...烧鸡..... adding material... adding condiment... adding mealInfo... [生成可口的烧鸡...] 进行打包,只需1分钟就能打包完成! 外卖小哥获取美食,外卖小哥可能须要花费1~20分钟来获取美食! 配送给客户,配送须要大概5~40分钟送达! Process finished with exit code 0
首先咱们将生产商品建立放在了静态工厂中,静态工厂处理对象建立的细节,MealStore 美食店只关心如何获得美食商品就能够了,并进行打包、获取、派送等操做,而这样操做起来方便了产品的建立了。
咱们经过静态工厂方法的方式实现了该功能,可是,是否有更好的封装方式呢?接下来咱们来分析一下吧。本例类图关系
1.如今咱们将MealStore.class
,修改成抽象类,而且将生产商品的方法也修改成抽象方法,咱们这样作的目的,为何呢?
咱们这样作是让各个分店子类来实现商品的生产,扩展性更高,封装性更加完善,而该抽象类并不知道是哪一个子类来完成商品的建立,达到了耦合。代码以下:
/** * Author Eirunye * Created by on 2018/9/18. * Describe 抽象工厂基类 美食总店 */ public abstract class MealStore { /** * 客户下单 * * @param type 选择什么样的美食 * @return 美食 Meal */ public Meal submitOrderMeal(String type) { Meal meal; //这里是咱们将生产的美食 meal = createMeal(type); //店家准备中... meal.mealPreparation(); //打包 meal.bake(); //获取 meal.getMeal(); //配送 meal.send(); return meal; } //实现抽象的工厂方法,让每一个分店来完成今生产操做, protected abstract Meal createMeal(String type); }
2.建立分店子类JiangNanMealStore .class
派生自MealStore.class
,进行生产商品
/** * Author Eirunye * Created by on 2018/9/18. * Describe JiangNanMealStore分店,这里是须要增长修改的地方,可能有新的菜品的时候就在这里增长或者删除*** */ public class JiangNanMealStore extends MealStore { @Override protected Meal createMeal(String type) { return getMeal(type); } //让子类来建立产品 private Meal getMeal(String type) { if ("crayfish".equals(type)) { return new CrayfishMeal();//小龙虾 } else if ("roastDuck".equals(type)) { return new RoastDuckMeal(); } else return null; } }
3.建立商品抽象基类Meal.class
。
/** * Author Eirunye * Created by on 2018/9/18. * Describe 抽象产品父类 美食抽象类 */ public abstract class Meal { public List mealInfo = new ArrayList(); public void mealPreparation() { System.out.println("您的商品准备中..."+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("进行打包,只需1分钟就能打包完成!"); } public void getMeal() { System.out.println("外卖小哥获取美食,外卖小哥可能须要花费1~20分钟来获取美食!"); } public void send() { System.out.println("配送给客户,配送须要大概5~40分钟送达!"); } }
3.定义具体子类CrayfishMeal.class
产品,扩展自Meal .class
/** * Author Eirunye * Created by on 2018/9/18. * Describe 具体产品 小龙虾美食 */ public class CrayfishMeal extends Meal { public CrayfishMeal() { setName("可口的小龙虾....."); setMaterial("添加几份小龙虾+一些材料..."); setCondiment("添加适量的调味品..."); 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("==============================\n"); MealStore guangDongMealStore = new GuangDongMealStore(); guangDongMealStore.submitOrderMeal("roastDuck"); System.out.println("广东店完成一单"); } }
输出结果
"C:\Program Files\Java\jdk1.8.0_161\bin\java"... 您的商品准备中...可口的小龙虾..... adding material... adding condiment... adding mealInfo... [生成可口的小龙虾...] 小龙虾分红5粉打包! 外卖小哥获取美食,外卖小哥可能须要花费1~20分钟来获取美食! 配送给客户,配送须要大概5~40分钟送达! 江南店完成一单 ============================== 您的商品准备中...江南烤鸭..... adding material... adding condiment... adding mealInfo... [生成可口的烤鸭...] 进行打包,只需1分钟就能打包完成! 外卖小哥获取美食,外卖小哥可能须要花费1~20分钟来获取美食! 配送给客户,配送须要大概5~40分钟送达! 广东店完成一单 Process finished with exit code 0
咱们经过简单的例子了解了简单工厂模式的开发案例,其实,简单工厂并非咱们常说的23中设计模式,他只是咱们经常使用的一种编程习惯罢了,抽象工厂,才是咱们经常使用的设计模式,接下来咱们会讲解到抽象工厂模式。
静态工厂(简单工厂)和简单工厂方法有什么不一样呢?
静态工厂将生产商品都定义在静态工厂的方法内,而简单工厂方法是交给子类来完成。可是静态工厂(简单工厂)不具有简单工厂方法所具备的扩展性强。
简单工厂方法的子类将会出现大量相同的代码,可是同时它也能够重写分类的方法,完成本身定义操做。
在Android中也经常使用到静态工厂、或者是工厂方法等编程设计思路,如AnimationUtils类获取的各个子类的动画,BitmapFactory等
你们能够到个人博客https://eirunye.github.io进行浏览相关文章,你们一块儿相互探讨技术。
设计模式系列你们能够了解相关知识。