Skip to content

Instantly share code, notes, and snippets.

@alobanov alobanov/factory.swift
Last active Oct 1, 2017

Embed
What would you like to do?
🏭 Фабричный метод — это порождающий паттерн проектирования, который определяет общий интерфейс для создания объектов в суперклассе, позволяя подклассам изменять тип создаваемых объектов.
//: Playground - noun: a place where people can play
import UIKit
// Models
struct UniverseType {
static let marvel = MarvelHero.self
static let dc = DCHero.self
}
protocol Hero {
var name: String {get}
init(rawHeroId: Int)
}
class UnknownHero: Hero {
var name: String
required init(rawHeroId: Int) {
self.name = "Kick Ass"
}
}
class DCHero: Hero {
enum DCHeroType: Int {
case batman = 0, superman, flash
var name: String {
switch self {
case .batman: return "batman"
case .superman: return "superman"
case .flash: return "flash"
}
}
static let count = 2
}
var name: String
required init(rawHeroId: Int) {
if let hero = DCHeroType(rawValue: rawHeroId) {
self.name = hero.name
} else {
self.name = "Зеленый фанарь"
}
}
}
class MarvelHero: Hero {
enum MarvelHeroType: Int {
case ironman = 0, capamerica, spiderman
var name: String {
switch self {
case .ironman: return "ironman"
case .capamerica: return "capamerica"
case .spiderman: return "spiderman"
}
}
static let count = 2
}
var name: String
required init(rawHeroId: Int) {
if let hero = MarvelHeroType(rawValue: rawHeroId) {
self.name = hero.name
} else {
self.name = "Соколиный глаз"
}
}
}
//
// Фабрика
//
protocol HeroFactoryProtocol {
func createHero() -> Hero
}
extension HeroFactoryProtocol {
func createHero() -> Hero {
return UnknownHero(rawHeroId: 0)
}
func random(max: Int) -> Int {
return Int(arc4random_uniform(UInt32(1 + max - 0))) + 0
}
}
class HeroFactory<H: Hero>: HeroFactoryProtocol {
func createHero() -> Hero {
return H(rawHeroId: random(max: 2))
}
}
class FactoryDemo {
private(set) var heroFactory: HeroFactoryProtocol!
func configure<T: Hero>(type: T.Type) {
heroFactory = HeroFactory<T>()
}
}
let demo = FactoryDemo()
demo.configure(type: UniverseType.marvel)
print(demo.heroFactory.createHero().name)
print(demo.heroFactory.createHero().name)
print(demo.heroFactory.createHero().name)
// Абстрактная фабрика
protocol AbstractHeroFactoryProtocol {
func hero() -> Hero
}
class AbstractHeroFactory: AbstractHeroFactoryProtocol {
private var factory: HeroFactoryProtocol
init(factory: HeroFactoryProtocol) {
self.factory = factory
}
func hero() -> Hero {
return factory.createHero()
}
}
// Demo
let dcFactory: HeroFactoryProtocol = HeroFactory<DCHero>()
let afDemo: AbstractHeroFactoryProtocol = AbstractHeroFactory(factory: dcFactory)
print(afDemo.hero().name)
print(afDemo.hero().name)
print(afDemo.hero().name)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.