【HeadFirst系列之HeadFirst设计模式】第5天之工厂模式:比萨店的秘密武器,轻松搞定对象创建!
- 开源代码
- 2025-08-28 04:00:01

工厂模式:比萨店的秘密武器,轻松搞定对象创建!
大家好,今天我们来聊聊设计模式中的工厂模式。如果你曾经为对象的创建感到头疼,或者觉得代码中到处都是 new 关键字,那么工厂模式就是你的救星!本文基于《Head First 设计模式》的工厂模式章节,带你从比萨店的故事中轻松掌握工厂模式的精髓,附上 Java 代码示例,让你彻底理解并爱上它!
1. 简单工厂模式:比萨店的起步 故事背景
小明开了一家比萨店,刚开始只有两种比萨:芝士比萨和素食比萨。每次接到订单,小明都会根据客户的需求,手动创建对应的比萨对象。
问题出现随着生意越来越好,比萨的种类也越来越多。小明发现,每次新增一种比萨,都需要修改订单处理的代码。这不仅麻烦,还容易出错。
解决方案:简单工厂模式小明决定引入简单工厂模式,将比萨的创建逻辑集中到一个工厂类中。这样,无论比萨种类如何变化,订单处理的代码都不需要修改。
代码实现 // 比萨接口 interface Pizza { void prepare(); void bake(); } // 具体比萨:芝士比萨 class CheesePizza implements Pizza { @Override public void prepare() { System.out.println("Preparing Cheese Pizza"); } @Override public void bake() { System.out.println("Baking Cheese Pizza"); } } // 具体比萨:素食比萨 class VeggiePizza implements Pizza { @Override public void prepare() { System.out.println("Preparing Veggie Pizza"); } @Override public void bake() { System.out.println("Baking Veggie Pizza"); } } // 简单工厂 class SimplePizzaFactory { public Pizza createPizza(String pizzaType) { if (pizzaType.equals("cheese")) { return new CheesePizza(); } else if (pizzaType.equals("veggie")) { return new VeggiePizza(); } else { throw new IllegalArgumentException("Unknown pizza type"); } } } // 客户端代码 public class PizzaStore { public static void main(String[] args) { SimplePizzaFactory factory = new SimplePizzaFactory(); Pizza pizza = factory.createPizza("cheese"); pizza.prepare(); // 输出: Preparing Cheese Pizza pizza.bake(); // 输出: Baking Cheese Pizza } } 优点 将对象的创建逻辑集中在一个类中,便于维护。客户端与具体产品解耦。 缺点 违反“开闭原则”,新增产品时需要修改工厂类。2. 工厂方法模式:扩展比萨帝国 故事背景
小明的比萨店越做越大,他决定开分店!每个分店都有自己的特色比萨,比如纽约风味芝士比萨和芝加哥风味素食比萨。
问题出现如果继续使用简单工厂模式,每次新增分店都需要修改工厂类,这显然不够灵活。
解决方案:工厂方法模式小明决定采用工厂方法模式,将比萨的创建延迟到子类。每个分店都可以实现自己的比萨创建逻辑。
代码实现 // 比萨接口 interface Pizza { void prepare(); void bake(); } // 具体比萨:纽约风味芝士比萨 class NYCheesePizza implements Pizza { @Override public void prepare() { System.out.println("Preparing NY Style Cheese Pizza"); } @Override public void bake() { System.out.println("Baking NY Style Cheese Pizza"); } } // 具体比萨:芝加哥风味素食比萨 class ChicagoVeggiePizza implements Pizza { @Override public void prepare() { System.out.println("Preparing Chicago Style Veggie Pizza"); } @Override public void bake() { System.out.println("Baking Chicago Style Veggie Pizza"); } } // 工厂接口 abstract class PizzaStore { public Pizza orderPizza(String type) { Pizza pizza = createPizza(type); pizza.prepare(); pizza.bake(); return pizza; } // 工厂方法 protected abstract Pizza createPizza(String type); } // 具体工厂:纽约比萨店 class NYPizzaStore extends PizzaStore { @Override protected Pizza createPizza(String type) { if (type.equals("cheese")) { return new NYCheesePizza(); } else { throw new IllegalArgumentException("Unknown pizza type"); } } } // 具体工厂:芝加哥比萨店 class ChicagoPizzaStore extends PizzaStore { @Override protected Pizza createPizza(String type) { if (type.equals("veggie")) { return new ChicagoVeggiePizza(); } else { throw new IllegalArgumentException("Unknown pizza type"); } } } // 客户端代码 public class PizzaTest { public static void main(String[] args) { PizzaStore nyStore = new NYPizzaStore(); Pizza pizza = nyStore.orderPizza("cheese"); // 输出: Preparing NY Style Cheese Pizza, Baking NY Style Cheese Pizza PizzaStore chicagoStore = new ChicagoPizzaStore(); pizza = chicagoStore.orderPizza("veggie"); // 输出: Preparing Chicago Style Veggie Pizza, Baking Chicago Style Veggie Pizza } } 优点 符合“开闭原则”,新增产品时只需扩展子类。将对象的创建逻辑分散到子类,降低了耦合度。 缺点 类的数量会增加,系统复杂度提高。3. 抽象工厂模式:比萨与饮料的完美搭配 故事背景
小明发现,客户不仅喜欢比萨,还喜欢搭配饮料。于是,他决定推出套餐,每个套餐包含一款比萨和一款饮料。
问题出现如果使用工厂方法模式,比萨和饮料的创建逻辑会分散在不同的工厂中,难以保证它们之间的兼容性。
解决方案:抽象工厂模式小明决定采用抽象工厂模式,将比萨和饮料的创建逻辑集中到一个工厂中,确保每个套餐的比萨和饮料是兼容的。
代码实现 // 比萨接口 interface Pizza { void prepare(); } // 饮料接口 interface Drink { void serve(); } // 具体比萨:纽约风味芝士比萨 class NYCheesePizza implements Pizza { @Override public void prepare() { System.out.println("Preparing NY Style Cheese Pizza"); } } // 具体饮料:纽约风味可乐 class NYCoke implements Drink { @Override public void serve() { System.out.println("Serving NY Style Coke"); } } // 具体比萨:芝加哥风味素食比萨 class ChicagoVeggiePizza implements Pizza { @Override public void prepare() { System.out.println("Preparing Chicago Style Veggie Pizza"); } } // 具体饮料:芝加哥风味雪碧 class ChicagoSprite implements Drink { @Override public void serve() { System.out.println("Serving Chicago Style Sprite"); } } // 抽象工厂接口 interface MealFactory { Pizza createPizza(); Drink createDrink(); } // 具体工厂:纽约风味套餐 class NYMealFactory implements MealFactory { @Override public Pizza createPizza() { return new NYCheesePizza(); } @Override public Drink createDrink() { return new NYCoke(); } } // 具体工厂:芝加哥风味套餐 class ChicagoMealFactory implements MealFactory { @Override public Pizza createPizza() { return new ChicagoVeggiePizza(); } @Override public Drink createDrink() { return new ChicagoSprite(); } } // 客户端代码 public class MealTest { public static void main(String[] args) { MealFactory nyFactory = new NYMealFactory(); Pizza pizza = nyFactory.createPizza(); Drink drink = nyFactory.createDrink(); pizza.prepare(); // 输出: Preparing NY Style Cheese Pizza drink.serve(); // 输出: Serving NY Style Coke MealFactory chicagoFactory = new ChicagoMealFactory(); pizza = chicagoFactory.createPizza(); drink = chicagoFactory.createDrink(); pizza.prepare(); // 输出: Preparing Chicago Style Veggie Pizza drink.serve(); // 输出: Serving Chicago Style Sprite } } 优点 可以创建一组相关的对象,保证它们之间的兼容性。符合“开闭原则”,新增产品族时只需扩展工厂类。 缺点 类的数量会大幅增加,系统复杂度提高。总结
工厂模式的核心思想是将对象的创建与使用分离,从而使得系统更加灵活和可维护。三种工厂模式各有优缺点:
简单工厂模式:适合创建逻辑简单的场景,但违反“开闭原则”。工厂方法模式:通过子类实现对象的创建,符合“开闭原则”,但会增加类的数量。抽象工厂模式:适合创建一组相关对象的场景,但系统复杂度较高。在实际开发中,应根据具体需求选择合适的工厂模式,以达到代码的高内聚、低耦合。希望本文能帮助你更好地理解工厂模式,并在项目中灵活运用!
互动话题 你在项目中用过工厂模式吗?遇到过哪些问题?欢迎在评论区分享你的经验!
【HeadFirst系列之HeadFirst设计模式】第5天之工厂模式:比萨店的秘密武器,轻松搞定对象创建!由讯客互联开源代码栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【HeadFirst系列之HeadFirst设计模式】第5天之工厂模式:比萨店的秘密武器,轻松搞定对象创建!”