
App.java
package ex06;
import ex06.notification.BasicNotifier;
import ex06.notification.EmailNotifier;
import ex06.notification.SmsNotifier;
public class App {
public static void main(String[] args) {
// Notifier b1 = new BasicNotifier();
// b1.send();
// System.out.println("_end");
//
// Notifier e1 = new EmailNotifier();
// e1.send();
// System.out.println("_end");
//
// Notifier s1 = new SmsNotifier();
// s1.send();
// System.out.println("_end");
// 1. 이메일 알림
EmailNotifier n1 = new EmailNotifier();
n1.send();
System.out.println("_end");
// 2. 이메일 알림 + 기본 알림
EmailNotifier n2 = new EmailNotifier(new BasicNotifier());
n2.send();
System.out.println("_end");
// 3. 이메일 알림 + 문자 알림
EmailNotifier n3 = new EmailNotifier(new SmsNotifier());
n3.send();
System.out.println("_end");
// 4. 문자 알림 + 기본 알림
SmsNotifier n4 = new SmsNotifier();
n4.send();
System.out.println("_end");
// 5. 문자 알림 + 이메일 알림 + 기본 알림
SmsNotifier n5 = new SmsNotifier(new EmailNotifier(new BasicNotifier()));
n5.send();
System.out.println("_end");
// 6. 문자 알림 + 문자 알림 + 이메일 알림 + 기본 알림
SmsNotifier n6 = new SmsNotifier(new SmsNotifier(new EmailNotifier(new BasicNotifier())));
ClientNotification.send(n6);
}
}
Notifier.java
package ex06.notification;
public interface Notifier {
void send();
}
ClientNotification.java
package ex06;
import ex06.notification.Notifier;
public class ClientNotification {
public static void send(Notifier s1) {
s1.send();
}
}
SmsNotifier.java
package ex06.notification;
public class SmsNotifier implements Notifier {
private Notifier notifier;
public SmsNotifier() {
}
public SmsNotifier(Notifier notifier) {
this.notifier = notifier;
}
@Override
public void send() {
System.out.println("문자 알림");
if (notifier != null) notifier.send();
}
}
EmailNotifier.java
package ex06.notification;
public class EmailNotifier implements Notifier {
private Notifier notifier;
public EmailNotifier() {
}
public EmailNotifier(Notifier notifier) {
this.notifier = notifier;
}
public void send() {
System.out.println("이메일 알림");
if (notifier != null) notifier.send();
}
}
BasicNotifier.java
package ex06.notification;
public class BasicNotifier implements Notifier {
public void send() {
System.out.println("기본 알림");
}
}
1. 패턴 목적
객체를 감싸며 기능을 점진적으로 확장할 수 있는 구조.상속 대신 **합성(Composition)**과 **위임(Delegation)**을 사용하여 유연하게 기능 추가함.
2. 구성 요소 정리
클래스명 | 역할 |
Notifier (인터페이스) | 알림을 보내는 공통 타입 정의 ( send() 메서드) |
BasicNotifier | 실제 알림을 보내는 기본 클래스 (기본 알림 출력) |
EmailNotifier | 이메일 알림 기능을 추가하는 데코레이터 |
SmsNotifier | 문자 알림 기능을 추가하는 데코레이터 |
ClientNotification | 알림 실행용 클라이언트 클래스 (Notifier 타입 받음) |
App | 알림 객체 조합 후 실행하는 메인 실행 클래스 |
3. 동작 방식
- 각 데코레이터는 내부에 Notifier를 포함(합성)하고 있음
send()
호출 시 자기 역할을 먼저 수행한 뒤, 내부 객체에send()
를 위임함
public void send() {
System.out.println("문자 알림"); // 자기 일 먼저
if (notifier != null) notifier.send(); // 내부 객체 호출
}
정리
Notifier
라는 **인터페이스(또는 추상 클래스)**를 만들고
→ 거기서
send()
라는 기능을 정의해둠 (즉, 반드시 구현해야 함)EmailNotifier
,SmsNotifier
같은 자식 클래스는Notifier
를 implements(또는 extends) 함- 따라서
send()
를 반드시 구현함
- 이 자식 클래스들은 생성자에서 Notifier 타입을 매개변수로 받음
- 즉, 자신과 같은 타입을 속에 들고 있음 (→ 합성, Composition)
send()
를 실행하면- 먼저 자기 역할을 수행 (예:
System.out.println("문자 알림")
) - 그리고 자기가 들고 있는 Notifier의
send()
도 호출함
- 이 구조가 계속 중첩되면
- 겉에서부터 감싸고
send()
실행 시에는 겉에서부터 안으로 차례대로 실행됨
- 그래서 결과적으로
- 기능을 조립하듯 추가할 수 있고
- 기존 클래스는 전혀 수정하지 않아도 됨 → OCP 만족
Share article