内容列表:
行为型模式
创建型模式
结构型模式
1.行为型模式
行为模式(Behavioral Pattern)是对在不同的对象之间划分责任和算法的抽象化。行为模式不仅仅是关于类和对象的,而且是关于它们之间的相互作用的。行为模式增加了对象相互交流的灵活性。
1.1 责任链模式(chain of responsibility pattern)
责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。
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))"
}
}
// Create piles of money and link them together 10 < 20 < 50 < 100.
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)
// Build ATM.
var atm = ATM(hundred: hundred, fifty: fifty, twenty: twenty, ten: ten)
atm.canWithdraw(310) // Cannot because ATM has only 300
atm.canWithdraw(100) // Can withdraw - 1x100
atm.canWithdraw(165) // Cannot withdraw because ATM doesn't has bill with value of 5
atm.canWithdraw(30) // Can withdraw - 1x20, 2x10
(个人解释)100元类,50元类,20,10元类从前到后一次处理给定的钱数,每个类对不能够处理的钱数留给下一个类进行处理。
1.2 命令模式(command pattern)
命令模式用来表示命令对象的一种需求,需求的调用者以及所有必要的参数。命令可以立即执行,也可以留作以后使用。
protocol FileOperationCommand {
init(file: String)
func execute()
}
class FileMoveCommand : FileOperationCommand {
let file:String
required init(file: String) {
self.file = file
}
func execute() {
print("\(file) moved")
}
}
class FileDeleteCommand : FileOperationCommand {
let file:String
required init(file: String) {
self.file = file
}
func execute() {
print("\(file) deleted")
}
}
class FileManager {
let deleteCommand: FileOperationCommand
let moveCommand: FileOperationCommand
init(deleteCommand: FileDeleteCommand, moveCommand: FileMoveCommand) {
self.deleteCommand = deleteCommand
self.moveCommand = moveCommand
}
func delete() {
deleteCommand.execute()
}
func move() {
moveCommand.execute()
}
}
let deleteCommand = FileDeleteCommand(file: "/path/to/testfile")
let moveCommand = FileMoveCommand(file: "/path/to/testfile")
let fileManager = FileManager(deleteCommand:deleteCommand , moveCommand: moveCommand)
fileManager.delete()
fileManager.move()
1.3 迭代器模式( iterator pattern)
迭代器模式是用来提供一个标准的接口,遍历一个集合对象的所有子元素,而不需要知道他们的底层结构。
1.4 中介者模式 (mediator pattern)
中介者模式是用来减弱两个互相通信的类之间的耦合度。替代直接通信的方式,需要知道这两个类的实现,他们通过中介者对象发送消息。
1.5 备忘录模式 (memento pattern)
备忘录模式是用来捕捉一个对象当前的状态并存下,利用这样的方式,它可以在晚些时候在不打破封装规则的前提下,恢复出来。
typealias Memento = Dictionary<NSObject, AnyObject>
/**
* Originator
*/
class GameState {
var gameLevel: Int = 1
var playerScore: Int = 0
func saveToMemeto() -> Memento {
return ["gameLevel": gameLevel, "playerScore": playerScore]
}
func restoreFromMemeto(memento: Memento) {
gameLevel = memento["gameLevel"]! as Int
playerScore = memento["playerScore"]! as Int
}
}
/**
* Caretaker
*/
class CheckPoint {
class func saveState(memento: Memento, keyName: String = "gameState") {
let defaults:NSUserDefaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(memento, forKey: keyName)
defaults.synchronize()
}
class func restorePreviousState(keyName: String = "gameState") -> Memento {
let defaults:NSUserDefaults = NSUserDefaults.standardUserDefaults()
return defaults.objectForKey(keyName) as Memento
}
}
var gameState = GameState()
gameState.gameLevel = 2
gameState.playerScore = 200
// Saves state: {gameLevel 2 playerScore 200}
CheckPoint.saveState(gameState.saveToMemeto())
gameState.gameLevel = 3
gameState.gameLevel = 250
// Restores state: {gameLevel 2 playerScore 200}
gameState.restoreFromMemeto(CheckPoint.restorePreviousState())
gameState.gameLevel = 4
// Saves state - gameState2: {gameLevel 4 playerScore 200}
CheckPoint.saveState(gameState.saveToMemeto(), keyName: "gameState2")
gameState.gameLevel = 5
gameState.playerScore = 300
// Saves state - gameState3: {gameLevel 5 playerScore 300}
CheckPoint.saveState(gameState.saveToMemeto(), keyName: "gameState3")
// Restores state - gameState2: {gameLevel 4 playerScore 200}
gameState.restoreFromMemeto(CheckPoint.restorePreviousState(keyName: "gameState2"))
1.6 观察者模式( observer pattern)
观察者模式是允许一个对象发布自己状态的变化,然后那些订阅的对象能够立即得知这些变化。
class StepCounter {
var totalSteps: Int = 0 {
willSet(newTotalSteps) {
println("About to set totalSteps to \(newTotalSteps)")
}
didSet {
if totalSteps > oldValue {
println("Added \(totalSteps - oldValue) steps")
}
}
}
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// About to set totalSteps to 200
// Added 200 steps
stepCounter.totalSteps = 360
// About to set totalSteps to 360
// Added 160 steps
stepCounter.totalSteps = 896
// About to set totalSteps to 896
// Added 536 steps
1.7 状态模式( state pattern)
状态模式目的是当对象内部状态变化时,改变对象的行为。该模式允许对象运行时的变化。
class Context {
private var state: State = UnauthorizedState()
var isAuthorized: Bool {
get { return state.isAuthorized(self) }
}
var userId: String? {
get { return state.userId(self) }
}
func changeStateToAuthorized(#userId: String) {
state = AuthorizedState(userId: userId)
}
func changeStateToUnauthorized() {
state = UnauthorizedState()
}
}
protocol State {
func isAuthorized(context: Context) -> Bool
func userId(context: Context) -> String?
}
class UnauthorizedState: State {
func isAuthorized(context: Context) -> Bool { return false }
func userId(context: Context) -> String? { return nil }
}
class AuthorizedState: State {
let userId: String
init(userId: String) { self.userId = userId }
func isAuthorized(context: Context) -> Bool { return true }
func userId(context: Context) -> String? { return userId }
}
let context = Context()
(context.isAuthorized, context.userId)
context.changeStateToAuthorized(userId: "admin")
(context.isAuthorized, context.userId) // now logged in as "admin"
context.changeStateToUnauthorized()
(context.isAuthorized, context.userId)
1.8 策略模式( strategy pattern)
策略模式是用来产生一族可交换的算法以供程序运行时选择。
protocol PrintStrategy {
func printString(string: String) -> String
}
class Printer {
let strategy: PrintStrategy
func printString(string: String) -> String {
return self.strategy.printString(string)
}
init(strategy: PrintStrategy) {
self.strategy = strategy
}
}
class UpperCaseStrategy : PrintStrategy {
func printString(string:String) -> String {
return string.uppercaseString
}
}
class LowerCaseStrategy : PrintStrategy {
func printString(string:String) -> String {
return string.lowercaseString
}
}
var lower = Printer(strategy:LowerCaseStrategy())
lower.printString("O tempora, o mores!")
var upper = Printer(strategy:UpperCaseStrategy())
upper.printString("O tempora, o mores!")
1.9 访问者模式(visitor pattern)
访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变。
protocol PlanetVisitor {
func visit(planet: PlanetEarth)
func visit(planet: PlanetMars)
func visit(planet: PlanetGliese581C)
}
protocol Planet {
func accept(visitor: PlanetVisitor)
}
class PlanetEarth: Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(self) }
}
class PlanetMars: Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(self) }
}
class PlanetGliese581C: Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(self) }
}
class NameVisitor: PlanetVisitor {
var name = ""
func visit(planet: PlanetEarth) { name = "Earth" }
func visit(planet: PlanetMars) { name = "Mars" }
func visit(planet: PlanetGliese581C) { name = "Gliese 581 C" }
}
let planets: [Planet] = [PlanetEarth(), PlanetMars(), PlanetGliese581C()]
let names = planets.map { (planet: Planet) -> String in
let visitor = NameVisitor()
planet.accept(visitor)
return visitor.name
}
names
文章翻译自github项目,地址如下:
点击打开链接https://github.com/ochococo/Design-Patterns-In-Swift#behavioral