개발을 하며 디자인 패턴과 아키텍처 패턴에 대한 다양한 정보를 접하고 적용한다. 어쩌면 습관처럼 사용해왔을지도 모르는 이러한 패턴들을 전체적으로 정리하고, 주요 패턴의 적용 사례를 살펴보자.

Patterns


패턴이란 디자인 패턴, 아키텍쳐 패턴 등 여러가지로 구분된다.

자주 접하는 것은 디자인 패턴과 아키텍처 패턴이지만 이외에도 여러 가지 패턴이 존재한다. 대표적으로 아래와 같은 패턴들이 있다.

1. 디자인 패턴 (Design Patterns)

코드 레벨에서 객체 간의 관계를 설계하는 패턴이다.
생성 패턴, 구조 패턴, 행위 패턴으로 분류된다.

예시: 싱글톤, 팩토리, 퍼사드, 옵저버 패턴 등

2. 아키텍처 패턴 (Architectural Patterns)

시스템 전체의 구조를 설계하는 패턴이다.
→ 애플리케이션의 확장성과 유지보수성을 고려한다.

예시: MVC, MVVM, 마이크로서비스, 계층형 아키텍처 등

3. 동시성 패턴 (Concurrency Patterns)

멀티스레드 및 비동기 처리를 효율적으로 설계하는 패턴이다.
→ 병렬 처리 및 동기화 문제를 해결한다.

예시:

  • 락 패턴 (Lock Pattern): 공유 리소스에 대한 동시 접근을 제어한다.
  • 생산자-소비자 패턴 (Producer-Consumer Pattern): 데이터를 생산하는 역할과 소비하는 역할을 분리하여 동기화한다.
  • 이벤트 루프 패턴 (Event Loop Pattern): 비동기 이벤트를 처리하는 구조로, Node.js에서 활용된다.
  • Actor Model: 객체 간 메시지 기반으로 상태를 관리하는 방식으로, Erlang, Akka에서 사용된다.

4. 분산 패턴 (Distributed Patterns)

여러 개의 시스템이 네트워크를 통해 협력할 때 사용하는 패턴이다.
→ 분산 시스템에서 성능과 확장성을 높이는 역할을 한다.

예시:

  • Saga 패턴: 마이크로서비스 간의 트랜잭션을 보장하는 패턴
  • CQRS (Command Query Responsibility Segregation): 읽기와 쓰기를 분리하여 성능을 최적화하는 패턴
  • Circuit Breaker 패턴: 장애 발생 시 서비스를 보호하는 패턴

5. 데이터 패턴 (Data Patterns)

데이터베이스와의 상호작용을 최적화하는 패턴이다.

예시:

  • Active Record: 객체가 데이터베이스 테이블과 직접 매핑되는 패턴 (ORM에서 사용)
  • Repository Pattern: 데이터베이스 접근을 추상화하여 비즈니스 로직과 분리
  • Unit of Work: 여러 개의 데이터 변경 작업을 하나의 트랜잭션으로 묶는 패턴

6. 보안 패턴 (Security Patterns)

애플리케이션 보안을 강화하는 패턴이다.

예시:

  • Authentication Gateway: 모든 요청을 인증하는 게이트웨이를 두는 패턴
  • Role-Based Access Control (RBAC): 역할 기반으로 접근을 제어하는 패턴
  • Secure Session Management: 세션을 안전하게 관리하는 패턴

7. 테스트 패턴 (Testing Patterns)

코드를 효과적으로 테스트하는 방법을 제공하는 패턴이다.

예시:

  • Arrange-Act-Assert (AAA): 테스트를 준비(Arrange)하고 실행(Act)한 후 결과를 검증(Assert)하는 방식
  • Mock Object Pattern: 실제 객체 대신 가짜(Mock) 객체를 사용하여 테스트하는 패턴
  • Given-When-Then: BDD(행동 주도 개발)에서 사용되는 테스트 패턴


디자인 패턴 (Design Patterns)


1. 생성 패턴 (Creational Patterns)

  1. 싱글톤 패턴 (Singleton Pattern)
    객체의 인스턴스를 하나만 생성하도록 보장하는 패턴이다. 전역 상태를 유지해야 하는 경우에 유용하다.

  2. 팩토리 메서드 패턴 (Factory Method Pattern)
    객체 생성의 책임을 서브클래스로 위임하는 패턴이다. 구체적인 클래스를 지정하지 않고도 객체를 생성할 수 있도록 한다.

  3. 추상 팩토리 패턴 (Abstract Factory Pattern)
    관련 객체의 집합을 생성할 수 있도록 하는 패턴이다. 구체적인 클래스를 지정하지 않고 인터페이스만으로 객체를 생성할 수 있다.

  4. 빌더 패턴 (Builder Pattern)
    복잡한 객체의 생성 과정을 단순화하는 패턴이다. 단계별로 객체를 생성하고 조합할 수 있도록 한다.

  5. 프로토타입 패턴 (Prototype Pattern)
    기존 객체를 복사하여 새로운 객체를 생성하는 패턴이다. 생성 비용이 높은 객체를 효율적으로 생성할 수 있다.

2. 구조 패턴 (Structural Patterns)

  1. 어댑터 패턴 (Adapter Pattern)
    인터페이스가 서로 다른 클래스들이 함께 동작할 수 있도록 변환하는 패턴이다. 기존 클래스를 변경하지 않고도 호환성을 유지할 수 있다.

  2. 브리지 패턴 (Bridge Pattern)
    구현과 추상화를 분리하여 독립적으로 확장할 수 있도록 하는 패턴이다. 다형성을 활용하여 결합도를 낮출 수 있다.

  3. 컴포지트 패턴 (Composite Pattern)
    객체들을 트리 구조로 구성하여 계층적으로 관리할 수 있도록 하는 패턴이다. 개별 객체와 복합 객체를 동일하게 다룰 수 있다.

  4. 데코레이터 패턴 (Decorator Pattern)
    객체에 동적으로 새로운 기능을 추가할 수 있도록 하는 패턴이다. 서브클래싱 없이 기능을 확장할 수 있다.

  5. 퍼사드 패턴 (Facade Pattern)
    복잡한 서브시스템을 단순화하여 사용할 수 있도록 하는 패턴이다. 클라이언트가 여러 클래스에 직접 접근하는 대신 단일 진입점을 제공한다.

  6. 플라이웨이트 패턴 (Flyweight Pattern)
    공유 가능한 객체를 활용하여 메모리 사용량을 줄이는 패턴이다. 동일한 객체를 여러 개 생성하지 않고 재사용할 수 있도록 한다.

  7. 프록시 패턴 (Proxy Pattern)
    대리 객체를 사용하여 원본 객체에 대한 접근을 제어하는 패턴이다. 접근 제어, 로깅, 지연 초기화 등에 활용할 수 있다.

3. 행위 패턴 (Behavioral Patterns)

  1. 책임 연쇄 패턴 (Chain of Responsibility Pattern)
    여러 개의 처리 객체를 연결하여 요청을 순차적으로 처리할 수 있도록 하는 패턴이다. 특정 객체가 요청을 처리할지 여부를 결정할 수 있다.

  2. 커맨드 패턴 (Command Pattern)
    요청을 객체로 캡슐화하여 실행, 취소, 기록 등의 기능을 제공하는 패턴이다. 요청과 실행을 분리할 수 있다.

  3. 인터프리터 패턴 (Interpreter Pattern)
    문법을 해석하고 실행하는 패턴이다. 특정 언어의 문법을 정의하고 해석하는 데 사용된다.

  4. 이터레이터 패턴 (Iterator Pattern)
    컬렉션 요소를 순차적으로 탐색할 수 있도록 하는 패턴이다. 내부 구현을 노출하지 않고도 순회할 수 있도록 한다.

  5. 미디에이터 패턴 (Mediator Pattern)
    객체 간의 직접적인 상호작용을 방지하고 중앙에서 통제할 수 있도록 하는 패턴이다. 객체 간의 결합도를 낮출 수 있다.

  6. 메멘토 패턴 (Memento Pattern)
    객체의 상태를 저장하고 복원할 수 있도록 하는 패턴이다. 되돌리기(Undo) 기능을 구현하는 데 유용하다.

  7. 옵저버 패턴 (Observer Pattern)
    한 객체의 상태 변경을 여러 객체가 감지하고 반응할 수 있도록 하는 패턴이다. 이벤트 기반 시스템에서 자주 사용된다.

  8. 상태 패턴 (State Pattern)
    객체의 상태에 따라 행동이 변하도록 하는 패턴이다. 상태 전환을 캡슐화하여 코드의 복잡성을 줄일 수 있다.

  9. 전략 패턴 (Strategy Pattern)
    동작을 캡슐화하여 런타임에 알고리즘을 변경할 수 있도록 하는 패턴이다. 다양한 방식의 동작을 유연하게 선택할 수 있다.

  10. 템플릿 메서드 패턴 (Template Method Pattern)
    알고리즘의 구조를 정의하고 일부 단계는 서브클래스에서 구현하도록 하는 패턴이다. 코드의 중복을 줄이고 일관성을 유지할 수 있다.

  11. 방문자 패턴 (Visitor Pattern)
    객체 구조를 변경하지 않고도 새로운 기능을 추가할 수 있도록 하는 패턴이다. 기존 클래스의 수정 없이 동작을 확장할 수 있다.


아키텍처 패턴 (Architectural Patterns)


디자인 패턴은 특정 문제를 해결하는 코드 수준의 패턴이라면,
아키텍처 패턴은 시스템 전체의 구조와 상호작용을 정의하는 패턴이다.

1. MVC (Model-View-Controller)

  • 애플리케이션을 Model(데이터), View(화면), Controller(로직)으로 분리하는 패턴이다.
  • UI와 비즈니스 로직을 분리하여 유지보수성과 확장성을 높일 수 있다.
  • 대표적인 웹 프레임워크(Spring MVC, Django, ASP.NET)에서 사용된다.

2. MVVM (Model-View-ViewModel)

  • MVC에서 Controller 대신 ViewModel을 사용하는 패턴이다.
  • 데이터 바인딩을 활용하여 UI와 비즈니스 로직을 더욱 느슨하게 결합할 수 있다.
  • 프론트엔드 라이브러리(Vue, React + MobX)에서 사용된다.

3. MVP (Model-View-Presenter)

  • MVC의 변형으로, View와 Model 사이에서 Presenter가 모든 로직을 처리하는 패턴이다.
  • View는 단순히 UI만 담당하고, Presenter가 UI와 데이터를 연결하는 역할을 한다.
  • Android 개발에서 많이 사용되었다.

4. Layered Architecture (계층형 아키텍처)

  • 애플리케이션을 여러 계층으로 분리하여 각 계층이 독립적으로 동작하도록 하는 패턴이다.
  • 일반적으로 프레젠테이션(Presentation), 비즈니스(Business), 데이터(Data) 계층으로 나눈다.
  • 대규모 엔터프라이즈 애플리케이션(Spring Boot, .NET)에서 자주 사용된다.

5. Microservices Architecture (마이크로서비스 아키텍처)

  • 애플리케이션을 여러 개의 작은 독립 서비스로 나누어 개발하는 패턴이다.
  • 서비스 간 독립성을 유지하여 확장성과 유지보수성을 높일 수 있다.
  • 클라우드 환경, 컨테이너 기반 시스템(Kubernetes, Docker)에서 주로 사용된다.