자바의 데코레이터 패턴

1. 개요

데코레이터 패턴을 사용하여 정적으로 또는 동적으로 객체에 추가 책임을 연결할 수 있습니다. 데코레이터는 원래 객체에 대한 향상된 인터페이스를 제공합니다.

이 패턴의 구현에서 우리는 상속보다 합성을 선호합니다. 그래서 우리는 각 데코 레이팅 요소에 대해 반복해서 서브 클래 싱의 오버 헤드를 줄일 수 있습니다. 이 디자인과 관련된 재귀는 우리가 필요로하는만큼 우리의 객체를 장식하는데 사용될 수 있습니다.

2. 데코레이터 패턴 예

크리스마스 트리 개체가 있고이를 장식한다고 가정합니다. 장식은 개체 자체를 변경하지 않습니다. 크리스마스 트리 외에도 화환, 반짝이, 나무 꼭대기, 거품 조명 등과 같은 장식 항목을 추가하고 있습니다.

이 시나리오에서는 원래 Gang of Four 디자인 및 명명 규칙을 따릅니다. 먼저 ChristmasTree 인터페이스와 그 구현을 만듭니다 .

public interface ChristmasTree { String decorate(); }

이 인터페이스의 구현은 다음과 같습니다.

public class ChristmasTreeImpl implements ChristmasTree { @Override public String decorate() { return "Christmas tree"; } }

이제이 트리에 대한 추상 TreeDecorator 클래스를 만듭니다 . 이 데코레이터는 ChristmasTree 인터페이스를 구현할 뿐만 아니라 동일한 객체를 보유합니다. 동일한 인터페이스에서 구현 된 메서드는 인터페이스에서 단순히 decorate () 메서드를 호출합니다 .

public abstract class TreeDecorator implements ChristmasTree { private ChristmasTree tree; // standard constructors @Override public String decorate() { return tree.decorate(); } }

이제 데코레이션 요소를 만들 것입니다. 이 데코레이터는 추상 TreeDecorator 클래스를 확장 하고 요구 사항에 따라 decorate () 메서드를 수정 합니다.

public class BubbleLights extends TreeDecorator { public BubbleLights(ChristmasTree tree) { super(tree); } public String decorate() { return super.decorate() + decorateWithBubbleLights(); } private String decorateWithBubbleLights() { return " with Bubble Lights"; } }

이 경우 다음이 참입니다.

@Test public void whenDecoratorsInjectedAtRuntime_thenConfigSuccess() { ChristmasTree tree1 = new Garland(new ChristmasTreeImpl()); assertEquals(tree1.decorate(), "Christmas tree with Garland"); ChristmasTree tree2 = new BubbleLights( new Garland(new Garland(new ChristmasTreeImpl()))); assertEquals(tree2.decorate(), "Christmas tree with Garland with Garland with Bubble Lights"); }

첫 번째 tree1 객체에서는 하나의 Garland 로만 장식 하고 다른 tree2 객체는 하나의 BubbleLights 및 두 개의 Garlands로 장식하고 있습니다. 이 패턴은 런타임에 원하는만큼 데코레이터를 추가 할 수있는 유연성을 제공합니다.

4. 결론

이 기사에서는 데코레이터 디자인 패턴을 살펴 보았습니다. 다음과 같은 경우에 좋은 선택입니다.

  • 객체의 동작이나 상태를 추가, 향상 또는 제거하려는 경우
  • 클래스의 단일 객체의 기능을 수정하고 다른 객체는 변경하지 않으려는 경우

이 예제의 전체 소스 코드는 GitHub에서 사용할 수 있습니다.