设计模式从入门到精通之(二)抽象工厂模式
抽象工厂模式:不同工厂背后的协作秘密
在上一期中,我们聊到了工厂模式,讲述了如何用一家咖啡店来帮我们制作不同类型的咖啡。那么,如果你不仅需要咖啡,还需要配套的甜品,比如蛋糕或饼干,这时应该怎么办呢?今天我们将引出一个进阶版的工厂模式:抽象工厂模式,来解决这个问题。
1. 什么是抽象工厂模式?
抽象工厂模式(Abstract Factory Pattern)
是一种创建型设计模式,它提供了一组用于创建相关或依赖对象的接口,而无需指定它们的具体类。换句话说,抽象工厂模式就像一个连锁品牌,你可以在这个品牌的任何分店下单,无论是咖啡、蛋糕还是饼干,所有的产品都是相互匹配的。
2. 用现实中的故事引出抽象工厂模式
还是用咖啡店的例子。假设你今天去咖啡店喝咖啡,发现菜单上不仅有咖啡,还有甜品搭配,比如:
- 美式咖啡 + 巧克力曲奇
- 拿铁咖啡 + 芝士蛋糕
你只需要告诉咖啡师你想要哪种套餐,他们就会为你准备好匹配的饮品和甜品,而不需要你逐一选择。这背后就是抽象工厂的思想:
- 一个工厂负责生产一组相关的产品。
- 通过选择工厂,统一获取搭配好的产品。
3. 抽象工厂模式的代码实现
我们用代码来模拟这个场景,看看如何用抽象工厂模式来制作咖啡和甜品。
3.1 抽象产品类
首先,定义两个抽象产品:咖啡和甜品。
// 抽象咖啡类
abstract class Coffee {
public abstract String getName();
}
// 抽象甜品类
abstract class Dessert {
public abstract String getName();
}
3.2 具体产品类
实现不同种类的咖啡和甜品。
// 美式咖啡
class AmericanCoffee extends Coffee {
@Override
public String getName() {
return "American Coffee";
}
}
// 拿铁咖啡
class LatteCoffee extends Coffee {
@Override
public String getName() {
return "Latte Coffee";
}
}
// 巧克力曲奇
class ChocolateCookie extends Dessert {
@Override
public String getName() {
return "Chocolate Cookie";
}
}
// 芝士蛋糕
class Cheesecake extends Dessert {
@Override
public String getName() {
return "Cheesecake";
}
}
3.3 抽象工厂
定义一个抽象工厂接口,负责创建相关的咖啡和甜品。
interface DessertFactory {
Coffee createCoffee();
Dessert createDessert();
}
3.4 具体工厂类
实现具体的工厂类,每个工厂负责创建一组相关的产品。
// 美式风味工厂
class AmericanFactory implements DessertFactory {
@Override
public Coffee createCoffee() {
return new AmericanCoffee();
}
@Override
public Dessert createDessert() {
return new ChocolateCookie();
}
}
// 意式风味工厂
class ItalianFactory implements DessertFactory {
@Override
public Coffee createCoffee() {
return new LatteCoffee();
}
@Override
public Dessert createDessert() {
return new Cheesecake();
}
}
3.5 客户端代码
客户端只需要选择一个工厂,就可以得到匹配的产品。
public class CoffeeShop {
public static void main(String[] args) {
// 创建美式风味工厂
DessertFactory americanFactory = new AmericanFactory();
Coffee americanCoffee = americanFactory.createCoffee();
Dessert chocolateCookie = americanFactory.createDessert();
System.out.println("Order: " + americanCoffee.getName() + " and " + chocolateCookie.getName());
// 创建意式风味工厂
DessertFactory italianFactory = new ItalianFactory();
Coffee latteCoffee = italianFactory.createCoffee();
Dessert cheesecake = italianFactory.createDessert();
System.out.println("Order: " + latteCoffee.getName() + " and " + cheesecake.getName());
}
}
运行结果:
Order: American Coffee and Chocolate Cookie
Order: Latte Coffee and Cheesecake
4. 抽象工厂模式的优缺点
优点:
- 产品族一致性:保证创建的产品彼此匹配。
- 可扩展性强:可以很方便地新增一个产品族(比如法式风味工厂)。
- 解耦:客户端代码与具体产品类完全解耦。
缺点:
- 复杂性提高:系统中会增加更多的类。
- 不够灵活:增加新产品(而非产品族)时,需要修改所有工厂类。
5. 总结
抽象工厂模式是工厂模式的升级版,适用于需要创建"一组相关产品"的场景。在实际开发中,它可以帮助我们更好地管理复杂的依赖关系,同时保持代码的高内聚和低耦合。
在下一篇专栏中,我们将介绍另一个重要的设计模式:单例模式,看看如何确保你的工厂在系统中只存在一个实例。
思考问题:
如果你需要为每个工厂增加一个新产品(比如茶饮),如何修改代码才能保持现有的结构?欢迎在评论区讨论!