Skip to content

Instantly share code, notes, and snippets.

@linearhw
Last active December 27, 2017 06:28
Show Gist options
  • Save linearhw/85f56271edf43f584de1daec58f6b661 to your computer and use it in GitHub Desktop.
Save linearhw/85f56271edf43f584de1daec58f6b661 to your computer and use it in GitHub Desktop.

Decorator

언제 사용하는 게 좋은가

  • 객체를 동적으로 확장할 필요가 있을 때
  • 객체에 첨가할 데이터가 다양하고 일정하지 않을 때 효율적
  • 대신 자잘한 객체가 많아지고 코드가 필요 이상으로 복잡해 질 수도 있다.

특징

  • 한 객체를 감싸기 위해 한 개 혹은 여러 개의 Decorator 를 사용할 수 있다.
  • Decorator 는 Decorate 하는 객체와 같은 type 을 가진다
  • Decorator 는 행위(behavior)를 객체에 위임할 수도 있고 객체로부터 위임 받을 수도 있다
  • 객체는 언제든지 Decorate 될 수 있어서, 런타임에 동적으로 얼마든지 많은 Decorator 로 객체를 감쌀 수 있다.

예제 (아이스크림 토핑 올리기)

class Topping { // abstract class
    class func getCost() -> Int {
        return 0
    }
}

class Nuts: Topping {
    override class func getCost() -> Int {
        return 1
    }
}

class Fruits: Topping {
    override class func getCost() -> Int {
        return 2
    }
}

class IceCream {
    var nuts: Int = 0
    var fruits: Int = 0
    
    var initialCost = 5
    
    func getCost() -> Int {
        return initialCost
        + nuts * Nuts.getCost()
        + fruits * Fruits.getCost()
    }
}

이 때 문제점: 새로운 Topping 이 추가될 때마다 IceCream class 의 property 와 getCost method 가 수정되어야 한다.

수정 버전:

class ToppingDecorator: IceCream {
    
}

class Nuts: ToppingDecorator {
    private var iceCream: IceCream!
    
    init(iceCream: IceCream) {
        super.init()
        self.iceCream = iceCream
    }
    
    override func getCost() -> Int {
        return super.getCost() + 1
    }
}

class Fruits: ToppingDecorator {
    private var iceCream: IceCream!
    
    init(iceCream: IceCream) {
        super.init()
        self.iceCream = iceCream
    }
    
    override func getCost() -> Int {
        return super.getCost() + 2
    }
}

class IceCream {
    func getCost() -> Int {
        return 5
    }
}

let iceCream = IceCream()
let iceCreamWithNuts = Nuts(iceCream: iceCream)
let iceCreamWithNutsAndFruits = Fruits(iceCream: iceCreamWithNuts)

iOS usage

  • Category
  • Delegation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment