工厂模式
工厂方法模式通过选取相关的实现类来满足调用组件的请求,调用组件无需了解这些实现。
何时使用
调用组件需要根据不同情况调用多个类的时候可以考虑使用工厂
下面是示例代码
///用基类实现更合适。协议感觉有点怪。特别是下面这个全局函数
func createRentalCar(by passengers:Int) -> RentalCar? {
var car:RentalCar?
switch passengers {
case 0...1:
car = Sports()
case 2...3:
car = Compact()
case 4...8:
car = SUV()
case 9...14:
car = Minivan()
default:
car = nil
}
return car
}
///RentalCar.swift
protocol RentalCar {
var name:String { get }
var passengers:Int { get }
var pricePerDay:Float { get }
}
class Compact: RentalCar {
var name: String = "VM Golf"
var passengers: Int = 3
var pricePerDay: Float = 20
}
class Sports: RentalCar {
var name: String = "Porsche Boxter"
var passengers: Int = 1
var pricePerDay: Float = 100
}
class SUV: RentalCar {
var name: String = "Cadillac Escalade"
var passengers: Int = 8
var pricePerDay: Float = 75
}
//CarSelector.swift
class CarSelector{
class func selectCar(by passengers:Int) -> String?{
let car = createRentalCar(by: passengers)
return car?.name
}
}
//main.swift
let passengers = [1,3,5]
for p in passengers{
print("\(p) passegers: \(CarSelector.selectCar(by: p) ?? "")")
}
class PriceCalculator {
class func calculatePrice(by passengers:Int,and totalDays:Int) -> Float?{
if let car = createRentalCar(by: passengers) {
return car.pricePerDay * Float(totalDays)
}
return nil
}
}
输出
Hello, World!
1 passegers: Porsche Boxter
3 passegers: VM Golf
5 passegers: Cadillac Escalade
Program ended with exit code: 0
抽象工厂
和简单工厂不一样的是,这个模式可以提供一组对象。
好处:可以在不修改调用组件的情况下,对其使用的类进行修改
什么时候使用:
当调用组件需要一组互相关联的对象,但这些对象又没有共同的父类和协议的时候。
下面是示例代码。创建一个命令行项目AbstractFactory
///FloorPlans.swift
enum EngineOption : String{
case front = "Front"
case mid = "Mid"
}
protocol Floorplan {
var seats:Int{ get }
var enginePosition:EngineOption { get }
}
class ShortFloorplan: Floorplan {
var seats: Int = 2
var enginePosition: EngineOption = .mid
}
class StandardFloorplan: Floorplan {
var seats: Int = 4
var enginePosition: EngineOption = .front
}
class LongFloorplan: Floorplan {
var seats: Int = 8
var enginePosition: EngineOption = .front
}
///Suspension.swift
enum SuspensionOption : String{
case standard = "Standard"
case sports = "Firm"
case soft = "Soft"
}
protocol Suspension {
var suspensionType:SuspensionOption { get }
}
class RoadSuspension: Suspension {
var suspensionType: SuspensionOption = .standard
}
class OffRoadSuspension: Suspension {
var suspensionType: SuspensionOption = .soft
}
class RaceSuspension: Suspension {
var suspensionType: SuspensionOption = .sports
}
///Drivetrains.swift
enum DriveOption : String{
case front = "Front"
case rear = "Rear"
case all = "4WD"
}
protocol Drivetrain {
var driveType:DriveOption { get }
}
class FrontWheelDrive: Drivetrain {
var driveType: DriveOption = .front
}
class RearWheelDrive: Drivetrain {
var driveType: DriveOption = .rear
}
class AllWheelDrive: Drivetrain {
var driveType: DriveOption = .all
}
///CarParts.swift
enum Cars : String {
case compact = "VM Golf"
case sports = "Porsche Boxter"
case suv = "Cadillac Escalade"
}
struct Car {
var carType:Cars
var floor:Floorplan
var suspension:Suspension
var drive:Drivetrain
func printDetail() {
print("Car type: \(carType.rawValue)")
print("Seats : \(floor.seats)")
print("Engine : \(floor.enginePosition.rawValue)")
print("Suspension : \(suspension.suspensionType.rawValue)")
print("Drive : \(drive.driveType.rawValue)")
}
}
///Abstract.swift
class CarFactory {
final class func getFactory(car:Cars) -> CarFactory {
var factory:CarFactory
switch car {
case .compact:
factory = CompactCarFactory()
case .sports:
factory = SportsCarFactory()
case .suv:
factory = SUVCarFactory()
}
return factory
}
func createFloorplan() -> Floorplan {
fatalError("no implemention")
}
func createSuspension() -> Suspension {
fatalError("no implemention")
}
func createDrivetrain() -> Drivetrain {
fatalError("no implemention")
}
}
///Concrete.swift
class CompactCarFactory : CarFactory {
override func createFloorplan() -> Floorplan {
return StandardFloorplan()
}
override func createSuspension() -> Suspension {
return RoadSuspension()
}
override func createDrivetrain() -> Drivetrain {
return FrontWheelDrive()
}
}
class SportsCarFactory: CarFactory {
override func createFloorplan() -> Floorplan {
return ShortFloorplan()
}
override func createSuspension() -> Suspension {
return RaceSuspension()
}
override func createDrivetrain() -> Drivetrain {
return RearWheelDrive()
}
}
class SUVCarFactory: CarFactory {
override func createFloorplan() -> Floorplan {
return LongFloorplan()
}
override func createSuspension() -> Suspension {
return OffRoadSuspension()
}
override func createDrivetrain() -> Drivetrain {
return AllWheelDrive()
}
}
工程代码下载地址github.com/RockyAo/Des…