묠니르묘묘
꾸준히 성장하는 개발자스토리
묠니르묘묘
전체 방문자
오늘
어제
  • 분류 전체보기 (188)
    • 프로그래밍 (48)
      • 디자인패턴 (4)
      • 예외,에러 (4)
      • Java (29)
      • Kotlin (3)
      • React.js (4)
      • JavaScript (2)
      • Apache Kafka (2)
    • Spring (49)
      • Spring (21)
      • Spring Cloud (3)
      • JPA (25)
    • 코딩테스트 (31)
      • 알고리즘 (5)
      • Java - 백준 (26)
      • Java - 프로그래머스 (0)
    • AWS (7)
    • 데이터베이스 (6)
    • 개발 etc (23)
    • 도서 (5)
    • 회고록 (4)
    • 데브코스-데이터엔지니어링 (15)

인기 글

최근 글

hELLO · Designed By 정상우.
묠니르묘묘

꾸준히 성장하는 개발자스토리

프로그래밍/디자인패턴

Delegate Pattern(델리게이트 패턴, 위임 패턴)이란?

2023. 3. 15. 20:46

* 23.03.29 코드수정

Delegate 패턴이 '헤드퍼스트 디자인 패턴' 도서에 나와있지 않아서 정리해보고자 한다.

아무래도 Decorator 패턴 또는 strategy 패턴과 비슷하기 때문일까?

또한, 이 Delegate 패턴이 Decorator 패턴이랑 혼동된 블로그 글도 나와있기에 힘들었다.

그리고 Strategy 패턴과 유사한 부분이 있어서 이 점도 많이 헷갈렸다.

 

🤔 Delegate 패턴이란?

  • delegate는 '위임하다' 라는 사전적 의미를 가지고 있음
  • 즉, 객체가 자신의 기능을 다른 객체에게 위임하여 기능을 실행하는 디자인 패턴
  • 객체 간의 결합도를 낮춰서 유지보수성과 확장성을 높이는데 사용됨

예를 들면 다음과 같다

  • A는 B의 기능을 사용하고 싶을 때, A가 B의 기능을 직접 구현하지 않고, C에게 위임(delegate)하여 구현하는 것
  • 이 때 C를 델리게이트(delegate) 객체 or 대리자 객체라고 함
  • 델리게이트 객체는 B의 기능을 대신 구현하기 때문에, A는 C를 통해 B의 기능을 호출할 수 있음
  • 이를 통해 A는 B의 기능을 사용할 수 있으면서도, A와 B의 결합도를 낮출 수 있음

위 예시를 좀 더 구체적으로 말해보면 다음과 같다

  • A가 동물의 울음소리를 출력하고 싶음
  • B는 다양한 동물이 존재함
  • A는 B에 직접적으로 접근하지 않고, 울음소리를 출력하는 기능을 C에게 위임
  • C는 B에서 적절한 동물의 울음소리를 선택하여 출력할 수 있음
  • 이처럼 A와 B의 결합도를 낮추면서 다양한 동물의 울음소리를 출력할 수 있음

 

💻 Delegate 패턴을 적용한 예시코드

public enum AnimalKind {
    CAT, DOG
}

public interface Animal {
    void makeSound();
    AnimalKind getKind();
    boolean isSameKind(AnimalKind kind);
}

// B
public class Cat implements Animal {
    @Override
    public void makeSound() {
        System.out.println("야옹");
    }
    
    @Override
    public AnimalKind getKind() {
    	return AnimalKind.CAT;
    }
    
    @Override
    public boolean isSameKind(AnimalKind kind) {
    	return AnimalKind.CAT.equals(kind);
    }
}

// B
public class Dog implements Animal {
    @Override
    public void makeSound() {
        System.out.println("멍멍");
    }

    @Override
    public AnimalKind getKind() {
    	return AnimalKind.DOG;
    }
    
    @Override
    public boolean isSameKind(AnimalKind kind) {
    	return AnimalKind.DOG.equals(kind);
    }
}

// C
public class AnimalDelegator {
	private final List<Animal> animals;
    
    public AnimalDelegator() {
    	animals = new ArrayList<>();
    	animals.add(new Cat());
        animals.add(new Dog());
    }

    public void makeSound(AnimalKind kind) {
        animals.stream()
                .filter(animal -> animal.isSameKind(kind))
                .forEach(Animal::makeSound);
    }
}

// A
public class Client {
    public static void main(String[] args) {
        AnimalDelegator delegator = new AnimalDelegator();
        delegator.makeSound(AnimalKind.CAT); // "야옹" 출력
        delegator.makeSound(AnimalKind.DOG); // "멍멍" 출력
    }
}
  • A는 `Client` 클래스
  • B는 `Cat`와 `Dog` 클래스
  • C는 `AnimalDelegator` 클래스
  • A는 C의 makeSound()를 호출함으로써 동물의 울음소리를 출력
  • A는 B에게 직접적으로 접근하지 않고, 울음소리를 출력하는 기능을 C에게 위임
  • C는 B에서 적절한 동물의 울음소리를 선택하여 출력

 

위 코드는 여기를 클릭하면 나옴

📚 Delegate 패턴과 Decorator 패턴 차이점

🚀 Decorator 패턴

  • 객체에 동적으로 기능을 추가 또는 변경할 수 있는 패턴
  • "객체가 가진 기본 기능을 변경하지 않으면서 기능을 추가하는 것"이 핵심
  • 기본 객체를 래핑(Wrapping)하여 추가적인 기능을 제공하고, 이를 계속 래핑하여 여러 개의 데코레이터가 중첩될 수 있음
  • 상속을 이용하여 구현하는 경우가 많음

 

🚀 Delegate 패턴

  • 객체의 행위를 다른 객체에 위임하는 패턴
  • "객체가 다른 객체에게 일부 기능을 위임할 수 있도록 하는 것"이 핵심
  • 객체가 직접적으로 기능을 수행하는 것 대신에 다른 객체에 해당 기능을 위임
  • 인터페이스를 이용하여 구현하는 경우가 많음

 

🚀 결론

  • Decorator 패턴은 객체의 기능을 동적으로 확장하는 것이 목적
    • 원래 객체는 변하지 않으며 새로운 Decorator 객체를 사용할 수 있음
  • Delegate 패턴은 객체의 동작을 다른 객체에 위임하는 것이 목적
    • 원래 객체의 동작이 변경될 수 있음

 

📚 Delegate 패턴과 Strategy 패턴 차이점

🚀 Strategy 패턴

  • 동일한 문제를 해결하기 위한 알고리즘을 캡슐화하고, 이를 교환해서 사용하는 패턴
  • 즉, 알고리즘을 인터페이스로 정의하고 이를 구현한 다양한 전략 객체를 필요에 따라 교체하여 사용
  • 전략 객체들은 같은 문제를 해결하기 위한 다양한 알고리즘으로, 서로 교체 가능하며, 동적으로 알고리즘을 변경 가능

 

🚀 결론

  • Stragegy 패턴은 실행 중에 알고리즘을 변경하기 위한 패턴
    • e.g. 할인 적용 시, 다양한 할인 전략에 따라 가격이 달라질 때
  • Delegate 패턴은 객체의 동작을 다른 객체에 위임하여 사용하기 위한 패턴
    • e.g. 주문 처리시, 여러 단계로 나누어 각 단계에서 다른 로직을 처리할 때

 

🧐 마무리

delegate 패턴이 다른 패턴들과 유사한 부분들이 많지만 그것이 나온 목적에 따라서 적용하면 될 것 같다.

따라서 내가 가진 기능 중에 일부분을 다른 객체에 위임시킬 때 사용하는 것이 델리게이트 패턴이라고 생각하자.

 


https://java-design-patterns.com/patterns/delegation/#explanation

저작자표시 비영리 (새창열림)

'프로그래밍 > 디자인패턴' 카테고리의 다른 글

Decorator(데코레이터) 패턴이란?  (0) 2023.04.18
Observer(옵저버) 패턴이란?  (0) 2023.03.30
Strategy Pattern(전략 패턴)이란?  (0) 2023.03.21
    '프로그래밍/디자인패턴' 카테고리의 다른 글
    • Decorator(데코레이터) 패턴이란?
    • Observer(옵저버) 패턴이란?
    • Strategy Pattern(전략 패턴)이란?
    묠니르묘묘
    묠니르묘묘

    티스토리툴바