Swift語言之命令模式(Command Pattern)實現

今天遇到這樣一個問題,我如今有一個整數數組,如:設計模式

var numbers = [3, 7, 12, 9, 200]

現須要對其中的每個數字都執行一系列相同的加減乘除操做,如對每個數字都加5乘8再減去1,可是這樣的操做在編譯時並不肯定,須要在運行時由用戶指定;數組

一看到這個題目,固然就想到了用設計模式中的命令模式來實現;app

因而先寫了這樣的一個類:ide

class Calculator {
private(set)
var total = 0 required init(value: Int){ total = value } func add(amount: Int) { total += amount } func substract(amount: Int) { total -= amount } func multiply(amount: Int) { total = total * amount } func divide(amount: Int) { total = total / amount } }

這個類用於實現對某個數執行不一樣的操做。ui

下一步中我建立了一個Command類,用於記錄須要執行的操做:spa

struct Command {
    
    typealias OperationType = (Calculator -> Int -> Void)
    
    let operation: OperationType
    let amount: Int
    
    init(operation: OperationType, amount: Int) {
        self.operation = operation
        self.amount = amount
    }
    
    func execute(calculator: Calculator) {
        operation(calculator)(amount)
    }
}

在該類中我定義了一個名爲OperationType的類型別名,從定義中能夠看出,OperationType類型的實例是一個Closure,該Closure接受一個Calculator類型的實例,並返回一個類型爲Int -> Void的Closure(此Closure的類型就是Calculator中每一個方法的類型);設計

amount爲執行那個操做的參數值;3d

待一切完畢後,由用戶來指定要執行的命令,如將數組numbers中的每個值加5乘8再減去1,則能夠這樣實現:code

var commands = [Command]()
commands.append(Command(operation: Calculator.add, amount: 5))
commands.append(Command(operation: Calculator.multiply, amount: 8))
commands.append(Command(operation: Calculator.substract, amount: 1))

這樣作並無達到Command設計模式想要達到的目的,及實現命令的發出者與命令的執行者之間的脫耦;因而我加入了一個新的enum類型:blog

enum OperationType {
    case Add(Int)
    case Substract(Int)
    case Multiply(Int)
    case Divide(Int)
}

這個enum類型中的每個成員都自帶一個關聯值,及要執行操做的參數,因而Command類型能夠改變爲:

struct Command {
    
    let operationType: OperationType
    
    init(operationType: OperationType) {
        self.operationType = operationType
    }
    
    func execute(calculator: Calculator) {
        switch self.operationType {
            case .Add(let value):
                calculator.add(value)
            case .Substract(let value):
                calculator.substract(value)
            case .Multiply(let value):
                calculator.multiply(value)
            case .Divide(let value):
                calculator.divide(value)
        }
    }
}

從新建立Commands數組:

var commands = [Command]()
commands.append(Command(operationType: .Add(5)))
commands.append(Command(operationType: .Multiply(8)))
commands.append(Command(operationType: .Substract(1)))

OK,執行全部命令:

for number in numbers {
    var calculator = Calculator(value: number)
    
    for command in commands {
        command.execute(calculator)
    }
    
    println("\(number) -> \(calculator.total)")
}

這裏是結果:

相關文章
相關標籤/搜索