作者有话要说
本文以奶茶为例,深入浅出地讲解工厂设计模式的三种分类,帮助读者轻松掌握这一概念。
一,什么是工厂设计模式
定义一个创建对象的接口,由子类决定实例化哪个类,将对象的创建延迟到子类。
例如:
如果没有奶茶店(工厂设计模式),你想喝珍珠奶茶就需要准备珍珠,牛奶等,还需要自己配方。如果你又想喝芋泥奶茶,你就又需要准备芋泥,还需要调整配方。
但是如果有了奶茶店(工厂设计模式),你想喝珍珠奶茶只需要给店员说一声就可以喝到,想喝芋泥奶茶也只需要说一声。而且奶茶店还可以拓展更多新品种的奶茶供你选择。
二,工厂设计模式的特点
核心:对象创建过程在子类中实现。
三,什么时候使用工厂设计模式
1.对象常见逻辑复杂,调用者无需关注细节。
- 如果new一个对象需要写5行以上的代码,就可以考虑使用工厂设计模式
2.需要支持多种产品类型,且可能频繁扩展。
- 存在支付宝支付,微信支付等多种支付方式,现在发明了银联支付可以直接支付。
3.需要统一管控对象的创建过程。
- 创建日志记录,在工厂中记录每个对象的创建时间,创建者。
4.需要创建一组配套的,相关的产品。
- 奶茶套餐,家具设计等。
四,工厂设计模式的代码解析
工厂设计模式可以分为三种类型,接下来就三种类型的代码进行解析
1.简单工厂模式(一个工厂生产不同的奶茶)
核心:定义一个工厂类,通过静态方法根据传入的参数,创建不同类型的产品对象。
适用场景:产品种类较少、变化不频繁的场景。
代码:
第一步:定义产品接口
// 第一步:定义产品接口(所有奶茶的共同行为) interface MilkTea { void make(); // 制作奶茶的方法 }第二步:实现具体产品类
// 珍珠奶茶类 class PearlMilkTea implements MilkTea { @Override public void make() { System.out.println("制作珍珠奶茶:煮茶底+加珍珠+调甜度"); } } //芋泥奶茶类 class TaroMilkTea implements MilkTea { @Override public void make() { System.out.println("制作芋泥奶茶:煮茶底+加芋泥+调甜度"); } }第三步:定义简单工厂类(核心:统一创建产品)
class MilkTeaFactory { // 静态工厂方法:根据参数返回不同的奶茶对象 public static MilkTea createMilkTea(String type) { if ("pearl".equals(type)) { return new PearlMilkTea(); } else if ("taro".equals(type)) { return new TaroMilkTea(); } else { throw new IllegalArgumentException("本店不卖,你可以去蜜雪冰城看看"); } } }第四步:测试一下
// 测试:调用者只需要传参数,不用关心创建过程 public class SimpleFactoryTest { public static void main(String[] args) { // 要珍珠奶茶 MilkTea pearlTea = MilkTeaFactory.createMilkTea("pearl"); pearlTea.make(); // 要芋泥奶茶 MilkTea taroTea = MilkTeaFactory.createMilkTea("taro"); taroTea.make(); } }2.工厂模式(不同的工厂生产不同的奶茶)
核心:将工厂抽象成接口 / 抽象类,每个具体产品对应一个具体工厂类,由具体工厂创建对应的产品。
适用场景:产品种类较多、需要频繁扩展的场景。
代码:
第一步:定义产品接口。
// 第一步:定义产品接口(和简单工厂一致) interface MilkTea { void make(); }第二步:实现具体产品类。
// 第二步:实现具体产品类(和简单工厂一致) class PearlMilkTea implements MilkTea { @Override public void make() { System.out.println("制作珍珠奶茶"); } } class TaroMilkTea implements MilkTea { @Override public void make() { System.out.println("制作芋泥奶茶"); } }第三步:定义工厂接口。
// 第三步:定义工厂接口(抽象工厂) interface MilkTeaFactory { MilkTea createMilkTea(); // 工厂方法:创建产品 }第四步:实现具体工厂类(每个产品对应一个工厂)。
// 第四步:实现具体工厂类(每个产品对应一个工厂) class PearlMilkTeaFactory implements MilkTeaFactory { @Override public MilkTea createMilkTea() { return new PearlMilkTea(); } } class TaroMilkTeaFactory implements MilkTeaFactory { @Override public MilkTea createMilkTea() { return new TaroMilkTea(); } }第五步:测试一下,调用者通过具体工厂获取产品。
// 测试:调用者通过具体工厂获取产品 public class FactoryMethodTest { public static void main(String[] args) { // 要珍珠奶茶:创建珍珠奶茶工厂,再生产产品 MilkTeaFactory pearlFactory = new PearlMilkTeaFactory(); MilkTea pearlTea = pearlFactory.createMilkTea(); pearlTea.make(); // 要芋泥奶茶:创建芋泥奶茶工厂,再生产产品 MilkTeaFactory taroFactory = new TaroMilkTeaFactory(); MilkTea taroTea = taroFactory.createMilkTea(); taroTea.make(); } }3.抽象工厂模式(一个工厂生产一组奶茶族:奶茶+小料)
核心:工厂不仅能创建一种产品,还能创建一组相关联、配套的产品(比如奶茶工厂不仅造奶茶,还能造配套的小料;汽车工厂不仅造汽车,还能造汽车轮胎、座椅)。
适用场景:需要创建一组配套产品的场景,比如系统的界面组件(Windows 风格的按钮 + 文本框、Mac 风格的按钮 + 文本框)。
代码:
第一步:定义一组产品接口(奶茶)
// 第一步:定义第一组产品接口(奶茶) interface MilkTea { void make(); } // 实现具体奶茶产品 class PearlMilkTea implements MilkTea { @Override public void make() { System.out.println("制作珍珠奶茶"); } } class TaroMilkTea implements MilkTea { @Override public void make() { System.out.println("制作芋泥奶茶"); } }第二步:定义第二组产品接口(小料)
// 第二步:定义第二组产品接口(小料) interface Topping { void add(); } // 实现具体小料产品 class PearlTopping implements Topping { @Override public void add() { System.out.println("添加珍珠小料"); } } class TaroTopping implements Topping { @Override public void add() { System.out.println("添加芋泥小料"); } }第三步:定义抽象工厂接口(能创建奶茶+小料一组产品)
// 第三步:定义抽象工厂接口(能创建奶茶+小料一组产品) interface MilkTeaSystemFactory { MilkTea createMilkTea(); // 创建奶茶 Topping createTopping(); // 创建配套小料 }第四步:实现具体工厂(珍珠奶茶+珍珠小料工厂)
// 第四步:实现具体工厂(珍珠奶茶+珍珠小料工厂) class PearlMilkTeaSystemFactory implements MilkTeaSystemFactory { @Override public MilkTea createMilkTea() { return new PearlMilkTea(); } @Override public Topping createTopping() { return new PearlTopping(); } } // 芋泥奶茶+芋泥小料工厂 class TaroMilkTeaSystemFactory implements MilkTeaSystemFactory { @Override public MilkTea createMilkTea() { return new TaroMilkTea(); } @Override public Topping createTopping() { return new TaroTopping(); } }第五步:测试一下,创建一组配套产品
// 测试:创建一组配套产品 public class AbstractFactoryTest { public static void main(String[] args) { // 珍珠奶茶套餐:珍珠奶茶+珍珠小料 MilkTeaSystemFactory pearlFactory = new PearlMilkTeaSystemFactory(); MilkTea pearlTea = pearlFactory.createMilkTea(); Topping pearlTopping = pearlFactory.createTopping(); pearlTea.make(); pearlTopping.add(); // 芋泥奶茶套餐:芋泥奶茶+芋泥小料 MilkTeaSystemFactory taroFactory = new TaroMilkTeaSystemFactory(); MilkTea taroTea = taroFactory.createMilkTea(); Topping taroTopping = taroFactory.createTopping(); taroTea.make(); taroTopping.add(); } }