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


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

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

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

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

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

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