【Java EE】工厂模式
工厂模式 为什么需要工厂模式简单工厂模式 核心思想️ 代码实现 优缺点分析工厂方法模式 核心思想️ 代码实现 优缺点分析抽象工厂模式 核心思想️ 代码实现 优缺点分析 总结与对比 为什么需要工厂模式假设你开了一家咖啡店代码是这样写的publicclassCoffeeStore{publicCoffeeorderCoffee(Stringtype){Coffeecoffeenull;if(americano.equals(type)){coffeenewAmericano();}elseif(latte.equals(type)){coffeenewLatte();}// 加糖加奶...returncoffee;}}问题来了如果现在要加一种卡布奇诺必须修改orderCoffee方法的源码这违反了开闭原则对扩展开放对修改关闭。而且咖啡店不仅负责卖咖啡还负责生产咖啡职责不单一。这时候我们把生产咖啡的活儿剥离出去交给专门的工厂来做。简单工厂模式简单工厂其实不属于 GoF 23 种设计模式但它太常用了可以说是工厂模式的入门。 核心思想定义一个工厂类根据传入的参数不同返回不同的对象实例。️ 代码实现// 1. 定义咖啡接口publicinterfaceCoffee{voidmake();}// 2. 具体咖啡实现publicclassAmericanoimplementsCoffee{Overridepublicvoidmake(){System.out.println(制作美式咖啡...);}}publicclassLatteimplementsCoffee{Overridepublicvoidmake(){System.out.println(制作拿铁咖啡...);}}// 3. 简单工厂类 (核心)publicclassSimpleCoffeeFactory{publicstaticCoffeecreateCoffee(Stringtype){if(americano.equals(type)){returnnewAmericano();}elseif(latte.equals(type)){returnnewLatte();}else{thrownewIllegalArgumentException(没有这种咖啡);}}}// 4. 咖啡店客户端publicclassCoffeeStore{publicCoffeeorderCoffee(Stringtype){// 咖啡店不自己生产交给工厂CoffeecoffeeSimpleCoffeeFactory.createCoffee(type);coffee.make();returncoffee;}} 优缺点分析优点客户端CoffeeStore免除了直接创建对象的职责解除了与具体产品的耦合。缺点违背了开闭原则。每增加一种咖啡都要修改SimpleCoffeeFactory里的if-else。工厂类的职责过重。工厂方法模式为了解决简单工厂违背开闭原则的问题我们升级一下。 核心思想定义一个用于创建对象的接口抽象工厂让子类决定实例化哪个类。将对象实例化推迟到子类。️ 代码实现// 1. 抽象工厂接口publicinterfaceCoffeeFactory{CoffeecreateCoffee();}// 2. 具体工厂实现publicclassAmericanoFactoryimplementsCoffeeFactory{OverridepublicCoffeecreateCoffee(){returnnewAmericano();}}publicclassLatteFactoryimplementsCoffeeFactory{OverridepublicCoffeecreateCoffee(){returnnewLatte();}}// 3. 咖啡店客户端publicclassCoffeeStore{// 聚合工厂接口不再依赖具体工厂privateCoffeeFactoryfactory;publicCoffeeStore(CoffeeFactoryfactory){this.factoryfactory;}publicCoffeeorderCoffee(){Coffeecoffeefactory.createCoffee();coffee.make();returncoffee;}}客户端调用// 想喝美式就开一家美式工厂注入进去CoffeeStorestorenewCoffeeStore(newAmericanoFactory());store.orderCoffee();// 想喝拿铁换一家拿铁工厂storenewCoffeeStore(newLatteFactory());store.orderCoffee(); 优缺点分析优点完美符合开闭原则。新增咖啡种类只需要新增一个Coffee实现类和一个对应的CoffeeFactory实现类完全不用改原有代码缺点类的数量成倍增加每个产品对应一个工厂。在系统复杂度较低时这种设计显得有些“重”。抽象工厂模式如果现在需求又升级了咖啡店不仅要卖咖啡还要卖甜点而且美式要配提拉米苏拿铁要配抹茶蛋糕它们是有组合关系的。这时候用工厂方法就需要建一堆工厂管理起来很乱。抽象工厂登场 核心思想提供一个创建一系列相关或相互依赖对象的接口而不指定它们具体的类。️ 代码实现// 1. 定义甜点接口publicinterfaceDessert{voidshow();}// 2. 具体甜点publicclassTiramisuimplementsDessert{Overridepublicvoidshow(){System.out.println(意大利提拉米苏);}}publicclassMatchaCakeimplementsDessert{Overridepublicvoidshow(){System.out.println(抹茶蛋糕);}}// 3. 抽象工厂 (现在是产品族的工厂了)publicinterfaceItalianDessertFactory{CoffeecreateCoffee();DessertcreateDessert();}// 4. 具体工厂 (美式风味工厂)publicclassAmericanStyleFactoryimplementsItalianDessertFactory{OverridepublicCoffeecreateCoffee(){returnnewAmericano();}OverridepublicDessertcreateDessert(){returnnewTiramisu();}}// 5. 具体工厂 (拿铁风味工厂)publicclassLatteStyleFactoryimplementsItalianDessertFactory{OverridepublicCoffeecreateCoffee(){returnnewLatte();}OverridepublicDessertcreateDessert(){returnnewMatchaCake();}}客户端调用// 买一套美式风味套餐ItalianDessertFactoryfactorynewAmericanStyleFactory();Coffeecoffeefactory.createCoffee();Dessertdessertfactory.createDessert();coffee.make();dessert.show(); 优缺点分析优点当一个产品族如咖啡甜点需要一起使用时它能保证客户端始终使用同一个族中的对象。缺点规定了所有可能被创建的产品集合扩展新产品比如新增“杯子”维度非常困难需要修改抽象工厂接口及其所有实现类严重违背开闭原则。 总结与对比别被这三个名字绕晕记住下面这张表模式核心特征if-else在哪扩展新产品扩展新产品族适用场景简单工厂一个具体工厂生产所有产品在工厂类里需改工厂代码不支持产品少逻辑简单工厂方法一个抽象工厂每个产品一个具体工厂没有了增加具体工厂即可不支持产品种类经常扩展抽象工厂一个抽象工厂生产一个产品族没有了非常困难增加具体工厂即可固定的产品族体系如UI换肤