✅ 행위패턴 (Behavioral Patterns) -11가지
행위 패턴은 클래스나 객체 간의 상호작용, 즉 "누가 언제 무엇을 어떻게 수행할 것인가"에 초점을 맞춘 디자인 패턴이다. 객체나 클래스 사이의 책임 분배와 상호작용을 더 유연하게 만들어주는 패턴들이다.
🎯 1. 행위 패턴이란?
객체들의 상호작용(행동)을 조절하는 디자인 패턴의 모음이다.
코드를 효율적으로 만들고, 변경에 유연하게 대응할 수 있도록 도와준다.
- 초점: “행동을 어떻게 나눌까?”
- 목적: 결합도를 낮추고, 행동 흐름을 유연하게 만들기
- 사용 시기: 객체들 간의 복잡한 로직이나 의사소통이 필요할 때
[행 미인이 템옵 스테 비커 스트 매체]
-> 미인이 템포 옵 되어 스테이크를 비커에 넣어 스트레이트로 마시다가 메체에 소개되었따. (수제비 책 출처)
패턴 | 핵심 키워드 |
중재자 (미 Mediator) |
중앙 소통 관리, 객체 간 간섭 제거 상호 작용의 유연한 변경을 지원 |
인터프리터 (인 Interpreter) |
문법 해석기, 표현식 계산 구문의 해석을 맡는 클래스를 작성 문법 자체를 캡슐화하여 이용 |
반복자 (이 Iterator) |
내부구조 은닉하며, 순차적으로 접근 가능 |
템플릿 메서드 (템 Template Method) |
알고리즘 틀 고정, 세부는 위임 전체구조 변경x, 특정 단계 수행 변경 o ( 상위 작업 구조 바꾸지 않고, 서브 클래스로 작업 일부분 수행) 유지보수 용이 |
옵저버 (옵 Observer) |
변화 감지 한 객체의 상태가 바뀌면 -> 의존하는 객체들 자동으로 변경 일대 다 의존성 상호작용 객체 간 느슨한 결합 |
상태 (스 State) |
객체 상태를 캡슐화하여 클래스화 객체 상태에 따라 행위 내용을 변경 변경 시 기존 코드 수정 최소화 -> 유지보수 편의성 증가 |
방문자 (비 Visitor) |
처리기능 분리하여 별도의 클래스 생성 해당 클래스 메서드(외부회계사가) 각 클래스 돌아다니며(회사마다) 특정 작업 수행(세무조사,감사,보고서작성 등의 기능 수행) 구조는 그대로, 기능만 외부에서 추가 또는 확장 |
커맨드 (커 Command) |
요청(요구사항)을 객체로 캡슐화, 실행/취소/기록 가능 재사용성 높은 클래스 설계 하나의 추상 클래스에 메서드 만들어 각 명령 들어오면 그에 맞는 서브 클래스 실행 |
전략 (스트 Strategy) |
알고리즘 군 정의하여 같은 알고리즘을 클래스화하여 캡슐화 필요할 때 서로 교환해서 사용 ( 알고리즘 교환 가능 ) 즉, 행위 객체를 클래스로 캡슐화하여 동적으로 행위를 자유롭게 바꿀 수 있음 |
메멘토 (메 Memento) |
상태 저장/복원, 되돌리기 객체 정보 저장 시 적용하는 디자인 패턴 Undo 기능 개발 시 사용 |
책임 연쇄 (체 Chain of Responsibility) |
순차 처리, 책임 전가 구조 처리할 객체들들 연결고리로 만들어서 요청이오면 각 객체는 내가 처리할 수 있는지 판단 후 못하면 다음 객체에게 넘기는 방식(책임 전가) (ex.handler) |
[☞ 생성패턴 공부하러 가기]
[☞ 구조패턴 공부하러 가기
① 중재자 패턴 (Mediator Pattern)
객체 간 복잡한 대화를 중재인이 대신 처리!
🧠 개념
객체들 간의 직접 통신을 막고, 중앙의 중재자 객체가 대신 통신을 관리하게 하는 패턴
→ 복잡한 의존 관계를 깔끔하게 정리할 수 있음
- 객체 지향 설계에서 객체의 수가 너무 많아지면 서로 간 통신을 위해 복잡해져서 객체 지향에서 가장 중요한 느슨한 결합의 특성을 헤칠 수 있다. 이를 해결하는 방법으로 중간에 이를 통제하고 지시할 수 있는 역할을 하는 중재자를 두고, 중재자에게 모든 것을 요구하여 통신의 빈도수를 줄인다.
- 상호 작용의 유연한 변경을 지원
💻 쉬운 코드 예시: 수식 계산
// 중재자 인터페이스
interface ChatMediator {
void sendMessage(String message, User sender);
}
// 유저 클래스
class User {
String name;
ChatMediator mediator;
User(String name, ChatMediator mediator) {
this.name = name;
this.mediator = mediator;
}
void send(String message) {
System.out.println(name + " ▶ 메시지 전송: " + message);
mediator.sendMessage(message, this);
}
void receive(String message) {
System.out.println(name + " ◀ 메시지 수신: " + message);
}
}
// 중재자 구현체
class ChatRoom implements ChatMediator {
List<User> users = new ArrayList<>();
void addUser(User user) {
users.add(user);
}
public void sendMessage(String message, User sender) {
for (User u : users) {
if (u != sender) {
u.receive(message);
}
}
}
}
🧪 사용 예시
ChatRoom room = new ChatRoom();
User alice = new User("Alice", room);
User bob = new User("Bob", room);
User charlie = new User("Charlie", room);
room.addUser(alice);
room.addUser(bob);
room.addUser(charlie);
alice.send("안녕!"); // Bob, Charlie가 메시지 받음
② 인터프리터 패턴 (Interpreter Pattern)
- 언어의 다양한 해석, 구체적으로 구문을 나누고, 분리된 구문의 해석을 맡는 클래스를 각각 작성하여ㅠ 여러 형태의 언어 구문을 해석할 수 있게 만드는 디자인 패턴이다.
- 문법 자체를 캡슐화하여 사용.
// 표현식 인터페이스
interface Expression {
int interpret();
}
// 숫자 표현식
class Number implements Expression {
int value;
Number(int value) {
this.value = value;
}
public int interpret() {
return value;
}
}
// 덧셈 표현식
class Plus implements Expression {
Expression left, right;
Plus(Expression left, Expression right) {
this.left = left;
this.right = right;
}
public int interpret() {
return left.interpret() + right.interpret();
}
}
// 사용예시
Expression expr = new Plus(new Number(2), new Number(3));
System.out.println(expr.interpret()); // 5
③ 반복자 패턴 (Iterator Pattern)
내부 구현을 몰라도 **모든 요소를 하나씩 순회(iterate)**할 수 있게 해주는 패턴
- 컬렉션 구현 방법을 노출시키지 않으면서도 그 집합체 안에 들어있는 모든 항목에 반복자를 사용하여 접근할 수 있는 디자인 패턴
- 내부구조를 노출하지 않고, 복잡 객체의 원소를 순차적으로 접근 가능하게 해주는 행위 패턴
// 간단한 컬렉션
class MyList {
List<String> items = new ArrayList<>();
void add(String item) {
items.add(item);
}
Iterator<String> getIterator() {
return items.iterator(); // Java의 내장 반복자 사용
}
}
// 사용예시
MyList list = new MyList();
list.add("🍎");
list.add("🍌");
list.add("🍇");
Iterator<String> it = list.getIterator();
while (it.hasNext()) {
System.out.println("과일: " + it.next());
}
④ 템플릿 메서드 패턴 (Template Method Pattern)
📘 어원
template = 템플릿, 틀
method = 메서드, 동작
→ "전체 알고리즘의 틀은 정의하고, 세부 단계는 서브클래스에 맡기는 구조.
🧠 개념
어떤 알고리즘의 골격(템플릿)은 상위 클래스에 정의하고,
그 중 일부 단계를 하위 클래스에서 재정의하는 방식
🧃 실생활 비유
라면 끓이는 순서는 같지만,
스프나 재료는 취향 따라 바뀌는 것
💻 쉬운 코드 예시
// 추상 클래스: 요리 템플릿
abstract class RamenRecipe {
final void cook() { // 고정된 순서 (변경 불가)
boilWater();
addNoodles();
addIngredients(); // 이건 사용자 정의
eat();
}
void boilWater() {
System.out.println("물을 끓입니다.");
}
void addNoodles() {
System.out.println("면을 넣습니다.");
}
abstract void addIngredients(); // 서브클래스에서 정의할 부분
void eat() {
System.out.println("맛있게 먹습니다.");
}
}
// 사용자 구현
class SpicyRamen extends RamenRecipe {
void addIngredients() {
System.out.println("🌶️ 매운 스프와 고추를 넣습니다.");
}
}
⑤ 옵저버 패턴 (Observer Pattern)
📘 어원
observe = 관찰하다, 지켜보다
→ "어떤 대상의 상태 변화에 따라 자동으로 반응하는 객체들"
🧠 개념
하나의 객체의 상태가 바뀌면,
그 객체를 관찰하던 다른 객체들에게 자동으로 알려주는 구조
🧃 실생활 비유
- 유튜브 구독: 새 영상 업로드 시 구독자들에게 알림
- 날씨 앱: 기상청 데이터 바뀌면 화면도 자동으로 갱신됨
💻 쉬운 코드 예시: 뉴스 발행 시스템
// 옵저버 (구독자)
interface Subscriber {
void update(String news);
}
// 발행자 (기자)
class NewsAgency {
List<Subscriber> subscribers = new ArrayList<>();
void subscribe(Subscriber s) {
subscribers.add(s);
}
void notifyAll(String news) {
for (Subscriber s : subscribers) {
s.update(news);
}
}
}
// 구독자 구현
class EmailSubscriber implements Subscriber {
String name;
EmailSubscriber(String name) { this.name = name; }
public void update(String news) {
System.out.println(name + " ▶ 이메일로 뉴스 수신: " + news);
}
}
🧪 사용 예시
// 사용예시
NewsAgency agency = new NewsAgency();
agency.subscribe(new EmailSubscriber("민수"));
agency.subscribe(new EmailSubscriber("철수"));
agency.notifyAll("📢 새로운 정책 발표!");
⑥ 상태 패턴 (State Pattern)
📘 어원
state = 상태
→ 객체의 상태에 따라 동작이 달라지도록 설계하는 패턴
🧠 개념
객체 내부 상태가 바뀌면,
**행동(메서드 결과)**도 바뀌도록 하는 구조
🧃 실생활 비유
- ATM 기계: 카드가 없을 때 / 있을 때 / 돈 출금 중 → 행동이 다름
- 신호등: 빨간불, 노란불, 초록불일 때 각기 다른 동작
💻 쉬운 코드 예시
interface State {
void pressButton();
}
// 상태 A: 대기 상태
class ReadyState implements State {
public void pressButton() {
System.out.println("⏯️ 음악 재생 시작");
}
}
// 상태 B: 재생 중
class PlayingState implements State {
public void pressButton() {
System.out.println("⏸️ 음악 일시 정지");
}
}
// 음악 플레이어 (상태에 따라 행동이 달라짐)
class MusicPlayer {
State state;
void setState(State s) {
this.state = s;
}
void pressPlay() {
state.pressButton();
}
}
🧪 사용 예시
// 사용예시
MusicPlayer player = new MusicPlayer();
player.setState(new ReadyState());
player.pressPlay(); // ▶ 재생 시작
player.setState(new PlayingState());
player.pressPlay(); // ⏸️ 일시 정지
⑦ 방문자 패턴 (Visitor Pattern)
📘 어원
visit = 방문하다 → “객체에 새로운 기능을 ‘방문자’가 추가해주는 구조”
🧠 개념
객체 구조는 그대로 두고,
기능만 외부에서 분리해서 확장할 수 있게 하는 패턴
🧃 실생활 비유
- **세무사(방문자)**가 회사(객체)를 방문해서 회계 점검을 해줌
- 회사 내부는 그대로인데, 방문자가 기능을 더해주는 방식
- 도형 도색 프로그램
- 사각형, 원 등의 도형이 있음
- 도형 클래스에는 좌표나 크기만 있고, ‘색칠하기’ 기능은 없음
- 색칠하기 기능을 외부에서 추가하고 싶을 때 → 방문자 패턴 사용!
💻 쉬운 코드 예
📦 1. 방문자 인터페이스 정의
// 방문자: 도형을 방문해서 색칠하는 기능 제공
interface ShapeVisitor {
void visitCircle(Circle circle);
void visitRectangle(Rectangle rectangle);
}
🧩 2. 도형 공통 인터페이스 정의
// 도형은 모두 이 인터페이스를 구현해야 함
interface Shape {
void accept(ShapeVisitor visitor); // 방문자를 받아들임
}
🟠 3. 도형 클래스 구현 (Circle, Rectangle)
class Circle implements Shape {
int radius;
Circle(int radius) {
this.radius = radius;
}
public void accept(ShapeVisitor visitor) {
visitor.visitCircle(this); // 방문자야, 원(Circle)을 처리해줘
}
}
class Rectangle implements Shape {
int width, height;
Rectangle(int w, int h) {
this.width = w;
this.height = h;
}
public void accept(ShapeVisitor visitor) {
visitor.visitRectangle(this); // 방문자야, 사각형을 처리해줘
}
}
🎨 4. 방문자 구현: 도형을 색칠하는 기능
class PaintVisitor implements ShapeVisitor {
public void visitCircle(Circle circle) {
System.out.println("🟠 반지름 " + circle.radius + "인 원을 주황색으로 칠함!");
}
public void visitRectangle(Rectangle rect) {
System.out.println("🟥 " + rect.width + "x" + rect.height + " 사각형을 빨간색으로 칠함!");
}
}
🧪 5. 실제 사용 예시
public class Main {
public static void main(String[] args) {
// 도형 객체 생성
Shape circle = new Circle(5);
Shape rect = new Rectangle(3, 4);
// 방문자 객체 생성 (색칠 기능)
ShapeVisitor painter = new PaintVisitor();
// 도형에 방문자를 전달 (색칠됨!)
circle.accept(painter); // 🟠
rect.accept(painter); // 🟥
}
}
🧾 출력 결과
🟠 반지름 5인 원을 주황색으로 칠함!
🟥 3x4 사각형을 빨간색으로 칠함!
✅ 핵심 흐름 요약
- 도형은 accept(visitor)를 제공함
- 방문자 객체는 visitCircle(circle) 등 도형별 처리 로직을 정의
- 도형에 방문자를 전달 → 도형의 구조는 그대로, 기능만 외부에서 처리
⑧ 커맨드 패턴 (Command Pattern)
📘 어원
command = 명령 → “요청(명령)을 객체로 캡슐화해서 실행시기를 제어할 수 있음”
🧠 개념
명령을 객체로 만들어서 요청, 실행, 취소, 기록 등을 유연하게 처리
🧃 실생활 비유
- 리모컨에 있는 버튼들: 각 버튼이 특정 명령을 수행
- "실행취소(Undo)", "다시 실행(Redo)" 기능 만들 때 유용
💻 쉬운 코드 예시
// 커맨드 인터페이스
interface Command {
void execute();
}
// 실제 명령: 전등 켜기
class LightOnCommand implements Command {
public void execute() {
System.out.println("💡 전등을 켭니다!");
}
}
// 리모컨 클래스
class RemoteControl {
Command command;
void setCommand(Command c) {
command = c;
}
void pressButton() {
command.execute();
}
}
🧪 사용 예시
Command lightOn = new LightOnCommand();
RemoteControl remote = new RemoteControl();
remote.setCommand(lightOn);
remote.pressButton(); // 💡 전등을 켭니다!
⑨ 전략 패턴 (Strategy Pattern)
📘 어원
strategy = 전략, 방식 → “행동 방법을 바꿀 수 있도록 알고리즘을 분리”
🧠 개념
알고리즘(행동 방법)을 객체로 분리해서,
필요할 때 전략을 바꿔 쓸 수 있는 구조
🧃 실생활 비유
- 네비게이션 경로 선택: 가장 빠른 길 / 최소 요금 / 경로 우선 전략 선택
- 게임 캐릭터가 공격 전략을 바꿀 수 있음
💻 쉬운 코드 예시
// 전략 인터페이스
interface PaymentStrategy {
void pay(int amount);
}
// 전략 1: 카드 결제
class CardPayment implements PaymentStrategy {
public void pay(int amount) {
System.out.println("💳 카드로 " + amount + "원 결제");
}
}
// 전략 2: 계좌 이체
class BankTransfer implements PaymentStrategy {
public void pay(int amount) {
System.out.println("🏦 계좌이체로 " + amount + "원 결제");
}
}
🛒 결제 컨텍스트 클래스
class Checkout {
PaymentStrategy strategy;
void setStrategy(PaymentStrategy s) {
strategy = s;
}
void payBill(int amount) {
strategy.pay(amount);
}
}
🧪 사용 예시
Checkout order = new Checkout();
order.setStrategy(new CardPayment());
order.payBill(10000);
order.setStrategy(new BankTransfer());
order.payBill(8000);
⑩ 메멘토 패턴 (Memento Pattern)
📘 어원
memento = 추억, 기억
→ "객체의 상태를 저장해서 되돌릴 수 있는 구조"
🧠 개념
객체의 상태를 저장하고,
나중에 그 상태로 복원(undo) 가능하게 하는 패턴
🧃 실생활 비유
- Ctrl + Z (실행취소)
- 게임 저장 & 불러오기 기능
💻 쉬운 코드 예시
// 메멘토: 상태 저장소
class TextMemento {
String text;
TextMemento(String text) {
this.text = text;
}
String getText() {
return text;
}
}
🎨 에디터 클래스 (저장/복원 기능)
class Editor {
String text = "";
void write(String newText) {
text = newText;
}
TextMemento save() {
return new TextMemento(text);
}
void restore(TextMemento memento) {
text = memento.getText();
}
void print() {
System.out.println("📝 현재 텍스트: " + text);
}
}
🧪 사용 예
Editor editor = new Editor();
editor.write("1차 작성");
TextMemento backup = editor.save(); // 저장
editor.write("2차 수정");
editor.print(); // 📝 2차 수정
editor.restore(backup); // 복원
editor.print(); // 📝 1차 작성
⑪ 책임 연쇄 패턴 (Chain of Responsibility)
📘 어원
chain = 사슬, responsibility = 책임
→ "여러 객체가 책임을 나눠서 처리하고, 조건 안 맞으면 다음에게 넘김"
🧠 개념
요청을 순차적으로 여러 객체에게 넘기면서 처리할 수 있는 구조
🧃 실생활 비유
- 고객센터 전화 → 상담원 1 → 못하면 상급자 → 그래도 안되면 관리자
- 웹 필터 체인: 인증 → 권한 검사 → 로깅 등
💻 쉬운 코드 예시
abstract class Handler {
Handler next;
void setNext(Handler n) {
next = n;
}
void handle(String request) {
if (next != null) {
next.handle(request); // 다음으로 넘김
}
}
}
// 실제 핸들러
class Manager extends Handler {
void handle(String request) {
if (request.equals("문서 결재")) {
System.out.println("👨💼 매니저가 문서를 결재합니다.");
} else {
super.handle(request);
}
}
}
class Director extends Handler {
void handle(String request) {
if (request.equals("예산 승인")) {
System.out.println("👩💼 이사가 예산을 승인합니다.");
} else {
super.handle(request);
}
}
}
🧪 사용 예시
Handler manager = new Manager();
Handler director = new Director();
manager.setNext(director);
manager.handle("문서 결재"); // 매니저가 처리
manager.handle("예산 승인"); // 매니저 → 이사 처리
[☞ 생성패턴 공부하러 가기]
[☞ 구조패턴 공부하러 가기
'자격증 > 정보처리기사' 카테고리의 다른 글
[정보처리기사 실기 이론] 네트워크 신기술 용어 (1) | 2025.07.17 |
---|---|
[정보처리기사 실기 이론] 블랙박스 테스트 개념 및 유형 종류-동경결상 유분페 원비오 (4) | 2025.07.15 |
[정보처리기사 실기 이론] 화이트박스 테스트 개념 및 유형 종류, 커버리지 개념 (3) | 2025.07.14 |
[정보처리기사 실기 이론] 네트워크 공격 기법 - 스니핑/네트워크 스캐너/스니퍼/패스워드 크래킹/IP스푸핑/ARP스푸핑/ICMP 리다이렉트/트로이목마 (1) | 2025.07.13 |
[정보처리기사 실기 이론] 세션 하이재킹(Session Hijacking) 개념 | 탐지 방법 (0) | 2025.07.11 |