0x1、定义
一般将工厂模式细分为种:简单工厂
、工厂方法
和 抽象工厂
,前两个在项目中用得多一些。
适用场景:创建一个对象,但创建过程比较复杂,希望对外隐藏这些细节。
注意!适用于对象创建过程比较复杂的场景,一般是这两类:创建过程涉及复杂的if-else分支判断 和 复杂依赖 (如new A(new B(new C()))),应用工厂模式无疑会带来类文件的增加,简单的场景直接new构造不香吗?
接下来通过一个简单的奶茶店案例来引入这几种模式的使用,先是面向过程(OOP)的写法:
public class TeaStoreTest { public static String make(int type) { String teaName = null; if (type == 0) { teaName = "珍珠奶茶"; } else if (type == 1) { teaName = "港式奶茶"; } else if (type == 2) { teaName = "冰奶茶"; } else if (type == 3) { teaName = "冻柠茶"; } return teaName; } public static void main(String[] args) { for (int i = 0; i < 5; i++) { String teaName = make(new Random().nextInt(5)); if (teaName != null) { System.out.println("产出一杯:" + teaName); } else { System.out.println("本店暂无此款茶饮~"); } } } }
运行结果如下:
网络异常,图片无法展示
|
把奶茶名生成的步骤包裹在make()方法中,传入不同的type,返回不同的奶茶名。接着转换下思路,OOP面向对象思想,可以将这部分逻辑剥离到一个独立的类中,让这个类只负责 奶茶名的创建。
// 生产奶茶的类 public class OldTeaStore { public String make(int type) { String teaName = null; if (type == 0) { teaName = "珍珠奶茶"; } else if (type == 1) { teaName = "港式奶茶"; } else if (type == 2) { teaName = "冰奶茶"; } else if (type == 3) { teaName = "冻柠茶"; } return teaName; } } // 测试用例 public class OldTeaStoreTest { public static void main(String[] args) { OldTeaStore store = new OldTeaStore(); for (int i = 0; i < 5; i++) { String teaName = store.make(new Random().nextInt(5)); if (teaName != null) { System.out.println("产出一杯:" + teaName); } else { System.out.println("本店暂无此款茶饮~"); } } } }
① 简单工厂 (Simple Factory)
不变的只有变化本身,而需求是不断变化的,现在单单一个奶茶名可不够,可能还要奶茶容量、价格等,基于封装和抽象的思想,我们抽象出一个Tea类,包含一个createTea() 生产奶茶的方法,并实现四个具体的茶类。
// 抽象的茶 public abstract class Tea { protected abstract String createTea(); } // 具体的茶 public class TapiocaMilkTea extends Tea { @Override protected String createTea() { return "珍珠奶茶"; } } public class HKStyleHotTea extends Tea { @Override protected String createTea() { return "港式奶茶"; } } public class IcedMilkTea extends Tea { @Override protected String createTea() { return "冰奶茶"; } } public class IcedLemonTea extends Tea { @Override protected String createTea() { return "冻柠茶"; } }
接着是生产奶茶的类:
// 创建Tea实例的类 public class NewTeaStore { public String exchange(int type) { String teaName = ""; if (type == 0) { teaName = "珍珠奶茶"; } else if (type == 1) { teaName = "港式奶茶"; } else if (type == 2) { teaName = "冰奶茶"; } else if (type == 3) { teaName = "冻柠茶"; } return teaName; } public Tea make(int type) { String teaName = exchange(type); Tea tea = null; if (teaName.equals("珍珠奶茶")) { tea = new TapiocaMilkTea(); } else if (teaName.equals("港式奶茶")) { tea = new HKStyleHotTea(); } else if (teaName.equals("冰奶茶")) { tea = new IcedMilkTea(); } else if (teaName.equals("冻柠茶")) { tea = new IcedLemonTea(); } return tea; } } // 测试用例 public class NewTeaStoreTest { public static void main(String[] args) { NewTeaStore store = new NewTeaStore(); for (int i = 0; i < 5; i++) { Tea tea = store.make(new Random().nextInt(5)); if (tea != null) { System.out.println("产出一杯:" + tea.createTea()); } else { System.out.println("本店暂无此款茶饮~ "); } } } }