From 87064a4a9135e3d08553d4cbd04def92abf7654a Mon Sep 17 00:00:00 2001 From: AhnHyunWoo Date: Sat, 21 Feb 2026 22:23:04 +0900 Subject: [PATCH] =?UTF-8?q?10=EC=A3=BC=EC=B0=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: bryan-ahn --- ...50\355\204\264\352\260\234\353\205\220.md" | 317 ++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 "CS/17-20weeks_DesignPatterns/10\354\243\274\354\260\250_\353\224\224\354\236\220\354\235\270\355\214\250\355\204\264\352\260\234\353\205\220.md" diff --git "a/CS/17-20weeks_DesignPatterns/10\354\243\274\354\260\250_\353\224\224\354\236\220\354\235\270\355\214\250\355\204\264\352\260\234\353\205\220.md" "b/CS/17-20weeks_DesignPatterns/10\354\243\274\354\260\250_\353\224\224\354\236\220\354\235\270\355\214\250\355\204\264\352\260\234\353\205\220.md" new file mode 100644 index 0000000..fa4009c --- /dev/null +++ "b/CS/17-20weeks_DesignPatterns/10\354\243\274\354\260\250_\353\224\224\354\236\220\354\235\270\355\214\250\355\204\264\352\260\234\353\205\220.md" @@ -0,0 +1,317 @@ +# Design Pattern (디자인 패턴) 정리 + +# 1. 디자인 패턴의 개념 +디자인 패턴은 소프트웨어 설계 과정에서 자주 발생하는 문제에 대한 전형적인 해결 방식(설계 템플릿) + +디자인 패턴은 코드 자체가 아니라 문제를 해결하는 구조와 접근 방법에 대한 정형화된 해법 + +개발자는 패턴의 개념을 이해하고, 자신의 프로그램에 맞게 구체적으로 구현해야 함 + +## 1.1 패턴 vs. 알고리즘 +- 패턴: 해결 구조를 설명하는 상위 수준의 설계 개념 +- 알고리즘: 목표 달성을 위한 구체적이고 순차적인 절차 + + +# 2. 디자인 패턴의 필요성 +- 검증된 설계 해법 +- 유지보수성 및 확장성 확보 +- 의사소통 비용 감소 (팀 내에서 패턴은 일종의 설계 메타 언어로 기능) +- 객체 지향적 설계 가능 (패턴을 통해 추상화, 캡슐화, 다형성 등 적용 가능) + + +# 3. 디자인 패턴의 분류 + +## 3.1 생성 패턴 (Creational Patterns) +기존 코드의 재활용과 유연성을 증가시키는 객체 생성 메커니즘들을 제공 +- **Singleton** +- **Factory** +- Abstract Factory +- Builder +- Prototype + +## 3.2 구조 패턴 (Structural Patterns) +구조를 유연하고 효율적으로 유지하면서 객체와 클래스를 더 큰 구조로 조합하는 방법을 설명 +- Adapter +- Decorator +- Proxy +- Composite +- Facade + +## 3.3 행위 패턴 (Behavioral Patterns) +객체 간의 효과적인 의사소통과 책임 할당을 처리 +- **Strategy** +- Observer +- Template Method +- Command +- State + + +# 4. Singleton Pattern + +``` mermaid +classDiagram + class Singleton { + - static Singleton instance + - Singleton() + + static getInstance() + } +``` + +## 4.1 개념 +클래스의 인스턴스를 하나만 생성하도록 보장하고, 전역적으로 접근 가능하게 하는 패턴 + +## 4.2 사용 목적 +- 설정 관리 객체 +- 로깅 시스템 +- 캐시 관리자 +- 공통 리소스 관리자 + +## 4.3 구현 방식 +### 1) 단순 구현 +인스턴스 생성 여부 확인 후 없으면 생성 +``` java +public class Singleton { + private static Singleton instance; + private Singleton() {} + public static Singleton getInstance() { + if (instance == null) { + instance = new Singleton(); + } + return instance; + } +} +``` +장점 +- 간단한 구현 + +단점 +- Multi-thread 환경에서 여러 인스턴스가 생성될 수 있음 + +### 2) 동기화 사용 +Synchronized를 통해 하나의 thread만 메서드 호출이 가능하도록 격리 보장 +``` java +public class Singleton { + private static Singleton instance; + private Singleton() {} + public static synchronized Singleton getInstance() { + if (instance == null) { + instance = new Singleton(); + } + return instance; + } +} +``` +장점 +- Multi-thread 환경에서도 하나의 인스턴스 생성 보장 + +단점 +- 메서드 호출마다 lock으로 인해 성능 저하 → 인스턴스 생성 여부를 synchronized 전후로 체크하여 개선 가능 + +### 3) Eager Initialization +클래스 초기화 과정에서 정적 멤버로 인스턴스 생성 +``` java +public class Singleton { + private static final Singleton instance = new Singleton(); + private Singleton() {} + public static Singleton getInstance() { + return instance; + } +} +``` +장점 +- 구현 단순 +- Thread-Safe +- 동기화 비용 없음 + +단점 +- 메서드 사용 여부와 관계없이 클래스 load 시 인스턴스 생성 → 불필요한 메모리 점유 + +### 4) Inner Static Holder +인스턴스 홀더 역할의 내부 클래스를 두어 메서드 호출 때만 인스턴스를 생성 +``` java +public class Singleton { + private Singleton() {} + private static class Holder { + private static final Singleton instance = new Singleton(); + } + public static Singleton getInstance() { + return Holder.instance; + } +} +``` +장점 +- Lazy initialization +- Thread-Safe +- 불필요한 메모리 점유 없음 + +단점 +- Java에서는 private 생성자라도 리플렉션으로 강제 호출 가능 → 여러 인스턴스 생성 + +### 5) Single-Element Enum +enum 인스턴스의 Thread-Safe한 특성을 활용 + +장점 +- 간단한 구현 +- 구현 단계에서 thread-safe를 직접 고려할 필요 없음 + +단점 +- Enum은 클래스 로딩 시점에 초기화됨 → 완전한 lazy는 아님 + + +# 5. Factory Pattern +``` mermaid +classDiagram + class Client + class Product { + <> + + use() + } + class ConcreteProductA + class ConcreteProductB + class ProductFactory { + + createProduct(type) + } + + Client --> ProductFactory + ProductFactory --> Product + Product <|.. ConcreteProductA + Product <|.. ConcreteProductB +``` + +## 5.1 개념 +객체 생성 로직을 팩토리 클래스(또는 메서드)에 위임하여 클라이언트 코드가 구체 클래스(concrete class)에 의존하지 않도록 하는 패턴 + +즉, 객체 생성 책임을 별도의 계층으로 분리하여 결합도(coupling)를 낮추고 확장성을 확보하는 것이 목적 + +## 5.2 사용 목적 +- 객체 생성 로직이 복잡한 경우 분리 +- 클라이언트 코드에서 new 키워드 제거 +- OCP(Open-Closed Principle) 준수 +- 구체 클래스 의존성 제거 +- 객체 생성 정책 변경 시 클라이언트 수정 최소화 + +## 5.3 예시 코드 +``` java +interface Product { + void use(); +} + +class ConcreteProductA implements Product { + public void use() { + System.out.println("Product A 실행"); + } +} + +class ConcreteProductB implements Product { + public void use() { + System.out.println("Product B 실행"); + } +} + +class ProductFactory { + public static Product createProduct(String type) { + if (type.equals("A")) { + return new ConcreteProductA(); + } else if (type.equals("B")) { + return new ConcreteProductB(); + } + throw new IllegalArgumentException("Unknown type"); + } +} +``` +장점 +- 객체 생성 책임을 분리 → 클라이언트는 구체 클래스에 의존하지 않음 +- OCP (객체 지향) 준수 → 기존 코드 수정 없이 확장 가능 +- 클라이언트는 인터페이스에만 의존도가 있음 + +단점 +- Product마다 클래스 존재 → 많은 클래스로 인한 구조 복잡도 상승 +- 단순히 new를 사용하면 되는 상황에서 불필요한 추상화가 될 수 있음 (over-engineering) + +# 6. Strategy Pattern (전략 패턴) + +``` mermaid +classDiagram + class Context { + - Strategy strategy + + setStrategy(Strategy) + + run() + } + + class Strategy { + <> + + execute() + } + + class ConcreteStrategyA + class ConcreteStrategyB + + Context --> Strategy + Strategy <|.. ConcreteStrategyA + Strategy <|.. ConcreteStrategyB +``` + +## 6.1 개념 +객체가 할 수 있는 행위들 각각을 전략 (캡슐화한 알고리즘)으로 만들어 놓고, 동적으로 행위의 수정이 필요한 경우 전략을 바꾸는 것만으로 행위의 수정이 가능하도록 만든 패턴 + +즉, 실행 중에 알고리즘을 선택할 수 있음 + +## 6.2 전략 패턴의 구조 +### 6.2.1 전략 인터페이스(Strategy Interface) +알고리즘을 캡슐화하는 인터페이스 + +다양한 알고리즘 클래스가 이 인터페이스를 구현하여 특정 작업을 수행 + +### 6.2.2 구체적인 전략 클래스(Concrete Strategy Classes) +전략 인터페이스를 구현하여 실제 알고리즘을 정의하는 클래스 + +서로 다른 알고리즘을 구현하며, 요청에 따라 교체 가능 + +### 6.2.3 컨텍스트 클래스(Context Class) +전략 인터페이스를 통해 알고리즘을 사용하는 클래스 + +클라이언트가 선택한 전략을 사용하여 작업을 수행 + +## 6.2 예시 코드 +``` java +interface Strategy { + void execute(); +} + +class ConcreteStrategyA implements Strategy { + public void execute() { + System.out.println("전략 A 실행"); + } +} + +class ConcreteStrategyB implements Strategy { + public void execute() { + System.out.println("전략 B 실행"); + } +} + +class Context { + private Strategy strategy; + public void setStrategy(Strategy strategy) { + this.strategy = strategy; + } + public void run() { + strategy.execute(); + } +} +``` +장점 +- 알고리즘을 쉽게 변경 및 대체할 수 있으므로 유연함 +- 알고리즘을 캡슐화로 인해 코드 재사용성이 좋음 → 높은 확장성 +- 각각 알고리즘을 독립적으로 테스트 가능 + +단점 +- 전략이 많아질수록 클래스 폭증 → 관리 비용 증가 +- 단순한 if나 switch로 끝날 로직도 인터페이스 + 구현체 + Context 구조로 분리됨 (over-engineering) +- 전략이 자주 교체되면 객체 생성 비용이 발생 + +# 정리 +- Singleton: 단일 인스턴스 보장 +- Factory: 객체 생성 책임 분리 +- Strategy: 알고리즘 교체 가능 구조 +