Шаблоны программирования на Swift: Strategy
В этой статье мы рассмотрим шаблон программирования Стратегия (Strategy) на Swift в среде разработки XCode
Strategy
Если Ваша девушка злая, вы скорее всего будете общаться с ней осторожно. Если на вашем проетке завал, то вероятнее всего вы не будете предлагать в команде вечерком дернуть пива или поиграть в компьютерные игры. В различных ситуациях, у нас могут быть очень разные стратегии поведения. К примеру, в приложении вы можете использовать различные алгоритмы сжатия, в зависимости от того с каким форматом картинки вы работаете, или же куда вы хотите после этого картинку деть. Вот мы и добрались до паттерна Стратегия.
Также отличным примером может быть MVC паттерн – в разных случаях мы можем использовать разные контроллеры для одного и того же View (к примеру авторизированный и не авторизированный пользователь).
Паттерн Стратегия определяет семейство алгоритмов, которые могут взаимозаменяться.
Когда использовать паттерн:
- Вам необходимы различные алгоритмы
- Вы очень не хотите использовать кучу вложенных If-ов
- В различных случаях ваш класс работает по разному
Давайте напишем пример – RPG игра, в которой у вас есть различные стратегии нападения Вашими персонажами:) Каждый раз когда вы делаете ход, ваши персонажи делают определенное действие. Итак, для начала управление персонажами!
Создадим базовую стратегию:
// // proSwift.ru // protocol BasicStrategy { func actionPerson1() func actionPerson2() func actionPerson3() }
Как видно из кода стратегии – у нас есть 3 персонажа, каждый из которых может совершать одно действие! Давайте научим персонажей нападать!
// // proSwift.ru // class AttackStrategy: BasicStrategy { func actionPerson1() { print("Герой 1 - атакуй всех врагов") } func actionPerson2() { print("Герой 2 - атакуй всех врагов") } func actionPerson3() { print("Герой 3 - атакуй всех врагов") } }
При использовании такой стратегии наши персонажи нападают на все что движется! Давайте научим их защищаться:
// // proSwift.ru // class DefenceStrategy: BasicStrategy { func actionPerson1() { print("Герой 1 - атакуй всех врагов") } func actionPerson2() { print("Герой 2 - Лечи героя 1") } func actionPerson3() { print("Герой 3 - защищай героя 2") } }
Во время защитной стратегии, наши персонажи действуют по-другому – кто атакует, кто лечит, а некоторый даже защищают:) Ну, теперь как-то надо это все использовать. Давайте создадим нашего игрока:
// // proSwift.ru // class Player { var strategy: BasicStrategy func makeAction() { self.strategy.actionPerson1() self.strategy.actionPerson2() self.strategy.actionPerson3() } func changeStrategy(aStrategy: BasicStrategy) { self.strategy = aStrategy } init(strategy: BasicStrategy) { self.strategy = strategy } }<br>
Наш игрок может только менять стратегию и действовать в зависимости от этой стратегии. Код для тестирования:
// // proSwift.ru // let a = AttackStrategy() let d = DefenceStrategy() let p = Player(strategy: a) p.makeAction() print("- - - - - - -") p.changeStrategy(d) p.makeAction()
Вывод лога в консоль:
Герой 1 - атакуй всех врагов Герой 2 - атакуй всех врагов Герой 3 - атакуй всех врагов - - - - - - - Герой 1 - атакуй всех врагов Герой 2 - Лечи героя 1 Герой 3 - защищай героя 2
Пример с GitHub
Шаблон «Стратегия» используется для создания сменного семейства алгоритмов, из которых нужный процесс выбирается во время выполнения.
// // proSwift.ru // // https://github.com/ochococo/Design-Patterns-In-Swift/blob/master/source/behavioral/strategy.swift protocol PrintStrategy { func printString(string: String) -> String } class Printer { let strategy: PrintStrategy func startPrinting(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()) let str1 = lower.startPrinting("O tempora, o mores!") print(str1) print("- - - - - - - - - -") var upper = Printer(strategy:UpperCaseStrategy()) let str2 = upper.startPrinting("O tempora, o mores!") print(str2)
Для принтера, который умеет печатать строки, мы создаем две стратегии: печать строчными и заглавными буквами. Подменяя стратегии у экземпляра принтера, мы меняем строку вывода.
o tempora, o mores! - - - - - - - - - - O TEMPORA, O MORES!
—
Добавить комментарий