工廠模式
工廠方法模式通過選取相關的實現類來滿足呼叫元件的請求,呼叫元件無需瞭解這些實現。
何時使用
呼叫元件需要根據不同情況呼叫多個類的時候可以考慮使用工廠
下面是示例程式碼
///用基類實現更合適。協議感覺有點怪。特別是下面這個全域性函式
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…