本文对Design Patterns implemented in Swift 1.2 进了简单整理翻译。
常见的设计模式有行为模式(Behavioral)、创建模式(Creational)和结构模式(Structural)三种。
行为模式 Behavioral 在软件工程中, 行为型模式为设计模式的一种类型,用来识别对象之间的常用交流模式并加以实现。如此,可在进行这些交流活动时增强弹性。
责任链模 式Chain Of Responsibility 处理命令物件或将之传到下一个可以处理的物件。
例子 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 class MoneyPile { let value: Int var quantity: Int var nextPile: MoneyPile ? init (value : Int , quantity : Int , nextPile : MoneyPile ?) { self .value = value self .quantity = quantity self .nextPile = nextPile } func canWithdraw (var v : Int ) -> Bool { func canTakeSomeBill (want : Int ) -> Bool { return (want / self .value) > 0 } var q = self .quantity while canTakeSomeBill(v) { if q == 0 { break } v -= self .value q -= 1 } if v == 0 { return true } else if let next = self .nextPile { return next.canWithdraw(v) } return false } } class ATM { private var hundred: MoneyPile private var fifty: MoneyPile private var twenty: MoneyPile private var ten: MoneyPile private var startPile: MoneyPile { return self .hundred } init (hundred : MoneyPile , fifty : MoneyPile , twenty : MoneyPile , ten : MoneyPile ) { self .hundred = hundred self .fifty = fifty self .twenty = twenty self .ten = ten } func canWithdraw (value : Int ) -> String { return "Can withdraw: \(self .startPile.canWithdraw(value)) " } }
用法 1 2 3 4 5 6 7 8 9 10 11 12 let ten = MoneyPile (value: 10 , quantity: 6 , nextPile: nil )let twenty = MoneyPile (value: 20 , quantity: 2 , nextPile: ten)let fifty = MoneyPile (value: 50 , quantity: 2 , nextPile: twenty)let hundred = MoneyPile (value: 100 , quantity: 1 , nextPile: fifty)var atm = ATM (hundred: hundred, fifty: fifty, twenty: twenty, ten: ten)atm.canWithdraw(310 ) atm.canWithdraw(100 ) atm.canWithdraw(165 ) atm.canWithdraw(30 )
命令模式 在面向对象程式设计的范畴中,命令模式是一种设计模式,它尝试以物件来代表实际行动。命令物件可以把行动(action) 及其参数封装起来,于是这些行动可以被:重复多次、取消(如果该物件有实作的话)和取消后又再重做。
例子 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 protocol DoorCommand { func execute () -> String } class OpenCommand : DoorCommand { let doors:String required init (doors : String ) { self .doors = doors } func execute () -> String { return "Opened \(doors) " } } class CloseCommand : DoorCommand { let doors:String required init (doors : String ) { self .doors = doors } func execute () -> String { return "Closed \(doors) " } } class HAL9000DoorsOperations { let openCommand: DoorCommand let closeCommand: DoorCommand init (doors : String ) { self .openCommand = OpenCommand (doors:doors) self .closeCommand = CloseCommand (doors:doors) } func close () -> String { return closeCommand.execute() } func open () -> String { return openCommand.execute() } }
用法 1 2 3 4 5 let podBayDoors = "Pod Bay Doors" let doorModule = HAL9000DoorsOperations (doors:podBayDoors)doorModule.open() doorModule.close()
解释器模式 The interpreter pattern is used to evaluate sentences in a language.
例子 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 protocol IntegerExp { func evaluate (context : IntegerContext ) -> Int func replace (character : Character , integerExp : IntegerExp ) -> IntegerExp func copy () -> IntegerExp } class IntegerContext { private var data: [Character :Int ] = [:] func lookup (name : Character ) -> Int { return self .data[name]! } func assign (integerVarExp : IntegerVarExp , value : Int ) { self .data[integerVarExp.name] = value } } class IntegerVarExp : IntegerExp { let name: Character init (name : Character ) { self .name = name } func evaluate (context : IntegerContext ) -> Int { return context.lookup(self .name) } func replace (name : Character , integerExp : IntegerExp ) -> IntegerExp { if name == self .name { return integerExp.copy() } else { return IntegerVarExp (name: self .name) } } func copy () -> IntegerExp { return IntegerVarExp (name: self .name) } } class AddExp : IntegerExp { private var operand1: IntegerExp private var operand2: IntegerExp init (op1 : IntegerExp , op2 : IntegerExp ) { self .operand1 = op1 self .operand2 = op2 } func evaluate (context : IntegerContext ) -> Int { return self .operand1.evaluate(context) + self .operand2.evaluate(context) } func replace (character : Character , integerExp : IntegerExp ) -> IntegerExp { return AddExp (op1: operand1.replace(character, integerExp: integerExp), op2: operand2.replace(character, integerExp: integerExp)) } func copy () -> IntegerExp { return AddExp (op1: self .operand1, op2: self .operand2) } }
用法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 var expression: IntegerExp ?var intContext = IntegerContext ()var a = IntegerVarExp (name: "A" )var b = IntegerVarExp (name: "B" )var c = IntegerVarExp (name: "C" )expression = AddExp (op1: a, op2: AddExp (op1: b, op2: c)) intContext.assign(a, value: 2 ) intContext.assign(b, value: 1 ) intContext.assign(c, value: 3 ) var result = expression? .evaluate(intContext)