swift - The command pattern

The command pattern provides a mechanism by which details of how to invoke a method can beencapsulated so that the method can be invoked later or by a different component.

命令模式:把每一次执行的命令放到一个队列里,undo队列 和 do队列,实现了undo/redo的操作。


client:


let calc = Calculator();

calc.add(10);

calc.multiply(4);

calc.subtract(2);

println("Calc 1 Total: \(calc.total)");


let macro = calc.getMacroCommand();


let calc2 = Calculator();

macro(calc2);

println("Calc 2 Total: \(calc2.total)");

///////////////////////////////////////////////////////////////////////////////////////////
pattern:
//1

import Foundation;


class Calculator {

private(set) var total = 0;

typealias CommandClosure = (Calculator -> Void);

private var history = [CommandClosure]();

private var queue = dispatch_queue_create("arrayQ",disPATCH_QUEUE_SERIAL);

func add(amount:Int) {

addMacro(Calculator.add,amount: amount);

total += amount;

}

func subtract(amount:Int) {

addMacro(Calculator.subtract,amount: amount);

total -= amount;

}

func multiply(amount:Int) {

addMacro(Calculator.multiply,amount: amount);

total = total * amount;

}

func divide(amount:Int) {

addMacro(Calculator.divide,amount: amount);

total = total / amount;

}

private func addMacro(method:Calculator -> Int -> Void,amount:Int) {

dispatch_sync(self.queue,{() in

self.history.append({ calc in method(calc)(amount)});

});

}

func getMacroCommand() -> (Calculator -> Void) {

var commands = [CommandClosure]();

dispatch_sync(queue,{() in

commands = self.history

});

return { calc in

if (commands.count > 0) {

for index in 0 ..< commands.count {

commands[index](calc);

}

}

};

}

}



//2

protocol Command {

func execute(receiver:Any);

}


class CommandWrapper : Command {

private let commands:[Command];

init(commands:[Command]) {

self.commands = commands;

}

func execute(receiver:Any) {

for command in commands {

command.execute(receiver);

}

}

}


class GenericCommand<T> : Command {

private var instructions: T -> Void;

init(instructions: T -> Void) {

self.instructions = instructions;

}

func execute(receiver:Any) {

if let safeReceiver = receiver as? T {

instructions(safeReceiver);

} else {

fatalError("Receiver is not expected type");

}

}

class func createCommand(instuctions: T -> Void) -> Command {

return GenericCommand(instructions: instuctions);

}

}

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...