protocol ModelType {}
struct Car: ModelType {
var name: String = ""
var speed: Int = 0
var price: Int = 0
var color: UIColor!
var createdAt: Date!
}
直接创建对象
没有使用任何模式的情况下,直接创建对象的方式,代码如下,
let bmwCar = Car(name: "BMW", speed: 125, price: 244000, color: UIColor.white, createdAt: Date())
创建第二个对象
let audiCar = Car(name: "Audi", speed: 120, price: 250000, color: UIColor.black, createdAt: Date())
这无疑写了很多重复代码,况且,若此时Car模型新增若干属性,例如,
struct Car: ModelType {
// 原来的属性
var name: String = ""
var speed: Int = 0
var price: Int = 0
var color: UIColor!
var createdAt: Date!
// 新增属性
var wheelNumber: Int = 0
var maxAge: Int = 0 // 使用寿命上限
}
此时创建对象是这样的,
// 三轮车
let threeWheelCar = Car.init(name: "三轮车", speed: 20, price: 10000, color: UIColor.red, createdAt: Date(), wheelNumber: 3, maxAge: 4)
这无疑为创建对象带来了麻烦,之前写的代码都要修改一遍。
使用工厂模式
protocol AbstractFactory {
associatedtype Product: ModelType
static func makeProduct() -> Product
}
class CarFactory: AbstractFactory {
static func makeProduct() -> Car {
let car = Car.init(name: "", speed: 0, price: 0, color: UIColor.white, createdAt: Date(), wheelNumber: 4, maxAge: 10)
}
}
let car = CarFactory.makeProduct()
print(car.createdAt)
使用这样的工厂模式,能够创建一个带有默认属性的Car,但是,因为方法签名- makeProduct
没有额外的参数,这样就不能创建指定属性的Car对象,当然我可以改一下AbstractFactory中的- makeProduct
签名,如下代码,
protocol AbstractFactory {
associatedtype Product: ModelType
static makeProduct(name: String, speed: Int, price: Int, color: UIColor, createdAt: Date, wheelNumber: Int, maxAge) -> Product
}
CarFactory: AbstractFactory {
static makeProduct(name: String, speed: Int, price: Int, color: UIColor, createdAt: Date, wheelNumber: Int, maxAge) -> Car {
let car = Car.init(name: "", speed: 0, price: 0, color: UIColor.white, createdAt: Date(), wheelNumber: 4, maxAge: 10)
return car
}
}
但是,这样实现,AbstractFactory的方法名不具备通用性,例如,想增加一个Bus类型,构建BusFactory实现AbstractFactory协议,此时,BusFactroy的实现如下,
struct Bus: ModelType {
var name: String = ""
var price: String = ""
var wheelNum: Int = 0
var maxAge: Int = 0
var maxPassengers: Int = 0 // 最大载客数
// 以及其他属性
// ....
}
class BusFactroy: AbstractFactory {
static makeProduct(name: String, speed: Int, price: Int, color: UIColor, createdAt: Date, wheelNumber: Int, maxAge) -> Bus {
// 尴尬了,因为方法名定义不具备通用性
// 现在不能创建Bus对象了
}
}
Question
so,我的疑问是,工厂模式的方法签名怎样定义,能具备通用性?
附:好像抽象工厂模式可以解决这种问题,帅帅,若有好的方案,能够分享下。
网友评论