코드 디자인 패턴/java

[java & 디자인 패턴] Decorator 패턴 정리

tea-tea 2024. 7. 17. 07:04

개념


이 패턴은 객체의 동작을 동적으로 추가하기 위해 사용한다.

기본적으로 자바는 클래스간에 상속으로 확장 방식을 지원하지만 단일 상속이 중심이라 한계가 존재하는데, 이 패턴은 이런 문제를 해결해줄 수 있다.

 

장점

  • 유연한 기능 확장(상속 대체): 객체의 기능을 동적으로 추가하거나 변경하는 유연성 제공
  • 코드 재사용성 증가: 여러 데코레이터를 조합하여 다양한 기능을 재사용할 수 있습니다.
  • 동적 결합 : 클래스 상속처럼 컴파일 시점에 확장이 아니라 런타임 후 동적으로 확장 가능

단점

  • 많은 객체 생성 | 데코레이터 패턴은 많은 추가 객체 및 인스턴스를 늘리며 setter도 복잡하여서 코드가 많아진다. 그래서 팩토리 패턴이나 빌더 패턴과 같이 사용한다.
  • 디버깅 어려움 | 많은 데코레이터가 중첩되면 디버깅이 어려워진다. 구상 구성요소(concrete component)의 형식을 알아내서 그에 따라 작업을 처리하는 코드에는 적용 불가. , 기존 클래스를 래핑하는 과정에서 사양이 달라 질수 있음(데코레이터 패턴을 적용하여 'A' ''로 한 번 감싸게 되면 사용할 때 ''인것은 알 수 있지만 이게 A로 만든 것인지 B로 만든 것인지 알 수 없음)

 

구현


 

Component (구성 요소)

기본 단위 기능을 구현하기 위한 인터페이스 또는 추상 클래스

public abstract class ABScharacter {

	protected String name;
	
	public String getName() {
		return this.getName();
	}
	
	public abstract void interActNPC();
	
	
}


ConcreteComponent (구체적인 구성 요소)

Component를 구현한 실제 객체. 기본적인 기능 제공

public class Character extends ABScharacter {

	public Character(String name) {
		// TODO Auto-generated constructor stub
		this.name = name;
	}

	@Override
	public void interActNPC() {
		// TODO Auto-generated method stub
		System.out.println("npc와 반갑게 이야기를 나눕니다");

	}

}

 

Decorator (데코레이터)

Component 인터페이스를 구현하고, 구성 요소를 포함하는 추상 클래스

기능을 확장하기 위해 메서드를 재정의


import case1.prac1.base.ABScharacter;

public abstract class Decorator extends ABScharacter {

	
	public abstract String getName();
}

 

ConcreteDecorator (구체적인 데코레이터): Decorator를 구현한 클래스

원래 구성요소의 인터페이스 사양을 구현하면서 기존의 구현 클래스와 메소드를 이용해 확장한다. 

import case1.prac1.base.ABScharacter;

public class warrior extends Decorator {
	private ABScharacter character;

	public warrior(ABScharacter abScharacter) {
		// TODO Auto-generated constructor stub
		this.character = abScharacter;
	}

	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return this.character.getName() + " warrior";
	}

	@Override
	public void interActNPC() {
		// TODO Auto-generated method stub
		this.character.interActNPC();
		System.out.println("npc가 기사에게 호감을 보입니다.");

	}

}