行爲型模式 | 建立型模式 | 結構型模式javascript
建立型模式是處理對象建立的設計模式,試圖根據實際狀況使用合適的方式建立對象。基本的對象建立方式可能會致使設計上的問題,或增長設計的複雜度。建立型模式經過以某種方式控制對象的建立來解決問題。java
來源: 維基百科git
抽象工廠模式提供了一種方式,能夠將一組具備同一主題的單獨的工廠封裝起來。在正常使用中,客戶端程序須要建立抽象工廠的具體實現,而後使用抽象工廠做爲接口來建立這一主題的具體對象。github
// 協議
protocol Decimal {
func stringValue() -> String
// 工廠
static func make(string: String) -> Decimal
}
typealias NumberFactory = (String) -> Decimal
// 工廠方法實現
struct NextStepNumber: Decimal {
private var nextStepNumber: NSNumber
func stringValue() -> String {
return nextStepNumber.stringValue
}
static func make(string: String) -> Decimal {
return NextStepNumber(nextStepNumber: NSNumber(value: (string as NSString).longLongValue))
}
}
struct SwiftNumber: Decimal {
private var swiftInt: Int
func stringValue() -> String {
return "\(swiftInt)"
}
static func make(string: String) -> Decimal {
return SwiftNumber(swiftInt: (string as NSString).integerValue)
}
}
// 抽象工廠
enum NumberType {
case nextStep, swift
}
enum NumberHelper {
static func factory(for type: NumberType) -> NumberFactory {
switch type {
case .nextStep:
return NextStepNumber.make
case .swift:
return SwiftNumber.make
}
}
}複製代碼
###用法:swift
let factoryOne = NumberHelper.factory(for: .nextStep)
let numberOne = factoryOne("1")
numberOne.stringValue()
let factoryTwo = NumberHelper.factory(for: .swift)
let nemberTwo = factoryTwo("2")
nemberTwo.stringValue()複製代碼
一種對象構建模式。它能夠將複雜對象的建造過程抽象出來(抽象類別),使這個抽象過程的不一樣實現方法能夠構造出不一樣表現(屬性)的對象。設計模式
class DeathStarBuilder {
var x: Double?
var y: Double?
var z: Double?
typealias BuilderClosure = (DeathStarBuilder) -> ()
init(buildClosure: BuilderClosure) {
buildClosure(self)
}
}
struct DeathStar: CustomStringConvertible {
let x: Double
let y: Double
let z: Double
init?(builder: DeathStarBuilder) {
if let x = builder.x, let y = builder.y, let z = builder.z {
self.x = x
self.y = y
self.z = z
} else {
return nil
}
}
var description: String {
return "Death Star at (x:\(x) y:\(y) z:\(z))"
}
}複製代碼
let empire = DeathStarBuilder { builder in
builder.x = 0.1
builder.y = 0.2
builder.z = 0.3
}
let deathStar = DeathStar(builder: empire)複製代碼
更多示例:Design Patterns in Swiftpost
定義一個建立對象的接口,但讓實現這個接口的類來決定實例化哪一個類。工廠方法讓類的實例化推遲到子類中進行。ui
protocol Currency {
func symbol() -> String
func code() -> String
}
class Euro: Currency {
func symbol() -> String {
return "€"
}
func code() -> String {
return "EUR"
}
}
class UnitedStatesDolar : Currency {
func symbol() -> String {
return "$"
}
func code() -> String {
return "USD"
}
}
enum Country {
case unitedStates, spain, uk, greece
}
enum CurrencyFactory {
static func currency(for country:Country) -> Currency? {
switch country {
case .spain, .greece :
return Euro()
case .unitedStates :
return UnitedStatesDolar()
default:
return nil
}
}
}複製代碼
let noCurrencyCode = "無可用貨幣碼"
CurrencyFactory.currency(for: .greece)?.code() ?? noCurrencyCode
CurrencyFactory.currency(for: .spain)?.code() ?? noCurrencyCode
CurrencyFactory.currency(for: .unitedStates)?.code() ?? noCurrencyCode
CurrencyFactory.currency(for: .uk)?.code() ?? noCurrencyCode複製代碼
經過「複製」一個已經存在的實例來返回新的實例,而不是新建實例。被複制的實例就是咱們所稱的「原型」,這個原型是可定製的。spa
class ChungasRevengeDisplay {
var name: String?
let font: String
init(font: String) {
self.font = font
}
func clone() -> ChungasRevengeDisplay {
return ChungasRevengeDisplay(font: self.font)
}
}複製代碼
let Prototype = ChungasRevengeDisplay(font:"GotanProject")
let Philippe = Prototype.clone()
Philippe.name = "Philippe"
let Christoph = Prototype.clone()
Christoph.name = "Christoph"
let Eduardo = Prototype.clone()
Eduardo.name = "Eduardo"複製代碼
更多示例:Design Patterns in Swiftprototype
單例對象的類必須保證只有一個實例存在。許多時候整個系統只須要擁有一個的全局對象,這樣有利於咱們協調系統總體的行爲
class DeathStarSuperlaser {
static let sharedInstance = DeathStarSuperlaser()
private init() {
}
}複製代碼
let laser = DeathStarSuperlaser.sharedInstance複製代碼