많이 쓰인다

✅ 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); // 타입으로 찾아서 위임
}
}


Share article