今天我们所说的这种模式都是创建型设计模式
简单工厂模式
简单工厂模式实现了生成产品类的代码跟客户端代码的分离,在工厂类中你可以添加所需的生成产品的逻辑代码
简单工厂模式Swift代码
///简单工厂模式
/// 定义枚举来标识我们需要获得的汽车种类
enum CarType {
case bmw
case benz
// TODO: 如果客户现在需要奥迪汽车,新增奥迪种类
case audi
}
/// 产品需要实现的协议
protocol CarProduct {
func carProduct()
}
/// 宝马汽车
struct BmwCar: CarProduct {
func carProduct() {
print("宝马汽车")
}
}
/// 奔驰汽车
struct BenzCar: CarProduct {
func carProduct() {
print("奔驰汽车")
}
}
// TODO: 新增奥迪汽车
struct AudiCar: CarProduct {
func carProduct() {
print("奥迪汽车")
}
}
/// 汽车工厂生产汽车
struct CarFactory {
/// 根据客户端传入的type类型来决定创建什么类型的汽车
/// - Parameter type: 汽车类型
static func productCar(type: CarType) {
switch type {
case .benz:
let benz = BenzCar()
benz.carProduct()
case .bmw:
let bmw = BmwCar()
bmw.carProduct()
case .audi:
// TODO: 如果客户现在需要奥迪汽车,那么我们就要修改内部代码,新增switch循环判断,如果你的逻辑很复杂的话,这个就不很友好了
let audi = AudiCar()
audi.carProduct()
}
}
}
///客户端使用
///简单工厂模式
CarFactory.productCar(type: .bmw)
///打印: 宝马汽车
这个简单模式相信大家一看就懂,肯定也能看出来这种模式的缺陷
缺点
- 违背了
开放-封闭
原则,前面我们已经有了宝马和奔驰,那么接下来客户如果需要奥迪汽车,那我们只能去修改内部func productCar(type: CarType)
方法,进行switch
判断,如果你的逻辑很多,是不是又要改很多东西?这显然不太适合。对于这个问题,我们的工厂方法模式就可以解决这个问题。下面我们来介绍工厂方法模式。
工厂方法模式
定义
- 工厂方法是一种创建型设计模式,其在父类中提供一个创建对象的接口,允许子类决定实例化对象的类型。
适用性
- 当你在编写代码的过程中,如果无法预知对象确切类别及其依赖关系时,可使用工厂方法。
- 如果你希望用户能扩展你软件库或框架的内部组件, 可使用工厂方法。
- 如果你希望复用现有对象来节省系统资源,而不是每次都重新创建对象,可使用工厂方法。
优点
-
你可以避免创建者和具体产品之间的紧密耦合。
-
单一职责原则。你可以将产品创建代码放在程序的单一位置,从而使得代码更容易维护
-
开闭原则。无需更改现有客户端代码,你就可以在程序中引入新的产品类型。
缺点
- 应用工厂方法模式需要引入许多新的子类,代码可能会因此变得更复杂。最好的情况是将该模式引入创建者类的现有层次结构中。
工厂方法模式Swift代码:
///工厂模式
protocol FactoryCar {
func creatProductCar()
}
/// 宝马工厂
struct BmwFactory: FactoryCar {
func creatProductCar() {
let bmw = BmwFactoryCar()
bmw.carProduct()
}
}
/// 奔驰工厂
struct BenzFactory: FactoryCar {
func creatProductCar() {
let benz = BenzFactoryCar()
benz.carProduct()
}
}
//TODO: 新增奥迪工厂
struct AudiFactory: FactoryCar {
func creatProductCar() {
let audi = AudiFactoryCar()
audi.carProduct()
}
}
/// 产品需要实现的协议
protocol CarFactoryProduct {
func carProduct()
}
/// 生产宝马汽车
struct BmwFactoryCar: CarFactoryProduct {
func carProduct() {
print("宝马汽车")
}
}
/// 生产奔驰汽车
struct BenzFactoryCar: CarFactoryProduct {
func carProduct() {
print("奔驰汽车")
}
}
//TODO: 新增生产奥迪汽车
struct AudiFactoryCar: CarFactoryProduct {
func carProduct() {
print("奥迪汽车")
}
}
/// 定义枚举来标识我们需要获得的汽车种类
enum CarFactoryType {
case bmw
case benz
//TODO: 新增奥迪系列
case audi
}
/// 外部使用
struct CarFactoryMethod {
/// 根据客户端传入的type类型来决定创建什么类型的汽车
/// - Parameter type: 汽车类型
static func productCar(type: CarFactoryType) {
switch type {
case .benz:
let benz = BenzFactory()
benz.creatProductCar()
case .bmw:
let bmw = BmwFactory()
bmw.creatProductCar()
case .audi:
//TODO: 新增获取奥迪汽车
let audi = AudiFactory()
audi.creatProductCar()
}
}
}
抽象工厂模式
定义
- 抽象工厂是一种创建型设计模式,它能创建一系列相关的对象,而无需指定其具体类。
适用性
- 如果代码需要与多个不同系列的相关产品交互,但是由于无法提前获取相关信息,或者出于对未来扩展性的考虑,你不希望代码基于产品的具体类进行构建,在这种情况下,你可以使用抽象工厂。
- 如果你有一个基于一组抽象方法的类,且其主要功能因此变得不明确,那么在这种情况下可以考虑使用抽象工厂模式。
优点
-
你可以确保同一工厂生成的产品相互匹配。
-
你可以避免客户端和具体产品代码的耦合。
-
单一职责原则,你可以将产品生成代码抽取到同一位置, 使得代码易于维护。
-
开闭原则,向应用程序中引入新产品变体时, 你无需修改客户端代码。
缺点
- 由于采用该模式需要向应用中引入众多接口和类, 代码可能会比之前更加复杂。
抽象工厂模式Swift代码:
///抽象工厂模式 生产统一的种类 如:宝马汽车我需要宝马车标,奔驰需要奔驰车标,不要搞成宝马车贴成了奔驰车标,那就搞笑了
protocol AudoLogo {
func audoLogoMethod()
}
struct BmwAudoLogo: AudoLogo {
func audoLogoMethod() {
print("宝马车标")
}
}
struct BenzAudoLogo: AudoLogo {
func audoLogoMethod() {
print("奔驰车标")
}
}
struct AudiAudoLogo: AudoLogo {
func audoLogoMethod() {
print("奥迪车标")
}
}
protocol FactoryAudo {
func ceratLogo() -> AudoLogo
}
protocol FactoryACar {
func creatProductCar()
func creatLogo()
}
/// 宝马工厂
struct BmwAFactory: FactoryACar {
func creatLogo() {
let bmw = BmwAudoLogo()
bmw.audoLogoMethod()
}
func creatProductCar() {
let bmw = BmwAFactoryCar()
bmw.carProduct()
}
}
/// 奔驰工厂
struct BenzAFactory: FactoryACar {
func creatLogo() {
let benz = BmwAudoLogo()
benz.audoLogoMethod()
}
func creatProductCar() {
let benz = BenzAFactoryCar()
benz.carProduct()
}
}
//TODO: 新增奥迪工厂
struct AudiAFactory: FactoryACar {
func creatLogo() {
let audi = AudiAudoLogo()
audi.audoLogoMethod()
}
func creatProductCar() {
let audi = AudiAFactoryCar()
audi.carProduct()
}
}
/// 产品需要实现的协议
protocol CarAFactoryProduct {
func carProduct()
}
/// 生产宝马汽车
struct BmwAFactoryCar: CarAFactoryProduct {
func carProduct() {
print("宝马汽车")
}
}
/// 生产奔驰汽车
struct BenzAFactoryCar: CarAFactoryProduct {
func carProduct() {
print("奔驰汽车")
}
}
//TODO: 新增生产奥迪汽车
struct AudiAFactoryCar: CarAFactoryProduct {
func carProduct() {
print("奥迪汽车")
}
}
/// 定义枚举来标识我们需要获得的汽车种类
enum CarAFactoryType {
case bmw
case benz
//TODO: 新增奥迪系列
case audi
}
/// 外部使用
struct CarAFactoryMethod {
/// 根据客户端传入的type类型来决定创建什么类型的汽车
/// - Parameter type: 汽车类型
static func productCar(type: CarAFactoryType) {
switch type {
case .benz:
let benz = BenzAFactory()
benz.creatProductCar()
benz.creatLogo()
case .bmw:
let bmw = BmwAFactory()
bmw.creatProductCar()
bmw.creatLogo()
case .audi:
//TODO: 新增获取奥迪汽车
let audi = AudiAFactory()
audi.creatProductCar()
audi.creatLogo()
}
}
}
///打印数据:
奥迪汽车
奥迪车标
- 抽象工厂模式中我们可以定义实现不止一个协议,一个工厂也可以生成不止一个产品类,抽象工厂模式较好的实现了“开放-封闭”原则,是三个模式中较为抽象,并具一般性的模式。按照我的理解是:只要是同一个种类需要增加不同产品,都可以使用抽象模式,采用同一工厂去生产产品
- 文中如有问题,请大家指明一下,互相学习,互相进步(通过自己的理解来一步一步实现的,避免理解有误,还请大家监督,谢谢)
不管我们遇到什么困难,也不要怕,微笑着面对它,消除恐惧的最好办法就是面对恐惧,坚持,才是胜利,加油,奥利给!!