|이름|의도|
|:---|:---|
|Abstract Factory 추상 팩토리| 구체적인 클래스를 지정하지 않고 > 인터페이스를 통해 서로 연관되는 객체들을 그룹으로 표현 |
|Builder 빌더| 복합 객체의 생성과 표현을 분리하여 동일한 생성 절차에서도 다른 표현 결과를 만들어낼 수 있음 |
|Factory Method 팩토리 메소드|객체 생성을 서브클래스로 위임하여 캡슐화함 |
|Prototype 프로토타입| 원본 객체를 복사함으로써 객체를 생성 |
|Singleton 싱글톤| 어떤 클래스의 인스턴스는 하나임을 보장하고 어디서든 참조할 수 있도록 함구조 패턴 |
이름 의도 Adapter 어댑터 클래스의 인터페이스를 다른 인터페이스로 변환하여 다른 클래스가 이용할 수 있도록 함 Bridge 브리지 구현부에서 추상층을 분리하여 각자 독립적으로 확장할 수 있게 함 Composite 컴포지트 객체들의 관계를 트리 구조로 구성하여 복합 객체와 단일 객체를 구분없이 다룸 Decorator 데코레이터 주어진 상황 및 용도에 따라 어떤 객체에 다른 객체를 덧붙이는 방식 Facade 퍼싸드 서브시스템에 있는 인터페이스 집합에 대해 하나의 통합된 인터페이스(Wrapper) 제공 Proxy 프록시 접근이 어려운 객체로의 접근을 제어하기 위해 객체의 Surrogate나 Placeholder를 제공
서로 다른 인터페이스를 가진 두 개의 클래스를 함께 동작하도록 해주는 구조적인 패턴으로 호환되지 않는 인터페이스를 변환하여 하나의 인터페이스를 제공하여 객체들이 함께 작동할 수 있도록 하는 패턴
장점
단점
예시
// Adaptee : 클라이언트에서 사용하고 싶은 기존의 서비스 (하지만 호환이 안되서 바로 사용 불가능)
class Service {
void specificMethod(int specialData) {
System.out.println("기존 서비스 기능 호출 + " + specialData);
}
}
// Client Interface : 클라이언트가 접근해서 사용할 어댑터 모듈
interface Target {
void method(int data);
}
// Adapter : Adaptee 서비스를 클라이언트에서 사용하게 할 수 있도록 호환 처리 해주는 어댑터
class Adapter implements Target {
Service adaptee; // composition으로 Service 객체를 클래스 필드로
// 어댑터가 인스턴스화되면 호환시킬 기존 서비스를 설정
Adapter(Service adaptee) {
this.adaptee = adaptee;
}
// 어댑터의 메소드가 호출되면, Adaptee의 메소드를 호출하도록
public void method(int data) {
adaptee.specificMethod(data); // 위임
}
}
class Client {
public static void main(String[] args) {
// 1. 어댑터 생성 (기존 서비스를 인자로 받아 호환 작업 처리)
Target adapter = new Adapter(new Service());
// 2. Client Interfac의 스펙에 따라 메소드를 실행하면 기존 서비스의 메소드가 실행된다.
adapter.method(1);
}
}
이름 의도 Chain of Responsibility 책임 연쇄 청을 받는 객체를 연쇄적으로 묶어 요청을 처리하는 객체를 만날 때까지 객체 Chain을 따라 요청을 전달 Command 커맨드 청을 객체의 형태로 캡슐화하여 재사용하거나 취소할 수 있도록 저장 Interpreter 인터프리터 특정 언어의 문법 표현을 정의 Iterator 반복자 내부를 노출하지 않고 접근이 잦은 어떤 객체의 원소를 순차적으로 접근할 수 있는 동일한 인터페이스 제공 Mediator 중재자 한 집합에 속해있는 객체들의 상호작용을 캡슐화하여 새로운 객체로 정의 Memento 메멘토 객체가 특정 상태로 다시 되돌아올 수 있도록 내부 상태를 실체화 Observer 옵서버 객체 상태가 변할 때 관련 객체들이 그 변화를 통지받고 자동으로 갱신될 수 있게 함 State 상태 객체의 상태에 따라 동일한 동작을 다르게 처리해야할 때 사용 Strategy 전략 동일 계열의 알고리즘군을 정의하고 캡슐화하여 상호교환이 가능하도록 함 Visitor 방문자 객체의 원소에 대해 수행할 연산을 분리하여 별도의 클래스로 구성함 Template Method Pattern 템플릿 메서드 여러 클래스에서 공통으로 사용하는 메서드를 템플릿화 하여 상위 클래스에서 정의하고, 하위 클래스마다 세부 동작 사항을 다르게 구현하는 패턴
알고리즘의 유연한 교체를 가능하게 하는 패턴 비슷한 동작을 하지만 다르게 구현되어 있는 행위(전략)들을 공통의 인터페이스를 구현하는 각각의 클래스로 구현하고, 동적으로 바꿀 수 있도록 하는 패턴
장점
단점
예시
// 전략 인터페이스 (Strategy Interface)
interface Strategy {
int execute(int a, int b);
}
// 전략 구현 클래스 (Concrete Strategies)
class AddOperation implements Strategy {
public int execute(int a, int b) {
return a + b;
}
}
// 컨텍스트 클래스 (Context)
class Context {
private Strategy strategy;
// 전략 교체 메소드
public Context(Strategy strategy) {
this.strategy = strategy;
}
// 전략 실행 메소드
public int executeStrategy(int a, int b) {
return strategy.execute(a, b);
}
}
// 사용 예시
public class Main {
public static void main(String[] args) {
int a = 10, b = 5;
// 전략 설정
Strategy addStrategy = new AddOperation();
Context context = new Context(addStrategy);
// 전략 실행
int result = context.executeStrategy(a, b);
}
}
여러 클래스에서 공통으로 사용하는 메서드를 템플릿화 하여 상위 클래스에서 정의하고, 하위 클래스마다 세부 동작 사항을 다르게 구현하는 패턴
장점
단점
예시
abstract class Ramyun {
public void cook() {
System.out.println("불을 켠다.");
System.out.println("냄비에 물을 받고 끓인다.");
getRamyun();
System.out.println("스프와 면을 넣는다.");
System.out.println("알맞게 끓인다.");
}
protected abstract void getRamyun();
}
// JinRamyun.java
public class JinRamyun extends Ramyun {
@Override
protected void getRamyun() {
System.out.println("진라면을 준비한다.");
}
}
// SamyangRamyun.java
public class SamyangRamyun extends Ramyun {
@Override
protected void getRamyun() {
System.out.println("삼양라면을 준비한다.");
}
}