[Swift] Decorator Pattern

온오·2024년 5월 29일
post-thumbnail

데코레이터 패턴(Decorator Pattern)

데코레이터 패턴은 메시지를 처리하는 메서드의 동작을 추가해 런타임에 해당 객체의 코드를 수정하지 않고도 새로운 기능을 수행할 수 있게 만들어주는 패턴입니다.

기존 객체를 감싸는 Wrapper를 만들고 해당 Wrapper객체에 다른 기능을 추가해서 Wrapper패턴이라고 불리기도 합니다.


구성

Component

  • 동적으로 추가된 기능을 가질 수 있는 객체에 대한 인스턴스를 정의합니다.
  • e.g : Wrapper와 Wrapper에 의해 래핑된 객체 모두에 대한 인스턴스를 정의합니다.

Concrete Component

  • Component 인터페이스의 기능들을 추가로 구현한 객체입니다.
  • 새로운 기능들이 추가될 수 있는 객체입니다.
  • e.g : 래핑되는 객체를 말합니다.

Decorator

  • Component 인터페이스를 따르는 객체를 참조할 수 있는 필드가 존재합니다.
  • Component 인터페이스를 따르는 인스턴스를 정의합니다.

Concrete Decorator

  • 구성 요소에 기능을 추가합니다.

Client

  • Component 인터페이스를 통해 모든 객체와 함께 동작하는 여러 계층의 Decorator로 Component를 래핑할 수 있습니다.

언제 사용하나요?

  • 다른 객체들에 영향을 주지않고 개별 객체에 기능을 추가하고 싶을 때 사용합니다.
  • 추가한 기능들은 언제든지 없앨 수 있습니다.
  • 상속을 사용하여 기능을 확장하기 어려울 때 사용합니다.

적용해보기

Component

먼저 가장 기본이 될 Component를 추가해줍니다. 예시로 저는 마라탕에 재료를 추가하면 돈이 추가되도록 구현하기 위해 마라탕 protocol을 선언해줬습니다.

Concrete Component

그리고 Maratang 프로토콜을 채택하는 기본이 되는 Concrete Component를 만들어 줍니다.
Concrete Component는 재귀를 종료할 base case가 필요하기 때문에 BasicMaratang의 const

Decorator


데코레이터 프로토콜을 만들고, 내부에 Maratang타입의 변수를 가지도록 인터페이스를 구성했습니다.
데코레이터 프로토콜은 데코레이터를 적용할 구체적인 객체의 타입을 상속하거나 채택해야하고, 동시에 같은 타입의 인스턴스를 멤버로 가지고 있어야 하기 때문에 이렇게 구성했어요.

Concrete Decorator

중국당면과 양고기는 생성자로 Maratag타입을 받습니다. 이 타입은 Concrete Component와 Decorator도 가지고 있기 때문에 Decorator를 생성자로 전달하는 것이 가능합니다.

중국당면과 양고기가 구현하는 메서드와 연산 프로퍼티는 생성자로 받은 Maratang 타입이 가진 동명의 메서드/연산 프로퍼티를 호출하고 그 반환 값에 자신의 상태 값을 추가해주는 방식으로 진행됩니다.

사용해보기


아까 Decorator가 Maratang타입을 따르고 있던 이유가 바로 여러개의 인스턴스를 추가하기 위함이었습니다.
이렇게 인스턴스를 생성해서 출력해보면


저희가 원하는대로 출력됩니다.

이렇게 데코레이터 패턴을 이용해서 OCP를 따르면서 유연하게 변경에 대처할 수 있는 객체를 만들 수 있습니다!

0개의 댓글