상속 없이 행동이나 기능을 특정한 객체에 추가할 수 있게 하는 것
class CodeBuilder : CustomStringConvertible
{
private var buffer: String = ""
init() {}
init(_ buffer: String)
{
self.buffer = buffer
}
func append(_ s: String) -> CodeBuilder
{
buffer.append(s)
return self
}
func appendLine(_ s: String) -> CodeBuilder
{
buffer.append("\(s)\n")
return self
}
static func +=(cb: inout CodeBuilder, s: String)
{
cb.buffer.append(s)
}
var description: String
{
return buffer
}
}
func main()
{
var cb = CodeBuilder()
// cb.append("glass").append("grass")
cb.appendLine("class glass")
.appendLine("{")
cb += " // testing!\n"
cb.appendLine("}")
print(cb)
}
protocol ICanFly
{
func fly()
}
protocol ICanCrawl
{
func crawl()
}
class Bird: ICanFly
{
func fly(){}
}
class Lizard: ICanCrawl
{
func crawl(){}
}
class Dragon: ICanFly, ICanCrawl
{
private let bird = Bird()
private let lizard = Lizard()
func fly()
{
bird.fly() // delegation
}
func crawl()
{
lizard.crawl()
}
}
protocol Shape : CustomStringConvertible
{
var description: String { get }
}
class Circle: Shape
{
private var radius: Float = 0
init(_ radius: Float)
{
self.radius = radius
}
func resize(_ factor: Float)
{
radius *= factor
}
var description: String
{
return "A circle of radius \(radius)"
}
}
class Square : Shape
{
private var side : Float = 0
init(_ side: Float)
{
self.side = side
}
var description: String
{
return "A square with side \(side)"
}
}
class ColoredShape : Shape
{
var shape : Shape
var color : String
init(_ shape: Shape, _ color: String)
{
self.shape = shape
self.color = color
}
var description: String
{
return "\(shape) has color \(color)"
}
}
class TransparentShape: Shape
{
var shape: Shape
var transparency: Float
init(_ shape: Shape, _ transparency: Float)
{
self.shape = shape
self.transparency = transparency
}
var description: String
{
return "\(shape) has \(transparency*100) % transparency"
}
}
func main()
{
let square = Square(1.89)
print(square)
let blueSquare = ColoredShape(square, "blue")
print(blueSquare)
let blueHalfTransparentSquare = TransparentShape(square, 0.5)
print(blueHalfTransparentSquare)
}
protocol Shape : CustomStringConvertible
{
init()
var description: String { get }
}
class Circle: Shape
{
private var radius: Float = 0
required init() {}
init(_ radius: Float)
{
self.radius = radius
}
func resize(_ factor: Float)
{
radius *= factor
}
var description: String
{
return "A circle of radius \(radius)"
}
}
class Square : Shape
{
private var side : Float = 0
required init(){}
init(_ side: Float)
{
self.side = side
}
var description: String
{
return "A square with side \(side)"
}
}
class ColoredShape<T> : Shape where T : Shape
{
private var shape : T = T()
private var color : String = "black"
required init(){}
init(_ color: String)
{
self.color = color
}
var description: String
{
return "\(shape) has color \(color)"
}
}
class TransparentShape<T>: Shape where T : Shape
{
private var shape: T = T()
private var transparency: Float = 0
required init(){}
init(_ transparency: Float)
{
self.transparency = transparency
}
var description: String
{
return "\(shape) has \(transparency*100) % transparency"
}
}
func main()
{
let purpleCircle = ColoredShape<Circle>("purple")
print(purpleCircle)
let purpleHalfSquare = TransparentShape<ColoredShape<Square>>(0.4)
print(purpleHalfSquare)
}
protocol shape: CustomStringConvertible
{
init()
var description: String { get }
}
protocol canFly : shape
{
func fly() -> String
}
protocol canCrawl : shape
{
func crawl() -> String
}
class Bird: canFly
{
var age = 0
required init() {}
func fly() -> String
{
return (age < 10) ? "flying" : "too old"
}
var description: String
{
return "Bird's age is \(age) and \(fly())"
}
}
class Lizard: canCrawl
{
var age = 0
required init() {}
func crawl() -> String
{
return (age > 1) ? "crawling" : "too young"
}
var description: String
{
return "Lizard's age is \(age) and \(crawl())"
}
}
class Dragon<T>: canFly, canCrawl where T : shape
{
// todo: reuse bird/lizard functionality here
private var shape : T = T()
required init() {}
var age: Int = 0
func fly() -> String { return "dragon Flying" }
func crawl() -> String { return "dragon Crawling" }
var description: String
{
return "\(shape)"
}
}
func main()
{
let LizardDragon = Dragon<Lizard>()
print(LizardDragon)
let BirdDragon = Dragon<Bird>()
print(BirdDragon)
}
class Dragon
{
private var _age = 0
private let bird = Bird()
private let lizard = Lizard()
// todo: reuse bird/lizard functionality here
var age: Int {
get { return _age }
set(value)
{
lizard.age = value
bird.age = value
_age = value
}
}
func fly() -> String { return bird.fly() }
func crawl() -> String { return lizard.crawl() }
}
func main()
{
let dragon = Dragon()
print("age: "+"\(dragon.age)")
print(dragon.fly())
print(dragon.crawl())
print("\n")
dragon.age = 10
print("age: "+"\(dragon.age)")
print(dragon.fly())
print(dragon.crawl())
}
Swift 에선 제약사항이 있어서 특정한 Decorator 방식을 C++에서와 같이 효율적이게 쓰는 건 힘들다.