Factories

godo·2022년 8월 15일
0

Swift - Design Patterns

목록 보기
3/24

만들어진 객체에 대해 component 가 전체에 대해 책임을 진다

Factory Method

class Point : CustomStringConvertible
{
    var x, y : Double
    
    private init(x: Double, y: Double)
    {
        self.x = x
        self.y = y
    }
    
    private init(rho: Double, theta: Double)
    {
        x = rho * cos(theta)
        y = rho * sin(theta)
    }
    
    static func createCartesian(x: Double, y: Double) -> Point
    {
        return Point(x: x, y: y)
    }
    
    static func createPolar(rho: Double, theta: Double) -> Point
    {
        return Point(rho: rho, theta: theta)
    }
    
    var description: String
    {
        return "x = \(x), y = \(y)"
    }
}

func main()
{
    let p = Point.createPolar(rho: 1, theta: 2)
    print(p)
}

두 방식의 initialize 중 한 방식을 이용할 수 있다

Factory

class PointFactory
{
    func createCartesian(x: Double, y: Double) -> Point
    {
        return Point(x: x, y: y)
    }
    
    static func createPolar(rho: Double, theta: Double) -> Point
    {
        return Point(rho: rho, theta: theta)
    }
}

func main()
{
//    let p = Point.createPolar(rho: 1, theta: 2)
    let f = PointFactory()
    let c = f.createCartesian(x: 1, y: 2)
    let p = PointFactory.createPolar(rho: 1, theta: 2)
    print(c, p)
}

Inner Factory

class Point : CustomStringConvertible
{
    private var x, y : Double
    
    private init(x: Double, y: Double)
    {
        self.x = x
        self.y = y
    }
    
    private init(rho: Double, theta: Double)
    {
        x = rho * cos(theta)
        y = rho * sin(theta)
    }
    
    var description: String
    {
        return "x = \(x), y = \(y)"
    }
    
    static let factory = PointFactory.instance
    
    class PointFactory
    {
        private init() {}
        static let instance = PointFactory()
        
        func createCartesian(x: Double, y: Double) -> Point
        {
            return Point(x: x, y: y)
        }
        
        func createPolar(rho: Double, theta: Double) -> Point
        {
            return Point(rho: rho, theta: theta)
        }
    }

 
}

func main()
{
//    let p = Point.createPolar(rho: 1, theta: 2)
//    let f = PointFactory()
//    let c = f.createCartesian(x: 1, y: 2)
//    let p = PointFactory.createPolar(rho: 1, theta: 2)
    let p = Point.factory.createCartesian(x: 1, y: 2)
    print(p)
}

Abstract Factory

protocol HotDrink
{
    func consume()
}


class Tea: HotDrink
{
    func consume()
    {
        print("This tea is nice but I'd prefer it with lemon.")
    }
}

class Coffe: HotDrink
{
    func consume()
    {
        print("This coffee is delicious!")
    }
}

protocol HotDrinkFactory {
    init()
    func prepare(amount: Int) -> HotDrink
}

class TeaFactory
{
    required init() {}
    func prepare(amount: Int) -> HotDrink
    {
        print("Put in tea bag, boil water, pour \(amount)ml, add lemon, enjoy!")
        return Tea()
    }
}

class CoffeeFactory
{
    required init() {}
    func prepare(amount: Int) -> HotDrink
    {
        print("Grind some beans, boil water, pour \(amount)ml, add cream and sugar")
        return Coffe()
    }
}


class HotDrinkMachine
{
    enum AvailableDrink : String // breaks OCP
    {
        case coffee = "Coffee"
        case tea = "Tea"
        
        static let all = [coffee, tea]
    }
    
    internal var factories = [AvailableDrink: HotDrinkFactory]()
    
    internal var namedFactories = [(String, HotDrinkFactory)]()
    
    init()
    {
        for drink in AvailableDrink.all
        {
            let type = NSClassFromString("demo.\(drink.rawValue)Factory")
            let factory = (type as! HotDrinkFactory.Type).init()
            factories[drink] = factory
            namedFactories.append((drink.rawValue, factory))
        }
    }
    
    func makeDrink() -> HotDrink
    {
        print("Available drinks:")
        for i in 0..<namedFactories.count
        {
            let tuple = namedFactories[i]
            print("\(i): \(tuple.0)")
        }
        let input = Int(readLine()!)!
        return namedFactories[input].1.prepare(amount: 250)
    }
}

func main() {
    let machine = HotDrinkMachine()
    print(machine.namedFactories.count)
    let drink = machine.makeDrink()
    drink.consume()
}

그닥 많이 쓰이는 방식은 아님

정리

  • factory method 는 객체를 만드는 static 메서드입니다.
  • factory 는 객체 생성을 케어할 수 있습니다.
  • fatory 의 계층은 객체 관계를 만들 수 있습니다.
profile
☀️☀️☀️

0개의 댓글