Design pattern 8. Delegate Pattern

김미숙's avatar
Jul 23, 2025
Design pattern 8. Delegate Pattern
💡
많이 쓰인다
notion image
 

✅ Delegate Pattern란?

  • 객체 지향 설계에서 자신이 해야 할 작업을 다른 객체에 위임(delegate) 하는 패턴
  • 델리게이트 패턴은 어떤 객체가 자신이 처리해야 할 작업을 다른 객체에 위임하는 구조
  • 즉, 자기가 직접 처리하지 않고 대신 해줄 다른 객체에게 전달(위임)
 

✅ 핵심 개념

  • 위임(Delegation) = “나 대신 저 친구가 처리하게 할게!”
  • 상속보다 합성(composition)과 위임을 선호하는 설계 방식
  • 주로 유연한 책임 분리로직 재사용을 위해 사용됨
 

✅ 구조

┌─────────────┐ │ Client │ 호출자 └────┬────────┘ │ 호출 ▼ ┌─────────────┐ │ Delegator │ → 일을 맡는 객체 │ (위임자) │ │ has a Delegate │ └────┬────────┘ │ 위임 ▼ ┌─────────────┐ │ Delegate │ → 실제로 일을 처리하는 객체 └─────────────┘
 

✅ 예시 (자바 스타일)

📌 인터페이스 정의
public interface Printer { void print(String message); }
📌 실제 로직 처리하는 클래스 (Delegate)
public class ConsolePrinter implements Printer { public void print(String message) { System.out.println("출력: " + message); } }
📌 위임자 (Delegator)
public class Report { private Printer printer; // 위임할 대상 public Report(Printer printer) { this.printer = printer; } public void generate(String content) { // 본인은 직접 출력하지 않고 프린터에게 위임 printer.print("리포트 내용: " + content); } }
📌 사용 예
Printer printer = new ConsolePrinter(); Report report = new Report(printer); report.generate("월간 매출 보고서");
 

✅ Delegate Pattern vs Decorator Pattern

구분
델리게이트 패턴
데코레이터 패턴
목적
일을 위임
기능을 감싸서 확장
위임 대상
다른 객체에게 위임
자기 자신과 같은 타입의 객체를 감싸서 확장
설계 구조
"위임"
"감싸기"
Report → Printer
BufferedReader → Reader
 

✅ 실전 활용 예

분야
설명
안드로이드 개발
Activity → AppCompatDelegate에 UI 위임
자바 Swing
이벤트 처리에서 위임 객체 사용
스프링 Bean 구성
전략 객체나 서비스 위임
 

✅ 장점

장점
설명
코드 재사용
위임 객체가 여러 곳에서 재사용 가능
책임 분리
역할이 분리되어 유지보수 쉬움
유연한 설계
런타임에 다른 객체로 교체 가능 (전략 패턴과 유사)
 

✅ 요약

항목
내용
목적
일을 다른 객체에 위임
키워드
위임, 합성, 유연성
특징
자신은 처리하지 않고 다른 객체에게 전달
관련 패턴
전략 패턴, 프록시 패턴과 비슷한 구조
 

✅ Delegate Pattern vs Proxy Pattern

  • Delegate(델리게이트) 패턴과 Proxy(프록시) 패턴은 자신의 작업을 다른 객체에 위임한다는 점에서 아주 비슷하지만 의도와 책임, 목적에서 차이가 있다.

✅ 공통점

항목
내용
구조
둘 다 내부에 **다른 객체(Real Object)**를 가지고 있음
메서드 호출
외부에서는 둘 다 프록시나 위임자가 호출을 대신 처리
목적
“나 대신 처리해줄 객체가 있어요” 구조 사용
 

✅ 차이점

구분
델리게이트 패턴
프록시 패턴
목적
역할을 분리하고 재사용성 확보
접근 제어나 부가 기능 처리
중심 역할
실제 작업을 수행할 객체에게 위임
자신도 의미 있는 작업을 하거나 제한을 걸기도 함
관점
내부 구현 분리 / 유연한 설계
대리 객체를 통해 원래 객체에 접근
예시
UI 컴포넌트가 렌더링을 델리게이트에게 위임
RemoteProxy, SecurityProxy, LazyProxy 등
의도
"나는 이 일의 책임이 없어. 대신 저 객체가 잘해줄 거야."
"나를 통해야만 진짜 객체에 접근할 수 있어."
 

✅ 간단한 비유

  • Delegate:
    • “나는 일 못 해. 옆에 있는 전문가한테 물어봐.”
  • Proxy:
    • “일단 나를 통해서 요청해. 내가 검토하고 진짜 객체에 전달할게.”
       

✅ 코드로 짧게 비교

🔸 Delegate

class Printer { void print(String msg) { System.out.println(msg); } } class Report { Printer printer; void generate() { printer.print("Report"); } }
Report는 Printer에게 출력 책임을 위임만 함

🔸 Proxy

class PrinterProxy { private RealPrinter realPrinter = new RealPrinter(); void print(String msg) { System.out.println("접근 로그 기록..."); realPrinter.print(msg); } }
PrinterProxy는 자체적으로 부가 로직 수행 후, 실제 객체에게 전달
 

✅ 결론

둘 다 위임 구조지만,
델리게이트는 기능을 분리해서 유연성 확보
프록시는 접근 제어, 로깅, 캐싱 등의 목적으로 대리인 역할을 한다.
 

✅ Delegate Pattern vs Strategy Pattern

  • 둘 다 작업을 외부 객체에 위임한다는 공통점이 있지만, 의도와 유연성, 설계 방향에서 중요한 차이점이 있습니다.
패턴
핵심 개념
🧭 전략(Strategy) 패턴
행위를 외부에서 갈아끼울 수 있게(선택 가능하게) 위임
🙋‍♀️ 델리게이트(Delegate) 패턴
자기가 해야 할 일을 다른 객체에게 “그냥” 맡기는 위임
 

✅ 비교 표

구분
델리게이트 패턴
전략 패턴
✅ 목적
책임 분리 & 기능 위임
알고리즘을 교체/선택 가능하게
✅ 전략성
없음 (고정된 위임 대상)
있음 (동적으로 바꿀 수 있음)
✅ 주체
위임자(Delegator)가 Delegate에게 단순히 위임
컨텍스트(Context)가 전략(Strategy)을 선택하고 사용
✅ 관계
“나 대신 얘가 일해요”
“상황에 맞게 다양한 전략 중 하나를 써요”
✅ 인터페이스 설계
필수 아님 (단순 위임)
보통 공통 인터페이스를 두고 여러 전략 구현체 사용
✅ 예시
UI 위임, 이벤트 처리
정렬 알고리즘 교체, 결제 방식 선택 등
 

✅ 예제로 비교

🎯 Delegate Pattern
class Printer { void print(String msg) { System.out.println(msg); } } class Report { Printer printer; public Report(Printer printer) { this.printer = printer; } void generate() { printer.print("리포트 출력"); } }
  • Report는 항상 같은 Printer에게 위임함 (선택 아님)
  • 단순히 역할 분리가 목적
 
🎯 Strategy Pattern
interface PaymentStrategy { void pay(int amount); } class CardPayment implements PaymentStrategy { public void pay(int amount) { System.out.println("💳 카드로 결제: " + amount); } } class KakaoPayPayment implements PaymentStrategy { public void pay(int amount) { System.out.println("📱 카카오페이로 결제: " + amount); } } class Order { private PaymentStrategy payment; public void setPaymentStrategy(PaymentStrategy payment) { this.payment = payment; } public void checkout(int amount) { payment.pay(amount); } }
  • Order는 전략을 선택하고 갈아낄 수 있음
  • 상황에 따라 카드, 카카오페이 등 전략을 다르게 설정 가능
 

✅ 핵심 차이 요약

항목
델리게이트
전략 패턴
❓ 왜 위임하는가?
내가 하기 귀찮아서 (역할 분리)
유연하게 바꾸려고 (전략 선택)
🔁 전략 변경 가능?
❌ (고정된 위임 대상)
✅ (전략을 바꿔 끼울 수 있음)
🎯 패턴 목적
구현 분리
알고리즘 선택/확장 가능성
🧩 유스케이스
프린터 위임, UI 위임, 이벤트 위임
결제 방식, 정렬 알고리즘, 인증 전략 등

✅ 마무리 요약

  • Delegate Pattern → “내가 하기 싫으니까 대신 해줘”
  • Strategy Pattern → 지금 상황에 가장 알맞은 방법을 선택해서 써야 해”
 

실습

Teacher
package ex07.teacher; public interface Teacher { void doLecture(); boolean isSameLecture(LectureType lectureType); // 책임: 누구한테 위임할지 결정 }
LectureType
package ex07.teacher; public enum LectureType { MATH, SCIENCE, HISTORY; }
MathTeacher
package ex07.teacher; public class MathTeacher implements Teacher { public void doLecture() { System.out.println("수학 강의를 시작합니다"); } @Override public boolean isSameLecture(LectureType lectureType) { return LectureType.MATH.equals(lectureType); } }
HistoryTeacher
package ex07.teacher; public class HistoryTeacher implements Teacher { public void doLecture() { System.out.println("역사 강의를 시작합니다"); } @Override public boolean isSameLecture(LectureType lectureType) { return LectureType.HISTORY.equals(lectureType); } }
LectureDelegator
package ex07.teacher; import java.util.ArrayList; import java.util.List; // 책임: 요청에 맞는 전문가를 찾아서 위임 - 단일진입점 // 단일 진입점을 만들면 좋은 이유 - 하나의 오브젝트만 바라볼 수 있음 public class LectureDelegator { private List<Teacher> teachers = new ArrayList<>(); public LectureDelegator() { teachers.add(new HistoryTeacher()); teachers.add(new MathTeacher()); } public void delegate(LectureType lectureType) { teachers .stream() .filter(teacher -> teacher.isSameLecture(lectureType)) .forEach(teacher -> { teacher.doLecture(); }); } }
App
package ex07; import ex07.teacher.LectureDelegator; import ex07.teacher.LectureType; // Delegate (위임) public class App { public static void main(String[] args) { LectureDelegator lectureDelegator = new LectureDelegator(); // 1. 수학 lectureDelegator.delegate(LectureType.MATH); // 타입으로 찾아서 위임 // 2. 역사 lectureDelegator.delegate(LectureType.HISTORY); // 타입으로 찾아서 위임 } }
notion image
notion image
 
Share article

parangdajavous