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
@enduml
interface Closeable {
    fun close()
}

class FileStream : Closeable {
    override fun close() {
        TODO("Not yet implemented")
    }
}

의존(Dependency)

  • 어떤 클래스가 다른 클래스를 참조하는 것을 말함

@startuml
Product ..> Amount
@enduml
class Product {
    fun payment(amount: Amount) {
        TODO("Not yet implemented")
    }

    fun refund(): Amount {
        TODO("Not yet implemented")
    }
}

class Amount

연관(Association)

  • 다른 객체의 참조를 가지는 필드를 나타냄

@startuml
Order  "1" -- "*" Merchant
@enduml
data class Order(
    val merchant: Merchant,
)

data class Merchant(
    val orders: List<Order>,
)

직접연관(Directed Association)

@startuml
Product  --> "1" Amount
Product  --> "*" Tag: tags
@enduml
data 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()
    }
}

References