设计模式-抽象工厂模式
引进抽象工厂模式
每一个模式都是针对一定问题的解决方案。抽象工厂模式与工厂方法模式的最大区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则需要面对多个产品等级结构。
在学习抽象工厂具体实例之前,应该明白两个重要的概念:产品族和产品等级。(内容转发此文章)
基本介绍
- 抽象工厂模式:定义了一个interface用于创建相关或有依赖关系的对象簇,而无需指明具体的类
- 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合
- 从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)
- 将工厂抽象成两层,AbsFactory(抽象工厂)和具体实现工厂子类。我们可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。
例子
我们以pizza店的例子来看看,分不同地区和不同口味来订购pizza。
类图设计:
@startuml abstract class Pizza{ + {abstract} void prepare() + void bake() + void cut() + void box() } class BJCheesePizza{ + {abstract} void prepare() } class BJPepperPizza{ + {abstract} void prepare() } class GZCheesePizza{ + {abstract} void prepare() } class GZPepperPizza{ + {abstract} void prepare() } Pizza <|-- BJCheesePizza Pizza <|-- BJPepperPizza Pizza <|-- GZCheesePizza Pizza <|-- GZPepperPizza interface AbsFactory{ + Pizza createPizza() } class BJFactory{ + Pizza createPizza() } class GZFactory{ + Pizza createPizza() } AbsFactory <-- BJFactory AbsFactory <-- GZFactory BJCheesePizza <.. BJFactory BJPepperPizza <.. BJFactory GZCheesePizza <.. GZFactory GZPepperPizza <.. GZFactory class OrderPizza{ } AbsFactory --o OrderPizza @enduml
生成的类图
代码
package Factory.AbsFactory /** * 抽象工作模式的抽象层 * */ interface AbsFactory { fun createPizza(orderType: String): Pizza? }
package Factory.AbsFactory abstract class Pizza { protected var name:String="" abstract fun prepare() fun bake(){ println("$name baking") } fun cut(){ println("$name cutting") } fun box(){ println("$name boxing") } }
package Factory.AbsFactory class BJCheesePizza : Pizza() { override fun prepare() { name = "Beijing Cheese pizza" println("preparing BeJin Cheese pizza") } }
package Factory.AbsFactory class BJPepperPizza : Pizza() { override fun prepare() { name = "Beijing Pepper pizza" println("preparing BeJin Pepper pizza") } }
package Factory.AbsFactory class GZCheesePizza : Pizza() { override fun prepare() { name = "GZ Cheese pizza" println("preparing GZ Cheese pizza") } }
package Factory.AbsFactory class GZPepperPizza : Pizza() { override fun prepare() { name = "GZ Pepper pizza" println("preparing GZ Pepper pizza") } }
package Factory.AbsFactory class BJFactory : AbsFactory { override fun createPizza(orderType: String): Pizza? { var pizza: Pizza? = null when (orderType) { "cheese" -> { pizza = BJCheesePizza() } "pepper" -> { pizza = BJPepperPizza() } } return pizza } }
package Factory.AbsFactory class GZFactory : AbsFactory { override fun createPizza(orderType: String): Pizza? { var pizza: Pizza? = null when (orderType) { "cheese" -> { pizza = GZCheesePizza() } "pepper" -> { pizza = GZPepperPizza() } } return pizza } }
package Factory.AbsFactory class OrderPizza constructor(factory: AbsFactory, orderType: String) { var factory: AbsFactory? = null var orderType = "" init { this.factory = factory this.orderType = orderType val pizza = factory.createPizza(orderType) if (pizza != null) { pizza.prepare() pizza.bake() pizza.cut() pizza.box() } else { println("Order Failure.") } } }
运行代码
val orderPizza = OrderPizza(GZFactory(),"cheese") println("======") val orderPizza2 = OrderPizza(GZFactory(),"a") println("======") val orderPizza3 = OrderPizza(BJFactory(),"pepper")
运行结果
preparing GZ Cheese pizza GZ Cheese pizza baking GZ Cheese pizza cutting GZ Cheese pizza boxing ====== Order Failure. ====== preparing BeJin Pepper pizza Beijing Pepper pizza baking Beijing Pepper pizza cutting Beijing Pepper pizza boxing
抽象工厂模式的优点
- 分离接口和实现
客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已。也就是说,客户端从具体的产品实现中解耦。
- 使切换产品族变得容易
因为一个具体的工厂实现代表的是一个产品族,比如上面例子的从Intel系列到AMD系列只需要切换一下具体工厂。
抽象工厂模式的缺点
- 不太容易扩展新的产品
如果需要给整个产品族添加一个新的产品,那么就需要修改抽象工厂,这样就会导致修改所有的工厂实现类。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)