| Note | GoF, 김정아(옮긴이), Design Patterns, 개정판, 프로텍미디어, 2015. | 
클래스 다이어그램
TODO: 전체 그림
@startuml ' config hide empty field hide empty method ' definition ' relation @enduml
일반화(Generalization)
- 
부모 클래스와 자식 클래스간의 상속 관계를 나타냄 
@startuml ' config hide empty field hide empty method ' relation Parent <|-- Children @enduml
open class Parent
class Children : Parent() // inheriance실체화(Realization)
- 
인터페이스를 실제 기능으로 구현하는 것을 말함 
@startuml
' config
hide empty field
hide empty method
' definition
interface Closeable {
    fun close()
}
class FileStream {
    fun close()
}
' relation
Closeable <|.. FileStream
@enduml@startuml
' config
hide empty field
hide empty method
' definition
circle Closeable
class FileStream {
    close()
}
' relation
Closeable -- FileStream
@endumlinterface Closeable {
    fun close()
}
class FileStream : Closeable {
    override fun close() {
        TODO("Not yet implemented")
    }
}의존(Dependency)
- 
어떤 클래스가 다른 클래스를 참조하는 것을 말함 
@startuml
Product ..> Amount
@endumlclass Product {
    fun payment(amount: Amount) {
        TODO("Not yet implemented")
    }
    fun refund(): Amount {
        TODO("Not yet implemented")
    }
}
class Amount연관(Association)
- 
다른 객체의 참조를 가지는 필드를 나타냄 
@startuml
Order  "1" -- "*" Merchant
@endumldata class Order(
    val merchant: Merchant,
)
data class Merchant(
    val orders: List<Order>,
)직접연관(Directed Association)
@startuml
Product  --> "1" Amount
Product  --> "*" Tag: tags
@endumldata class Product(
    val amount: Amount,
    val tags: List<Tag>,
)집합(Aggregation)
@startuml
A  o-- B
@enduml합성(Composition)
@startuml
A *-- B
@enduml생성 패턴(Creational Pattern)
- 
인스턴스를 만드는 절차를 추상화하는 패턴 
추상 팩토리(Abstract factory)
구체적인 클래스를 지정하지 않고 관련성을 갖는 객체들의 집합을 생성하거나 서로 독립적인 객체들의 집합을 생성할 수 있는 인터페이스를 제공하는 패턴입니다.
@startuml
' define
abstract class AbstractFactory {
    CreateProductA()
    CreateProductB()
}
class ConcreteFactory1 {
    CreateProductA()
    CreateProductB()
}
class ConcreteFactory2 {
    CreateProductA()
    CreateProductB()
}
' structure
AbstractFactory <|-- Client
@enduml추상 팩토리 vs 팩토리 메서드??
싱글턴?
빌더(Builder)
구조 패턴(Structural Patterns)
퍼사드(Facade)
- 
한 서브시스템 내의 인터페이스 집합에 대한 획일화된 인터페이스를 제공하는 패턴. 
- 
서브시스템을 사용하기 쉽도록 상위 수준의 인터페이스를 정의. 
- 
이점 - 
서브시스템의 구성요소를 보호할 수 있음 
- 
서브시스템과 사용자 코드 간의 결합도를 낮춤 
 
- 
- 
중재자(mediator) vs. 퍼사드 - 
중재자 패턴의 목적은 여러 객체들 사이의 협력 관계를 추상화하여 기능성의 집중화를 막자는 것. 중재자 패턴에 참여하는 객체는 서로를 집적 알지 못하고 단지 중재자를 통해서만 상호작용 
- 
퍼사드는 서브시스템 인터페이스 자체를 추상화하여 사용을 용이하게 하려는 목적. 즉 새로운 기능성을 추가할 수도 없고, 이런 새로운 추가 기능에 대해서는 알 수도 없음. 
 
- 
- 
어댑터(adapter) vs. 퍼사드 - 
어댑터는 객체 수준에서 어댑팅을 수행 
- 
퍼사드는 어떤 서브시스템 전체를 어댑팅 
- 
퍼사드는 레거시 시스템과 통신하기 위해 사용되는 경우 많음 
 
- 
- 
퍼사드 객체가 하나만 있어도 된다면 싱글턴으로 구현. 
| Note | 획일화된 인터페이스를 제공하는 것이 코어 모델과 다른 점이 무엇인가. 비지니스가 아닌 단순 인터페이스만 제공하는 것? | 
행동 패턴(Behavioral Pattern)
전략(Strategy)
internal class DesignPatternTest {
    @Test
    fun main() {
        listOf(
            Context(Person()),
            Context(Car()),
            Context(Airplane()),
        ).forEach {
            it.move()
        }
    }
}
interface Strategy {
    fun logic()
}
class Person : Strategy {
    override fun logic() {
        println("walk")
    }
}
class Car : Strategy {
    override fun logic() {
        println("drive")
    }
}
class Airplane : Strategy {
    override fun logic() {
        println("fly")
    }
}
data class Context(
    private val strategy: Strategy,
) {
    fun move() {
        strategy.logic()
    }
}