#Паттерны ООП
Паттерн Chain of Responsability
Цепочка обработчиков
Цепочка обязаностей, она же цепочка ответственности, она же цепочка обработчиков
Когда использовать этот паттерн:
- У вас более чем один объект — обработчик.
- У вас есть несколько объектов обработчика, при этом вы не хотите специфицировать который объект должен обрабатывать в даный момент времени.
Цепочка обязанностей используется для обработки разнообразных запросов, каждый из которых может рассматриваться другим обработчиком.
Паттерн Fabric Method
Фабричный метод
Фабричный метод порождает объекты одного и того же типа.
import Foundation import UIKit // Protocol for "Product" protocol AppleProduct { var name: String {get set} var screenSize: Double {get set} var price: Double {get set} func getProduct() -> String } // Protocl for "Creator" protocol AppleProductCreator { func createProduct() -> AppleProduct } // Class for "ConcreteProduct" class IPhoneProduct: AppleProduct { var name: String = "iPhone 6" var screenSize: Double = 4.7 var price: Double = 199.00 func getProduct() -> String { return "Apple product "(name)", with screen size in (screenSize) inch, at proce: $(price)" } } class IPadProduct: AppleProduct { var name: String = "iPad Air 3" var screenSize: Double = 10.1 var price: Double = 499.00 func getProduct() -> String { return "Apple product "(name)", with screen size in (screenSize) inch, at proce: $(price)" } } // Class for "ConcreteCreator" class IPhoneProductCreator: AppleProductCreator { static let sharedInstance:IPhoneProductCreator = IPhoneProductCreator() func createProduct() -> AppleProduct { return IPhoneProduct() } } class IPadProductCreator: AppleProductCreator { static let sharedInstance:IPadProductCreator = IPadProductCreator() func createProduct() -> AppleProduct { return IPadProduct() } }
Применение
let product1: AppleProduct = IPhoneProductCreator.sharedInstance.createProduct() print("Got a new device: " + product1.getProduct()) let product2: AppleProduct = IPadProductCreator.sharedInstance.createProduct() print("Got a new device: " + product2.getProduct())
Пример 2
protocol Currency { func symbol() -> String func code() -> String } class Euro : Currency { func symbol() -> String { return "€" } func code() -> String { return "EUR" } } class UnitedStatesDolar : Currency { func symbol() -> String { return "$" } func code() -> String { return "USD" } } enum Country { case unitedStates, spain, uk, greece } enum CurrencyFactory { static func currency(for country:Country) -> Currency? { switch country { case .spain, .greece : return Euro() case .unitedStates : return UnitedStatesDolar() default: return nil } } }
Применение
let noCurrencyCode = "No Currency Code Available" CurrencyFactory.currency(for: .greece)?.code() ?? noCurrencyCode CurrencyFactory.currency(for: .spain)?.code() ?? noCurrencyCode CurrencyFactory.currency(for: .unitedStates)?.code() ?? noCurrencyCode CurrencyFactory.currency(for: .uk)?.code() ?? noCurrencyCode
Pattern: Abstract Factory
Паттерн Абстрактная фабрика используется для обеспечения клиента набором родственных или зависимых объектов. «Семья» объектов, созданных на заводе-изготовителе определяются во время выполнения.
Паттерн Iterator
Пример
//: Playground - noun: Паттерн Iterator import UIKit struct BanksLevel{ let price:Double let time:UInt32 let comment:String } struct Levels { let arLevels: [BanksLevel] } struct LevelsIterator: IteratorProtocol { private var current = 0 private let levels: [BanksLevel] init(levels: [BanksLevel]) { self.levels = levels } mutating func next() -> BanksLevel? { defer { current += 1 } return levels.count > current ? levels[current] : nil } } extension Levels: Sequence { func makeIterator() -> LevelsIterator { return LevelsIterator(levels: arLevels) } }
Применение
let arLevels = Levels(arLevels: [ BanksLevel(price: 1.06740, time: 1, comment: "Первый банковский уровень"), BanksLevel(price: 1.06210, time: 2, comment: "Второй банковский уровень") ] ) for level in arLevels { print("Определён: \(level)") }
Пример 2
import UIKit class Item{ let name:String init(_ name:String){ self.name = name } } class IteratableItems{ var arItems: [Item] = [] init(items:[Item]){ self.arItems = items } } class ItemIterator: IteratorProtocol{ private var current = 0 private let arItems: [Item] init(items:[Item]){ self.arItems = items } func next()-> Item?{ defer { current += 1 } return arItems.count > current ? arItems[current] : nil } } extension IteratableItems: Sequence { func makeIterator() -> ItemIterator { return ItemIterator(items: arItems) } }
Используем:
let arItems = IteratableItems(items: [Item("One"),Item("Two"),Item("Three")]) for item in arItems{ print("item: \(item.name)") }
Пишем в лог
Последнее время мне частенько приходится писать в лог, при этом не имея штатных классов записи в лог, по сему делаю себе ещё одну памятку.
if (!class_exists('Log')) { /** * Class Log * @singleton * @example Log::getInstance()->write("Всё хорошо прошло )) "); */ class Log{ protected static $instance = null; protected static $fileName = "/codeception.log"; protected function __construct(){ } public function getInstance(){ if (empty(static::$instance)){ static::$instance = new static(); } return static::$instance; } protected function getFullFileName(){ return $_SERVER["DOCUMENT_ROOT"].static::$fileName; } public function write($arg) { $strArg = ""; $fp = fopen($this->getFullFileName(), 'a+'); if (is_array($arg)){ $strArg = $this->ar2s($arg); } else { $strArg = $arg; } fwrite($fp, $strArg); fclose($fp); } /** * @param $ar * конвертируем массив в строку */ public function ar2s($ar){ return var_export($ar,true); } } }
Паттерны: Оглавление
Мастерство состоит в том, чтобы двигаться от земли к небу и обратно
Александра Волкова
Оглавление
- Registry (Реестр)
- Singleton (Одиночка)
Log - Factory Method — Фабричный метод порождает объекты одного и того же типа
- Simple Factory
- Abstract Factory
- Цепочка обязанностей
___
- Iterator
- Observer
- Decorator
- Wrapper
- Composer
- Pool
- Multiton (Пул одиночек)
- Prototype
- Adapter
- Template Method
- Specification
- Dependency Injection
Книги по теме
- Банда Четырёх
- Мэт Зандстра (Matt Zandstra): PHP. Объекты, шаблоны и методики программирования (Objects, Patterns, and Practice)
Паттерны на Swift
http://proswift.ru/shablony-programmirovaniya-na-swift-abstract-factory/
https://habrahabr.ru/company/badoo/blog/281162/
https://github.com/ochococo/Design-Patterns-In-Swift
Ссылки по теме
Серия статей о шаблонах проектирования на PHP
Примеры на PHP
Patterns PHP