본문 바로가기

개발기술/설계|소프트웨어패턴

소프트웨어 패턴 개념과 분류

필요성  (나무위키)

일반 프로그래머가 만나는 문제가 지구상에서 유일한 문제일 확률은 거의 없다. 이미 수많은 사람들이 부딪힌 문제다. 따라서 전문가들이 기존에 해결책을 다 마련해 놓았다. 소프트웨어 디자인 패턴 또는 디자인 패턴 소프트웨어 설계에서 흔히 발생하는 문제에 대한 일반적이고 재사용이 가능한 해결책이다

 

  여러 사람이 협업해서 개발할 때 다른 사람이 작성한 코드, 기존에 존재하는 코드를 이해하는 것은 어렵다. 이런 코드를 수정하거나 새로운 기능을 추가해야 하는데 의도치 않은 결과나 버그를 발생시키기 쉽고 성능을 최적화하기도 어렵다. 이로 인해 시간과 예산이 소모된다.

  디자인 패턴은 의사소통 수단의 일종으로서 이런 문제를 해결해 준다. 예를 들어 문제 해결의 제안에 있어서도 “기능마다 별도의 클래스를 만들고, 그 기능들로 해야 할 일을 한 번에 처리해 주는 클래스를 만들자.”라고 제안하는 것보다 "Facade 패턴을 써보자."라고 제안하는 쪽이 이해하기 쉽다.

 

 

코어 패턴 (필수)

  • 범위: 클래스/객체 수준
  • 관심사: 코드 재사용성, 유지보수성, 객체 간 관계
  • 목적: 반복되는 설계 문제에 대한 검증된 해결책 제공
  • 결정 요소: 객체 생성 방법, 구조 조합, 행위 위임

 

GoF 디자인 패턴 (객체 설계)
├── 자주 쓰이는 5개부터
│   ├── Singleton (설정, DB 연결)
│   ├── Factory (객체 생성)
│   ├── Observer (이벤트)
│   ├── Strategy (알고리즘 교체)
│   └── Decorator (기능 확장)

 

 

 


싱글톤패턴

하나의 인스턴스만 사용되는 경우. 하나의 인스턴스가 사용되지 않는 경우에는 인스턴스의 멤버변수에 저장/입력된 값들이 다른 인스턴스에 공유되지 않는다.  이로인해서 예상한 데이터를 찾을 수 없어서 문제가 발생하기도 함.

빌더패턴

  • 장점1 : Setter대신 빌더패턴을 사용하면, 한번 생성된 instance의 값은 변경되지 못하게 하여 thread safe를 확보할 수 있음
  • 장점2 : 순차적으로 field를 하나씩 설정할 수 있어서 readbility가 증진됨. 필요한 데이터만 설정할 수 있어서 유연성이 증가됨
  • 장점3 : 필요한 데이터만 설정할 수 있어서 유연성이 증가됨

스태틱팩토리패턴

 

 

프록시패턴

프록시 패턴의 핵심은 바로 인터페이스의 동일성을 유지함으로써, 클라이언트가 실제로 대리 객체를 사용하고 있는지, 아니면 실제 객체를 사용하고 있는지 신경 쓸 필요가 없도록 만드는 데 있습니다.  서버는 대리객체를 통해서 원래 객체를 호출하고 추가적인 로직을 실행한다.

프록시의 장점은 원래 실제 객체에 기능을 추가하거나 변경하지 않고도, 그 객체에 대한 접근 방식이나 동작을 확장할 수 있게 만드는 것입니다.

 

  • 접근 제어: 프록시는 원래 객체에 대한 접근을 제어할 수 있습니다. 예를 들어, 특정 조건에서만 실제 객체에 접근하도록 하거나, 접근 전에 인증 및 권한 검사를 수행할 수 있습니다.
  • 기능 확장: 프록시는 원래 객체의 메서드를 호출하면서 추가적인 기능(예: 로깅, 트랜잭션 관리, 성능 모니터링 등)을 수행할 수 있습니다.
  • 지연 초기화(Lazy Initialization): 프록시를 사용하면 실제 객체를 필요한 시점까지 생성하지 않고 미뤄둘 수 있습니다.

퍼사드 패턴 (Facade Pattern)

퍼사드 패턴은 시스템의 복잡성을 숨기고 단순한 인터페이스를 제공하여 클라이언트가 시스템과 상호작용하기 쉽게 만드는 데 사용됩니다. 여러 개의 복잡한 서브시스템이나 서비스가 존재할 때, 퍼사드는 그 모든 기능을 감싸서 하나의 간단한 인터페이스를 제공합니다.

  • 예를 들어, 어떤 소프트웨어 시스템이 여러 개의 모듈(결제 모듈, 사용자 관리 모듈, 알림 모듈 등)을 포함하고 있다면, 퍼사드는 이러한 모듈들의 복잡한 API를 숨기고, 하나의 단순한 메서드 호출로 모든 작업을 수행할 수 있게 만들어줍니다.
  • 이를 통해 클라이언트는 내부 시스템의 복잡한 구성 요소를 알 필요 없이 단순히 퍼사드를 호출하여 작업을 완료할 수 있습니다.

퍼사드 패턴의 장점 사용의 용이성 내부 구현의 캡슐화입니다. 클라이언트는 시스템의 복잡한 내부 구현을 알 필요 없이 간단한 인터페이스만 사용하여 기능을 이용할 수 있습니다.

 

 

 

 

 

아키텍처 패턴 (구조)

  • 범위: 클래스 이상의 구조 (모듈, 컴포넌트, 계층, 서비스 등)
  • 관심사: 큰 단위 컴포넌트들의 조직화, 책임 분리, 상호작용 방식
  • 목적: 시스템의 구조적 품질 달성 (확장성, 유지보수성, 테스트용이성, 성능)
  • 결정 요소: 컴포넌트 분할 기준, 의존성 방향, 통신 방식, 데이터 흐름

 

시스템 레벨 (여러 서비스 간 구조)

├── Microservices (서비스 분산)
├── Monolithic (단일 배포 단위)
├── SOA (Service-Oriented Architecture)
└── Event-Driven Architecture (이벤트 기반)

애플리케이션 레벨 (단일 앱 내부 구조)

├── Clean Architecture (의존성 방향 제어)
├── Hexagonal Architecture (포트-어댑터)
├── Layered Architecture (계층 분리)
└── Onion Architecture (도메인 중심)

컴포넌트/모듈 레벨 (UI 및 모듈 구조)

├── MVC (Model-View-Controller)
├── MVP (Model-View-Presenter)
├── MVVM (Model-View-ViewModel)
└── Component-Based (컴포넌트 기반)

 

특수 목적 패턴

  • 범위 : 그외 기타

동시성/병렬처리
├── Producer-Consumer (생산자-소비자)
├── Actor Model (액터 기반)
├── Thread Pool (스레드 풀)
└── Lock-Free (무잠금)

데이터/영속성
├── Repository (데이터 접근 추상화)
├── DAO (Data Access Object)
├── CQRS (명령-조회 분리)
├── Event Sourcing (이벤트 저장)
└── Unit of Work (작업 단위)

통합/연동
├── Message Queue (메시지 큐)
├── API Gateway (API 관문)
├── Saga (분산 트랜잭션)
└── Adapter (시스템 연결)

운영/배포
├── Blue-Green Deployment
├── Canary Deployment  
├── Circuit Breaker (장애 차단)
├── Bulkhead (격벽)
└── Retry Pattern (재시도)

웹/프론트엔드
├── Module Pattern (모듈화)
├── Publish-Subscribe (발행-구독)
├── Flux/Redux (상태 관리)
└── Component Pattern (컴포넌트)

 

..... 등