抽象工厂模式是在简单工厂的基础上将未来可能需要修改的代码抽象出来,通过继承的方式让子类去做决定。
简单工厂的问题: 如果使用简单工厂,每次需要新增品类(如从咖啡变为啤酒)时,都需要修改工厂类的
代码,这违反了开闭原则。
开闭原则: 即软件实体(类、模块、函数等)应该对扩展开放,对修改关闭
抽象工厂的解决方案: 使用抽象工厂模式,通过定义抽象工厂接口或抽象类来声明创建产品的方法。具体的产品工厂(如咖啡工厂、啤酒工厂)继承这个抽象工厂并实现具体的方法。这样,当需要新增品类时,只需要创建新的具体工厂类,而不需要修改现有的工厂代码。
示例比较
简单工厂模式
// 产品接口
public interface Drink {
void drink();
}
// 具体产品类
public class Coffee implements Drink {
@Override
public void drink() {
System.out.println("Drinking coffee");
}
}
public class Beer implements Drink {
@Override
public void drink() {
System.out.println("Drinking beer");
}
}
// 简单工厂类
public class SimpleDrinkFactory {
public static Drink createDrink(String type) {
switch (type) {
case "Coffee":
return new Coffee();
case "Beer":
return new Beer();
default:
throw new IllegalArgumentException("Unknown drink type");
}
}
}
// 测试简单工厂模式
public class SimpleFactoryDemo {
public static void main(String[] args) {
Drink coffee = SimpleDrinkFactory.createDrink("Coffee");
coffee.drink();
Drink beer = SimpleDrinkFactory.createDrink("Beer");
beer.drink();
}
}
在简单工厂模式中,每次新增产品(如新增一个新的饮料),都需要修改 SimpleDrinkFactory 类的 createDrink 方法。假如我们要新增一个新的饮料类 Tea:
public class Tea implements Drink {
@Override
public void drink() {
System.out.println("Drinking tea");
}
}
// 修改简单工厂类
public class SimpleDrinkFactory {
public static Drink createDrink(String type) {
switch (type) {
case "Coffee":
return new Coffee();
case "Beer":
return new Beer();
case "Tea":
return new Tea();
default:
throw new IllegalArgumentException("Unknown drink type");
}
}
}
这种做法需要修改 SimpleDrinkFactory 的代码,不符合开闭原则。
抽象工厂模式
// 抽象产品接口
public interface Drink {
void drink();
}
// 具体产品类
public class Coffee implements Drink {
@Override
public void drink() {
System.out.println("Drinking coffee");
}
}
public class Beer implements Drink {
@Override
public void drink() {
System.out.println("Drinking beer");
}
}
// 抽象工厂接口
public interface DrinkFactory {
Drink createDrink();
}
// 具体工厂类:咖啡工厂
public class CoffeeFactory implements DrinkFactory {
@Override
public Drink createDrink() {
return new Coffee();
}
}
// 具体工厂类:啤酒工厂
public class BeerFactory implements DrinkFactory {
@Override
public Drink createDrink() {
return new Beer();
}
}
// 新增具体工厂类:茶工厂
public class TeaFactory implements DrinkFactory {
@Override
public Drink createDrink() {
return new Tea();
}
}
// 测试抽象工厂模式
public class AbstractFactoryDemo {
public static void main(String[] args) {
DrinkFactory coffeeFactory = new CoffeeFactory();
Drink coffee = coffeeFactory.createDrink();
coffee.drink();
DrinkFactory beerFactory = new BeerFactory();
Drink beer = beerFactory.createDrink();
beer.drink();
// 新增茶的工厂和使用
DrinkFactory teaFactory = new TeaFactory();
Drink tea = teaFactory.createDrink();
tea.drink();
}
}
对比和总结
- 修改现有代码:简单工厂模式在新增产品时需要修改工厂类代码,不符合开闭原则;抽象工厂模式只需添加新的具体工厂类,无需修改已有代码,符合开闭原则。
- 代码结构:简单工厂模式结构简单,适用于产品种类较少的情况;抽象工厂模式结构更复杂,但更灵活,适用于产品种类多且变化频繁的情况。
- 扩展性:抽象工厂模式的扩展性更好,可以轻松添加新的产品和工厂,而不影响现有代码。