소프트웨어 아키텍처 패턴

김동욱·2024년 6월 3일

computer science

목록 보기
1/1
post-thumbnail

소프트웨어 아키텍처 패턴이란

소프트웨어 개발을 시작하기 전 적절한 아키텍처를 선택하는 것은 매우 중요하다. 시스템 설계 시 자주 발생하는 문제들을 해결하기 위해, 소프트웨어 아키텍처 패턴은 이러한 문제들을 체계적으로 접근할 수 있는 설계 방안을 제공한다. 아키텍처 패턴은 시스템의 구조를 정의하고, 시스템 컴포넌트들을 조직화함으로써 컴포넌트 간의 효율적인 상호작용을 보장하여 유지보수가 용이한 시스템을 설계하는 데 목적이 있다.

아키텍처 패턴은 복잡성 관리, 기술적 부채 감소, 재사용성 증가, 그리고 시스템의 확장성 및 유연성 향상을 위해 사용된다. 시스템의 설계 초기 단계에서 적절한 아키텍처 패턴을 적용함으로써, 장기적으로 보았을 때 개발 비용과 유지 관리 비용을 절감할 수 있다. 그러나 규모가 작은 프로젝트에서 복잡한 패턴을 무리하게 도입하면 오버엔지니어링으로 이어질 위험이 있으며, 특정 패턴이 프로젝트의 유연성을 제한할 수도 있다. 따라서 아키텍처 패턴을 도입하더라도 프로젝트의 규모와 요구 사항을 신중히 고려해야 하며, 적용 가능성을 면밀히 검토한 후 결정해야 한다.

주요 아키텍처 패턴

레이어드 패턴 (Layered Pattern)

레이어드 패턴은 각 계층이 독립적인 역할을 수행하며 상위 계층으로 서비스를 제공하는 구조를 가지고 있다. 이는 유지 관리와 확장성을 향상시키는 데 유용하며, 특히 복잡한 비즈니스 어플리케이션 및 웹 기반 서비스에 효과적이다.

가장 일반적인 4개의 계층은 다음과 같다.

  • 프레젠테이션 계층 (UI 계층): 사용자 인터페이스 처리
  • 애플리케이션 계층 (서비스 계층): 애플리케이션의 기능 수행
  • 비즈니스 로직 계층 (도메인 계층): 핵심 비즈니스 규칙 및 로직 처리
  • 데이터 접근 계층 (퍼시스턴스 계층): 데이터베이스 또는 기타 저장소와의 통신 관리

일반 데스크탑 애플리케이션이나 전자 상거래 웹 애플리케이션 등에서 사용되는 패턴이다.

클라이언트-서버 패턴 (Client-server pattern)

클라이언트-서버 패턴은 서버와 여러 클라이언트로 구성되며, 서버는 다수의 클라이언트에게 서비스를 제공한다. 클라이언트는 서비스를 요청하고 서버는 적절한 서비스를 제공한다. 서버는 클라이언트의 요청을 계속 듣고 응답한다. 이 패턴은 이메일, 문서 공유, 온라인 뱅킹 등 온라인 애플리케이션에 주로 사용된다. 이 구조는 실시간 데이터 처리와 분산 환경에서 효과적으로 작동하여 다양한 서비스를 제공할 수 있다.

마스터-슬레이브 패턴 (Master-slave pattern)

마스터-슬레이브 패턴은 마스터 컴포넌트슬레이브 컴포넌트로 구성된다. 이 패턴에서 마스터는 작업을 동일한 슬레이브 컴포넌트들에게 분배하고, 슬레이브들이 반환한 결과를 종합하여 최종 결과를 계산한다. 이 구조는 데이터 관리와 자원 분배에서 효율성을 제공하며, 특히 대규모 데이터 처리와 자원 관리가 중요한 시스템에서 유용하다.

주로 다음의 상황에서 사용된다.

  • 데이터베이스 복제에서, 마스터 데이터베이스는 신뢰할 수 있는 데이터 소스로 간주되며 슬레이브 데이터베이스는 마스터 데이터베이스와 동기화된다.
  • 컴퓨터 시스템에서 버스와 연결된 주변장치 (마스터 드라이버와 슬레이브 드라이버)

파이프-필터 패턴 (Pipe-filter pattern)

파이프-필터 패턴은 데이터 스트림을 생성하고 처리하는 시스템의 구조를 설계하는 데 사용된다. 각 처리 단계는 필터 컴포넌트 내에 포함되며, 처리할 데이터는 파이프를 통해 전달된다. 이 파이프는 데이터 버퍼링이나 동기화 목적으로 사용될 수 있다. 이 패턴은 시스템을 명확하고 관리 가능한 단위로 분리하여 각 단계를 독립적으로 관리하고 확장할 수 있게 한다.

주로 다음의 상황에서 사용된다.

  • 컴파일러: 연속적인 필터들이 어휘 분석, 구문 분석, 의미 분석, 코드 생성 등을 수행한다.
  • 생물정보학 워크플로우: 데이터의 전처리, 분석, 결과 생성 등의 과정이 연속적으로 진행된다.

브로커 패턴 (Broker pattern)

브로커 패턴은 분산 시스템에서 컴포넌트 간의 결합을 최소화하도록 설계된 구조이다. 이 패턴에서, 서버는 자신의 기능(서비스와 특성)을 브로커에게 등록하고, 클라이언트는 브로커를 통해 필요한 서비스를 요청한다. 브로커는 등록된 서비스 목록에서 적합한 서비스를 찾아 클라이언트에게 연결시켜 준다. 이 패턴은 Apache ActiveMQ, Apache Kafka, RabbitMQ, JBoss Messaging과 같은 메시지 브로커 소프트웨어에서 주로 사용된다. 이 구조는 컴포넌트 간의 효율적인 통신과 서비스 관리를 가능하게 한다.

피어 투 피어 패턴 (Peer-to-peer pattern)

피어-투-피어 패턴에서는 각 구성 요소가 피어로 알려져 있다. 피어는 클라이언트로서 다른 피어에게 서비스를 요청하거나 서버로서 다른 피어에게 서비스를 제공할 수 있다. 각 피어는 클라이언트, 서버 또는 둘 다의 역할을 수행할 수 있으며, 시간에 따라 동적으로 역할을 변경할 수 있다. 이 패턴은 분산된 환경에서 자원의 공유와 커뮤니케이션을 효과적으로 지원한다.

주로 다음의 상황에서 사용된다.

  • 파일 공유 네트워크: Gnutella, G2 같은 네트워크에서 사용
  • 멀티미디어 프로토콜: P2PTV, PDTP 등이 이에 해당
  • 암호화폐 기반 제품: 비트코인과 블록체인 같은 기술에 적용

이벤트-버스 패턴 (Event-bus pattern)

이벤트 버스 패턴은 이벤트 기반 커뮤니케이션을 구조화하는 데 사용되며, 주요 구성 요소로는 이벤트 소스, 이벤트 리스너, 채널, 그리고 이벤트 버스가 있다. 소스는 이벤트 버스의 특정 채널에 메시지를 발행하고, 리스너는 특정 채널을 구독한다. 리스너는 자신이 구독한 채널에 게시된 메시지를 알림 받는다.

안드로이드 개발, 알림 서비스 등에서 사용된다.

모델-뷰-컨트롤러 패턴 (Model-view-controller pattern)

MVC 패턴은 상호작용하는 애플리케이션을 모델, , 컨트롤러의 세 부분으로 나뉜다. 모델은 핵심 기능성과 데이터를 담고, 뷰는 사용자에게 정보를 표시하며, 컨트롤러는 사용자의 입력을 처리한다. 이 구조는 정보의 내부 표현과 사용자에게 제공되는 방식을 분리하여 컴포넌트의 결합을 최소화하고 코드 재사용을 용이하게 한다.

주로 다음의 상황에서 사용된다.

  • 주요 프로그래밍 언어의 웹 애플리케이션 아키텍처
  • Django, Rails와 같은 웹 프레임워크

블랙보드 패턴 (Blackboard pattern)

블랙보드 패턴은 확실한 해결 전략이 알려지지 않은 문제에 유용하다. 이 패턴은 다음의 컴포넌트로 구성된다.

  • 블랙보드 (blackboard) — 솔루션의 객체를 포함하는 구조화된 전역 메모리
  • 지식 소스 (knowledge source) — 자체 표현을 가진 특수 모듈
  • 제어 컴포넌트 (control component) — 모듈 선택, 설정 및 실행을 담당한다

모든 컴포넌트는 블랙보드에 접근할 수 있으며, 새로운 데이터 객체를 생성하거나 특정 데이터를 찾아내어 작업을 수행할 수 있다.

음성 인식, 차량 식별 및 추적, 단백질 구조 식별, 수중 음파 탐지기 신호 해석 등에서 사용된다.

인터프리터 패턴 (Interpreter pattern)

인터프리터 패턴은 특정 언어로 작성된 프로그램을 해석하기 위해 설계된 컴포넌트에 사용된다. 이 패턴은 언어의 각 기호마다 클래스를 가지며, 특정 언어로 작성된 문장이나 표현식을 평가하는 방법을 지정한다.

주로 다음의 상황에서 사용된다.

  • SQL과 같은 데이터베이스 쿼리 언어
  • 통신 프로토콜을 설명하는 언어

아키텍처 패턴 비교

각 아키텍처 패턴의 장단점을 요약한 테이블이다.

아키텍처장점단점
계층식 (Layered)하위 레이어는 다른 상위 레이어에 의해 사용된다. 레이어 표준화가 쉬우며 레이어 수준을 정의하기가 수월하다. 레이어를 변경해도 다른 레이어에는 영향을 끼치지 않는다.광범위한 적용이 어렵다. 특정 상황에서는 특정 레이어가 불필요할 수도 있다.
클라이언트-서버 (Client-server)클라이언트가 요청할 수 있는 일련의 서비스를 모델링 할 수 있다.요청은 일반적으로 서버에서 별도의 스레드로 처리된다. 프로세스간 통신은 서로 다른 클라이언트가 서로 다르게 표현되므로 오버헤드가 발생한다.
마스터-슬레이브 (Master-slave)정확성 - 서비스의 실행은 각기 다른 구현체를 가진 슬레이브들에게 전파된다.슬레이브가 독립적이므로 공유되는 상태가 없다. 실시간 시스템에서는 마스터-슬레이브간 레이턴시 문제가 발생할 수 있다. 이 패턴은 분리 가능한 문제에만 적용할 수 있다.
파이프-필터 (Pipe-filter)동시성 처리를 나타낸다. 입출력이 스트림으로 구성되고 필터가 데이터를 수신하면 연산을 수행하기 시작한다. 필터 추가가 쉽다. 시스템 확장성이 좋다. 필터는 재사용 가능하다. 주어진 필터들을 재구성하여 또 다른 파이프라인을 구축할 수 있다.가장 느린 필터 연산에 의해 효율성이 제한될 수 있다. 필터간 데이터 이동에서 데이터 변환 오버헤드가 발생한다.
브로커 (Broker)객체의 동적인 변경, 추가, 삭제 및 재할당이 가능하며 개발자에게 배포를 투명하게 만든다.서비스 표현에 대한 표준화가 필요하다.
피어 투 피어 (Peer to peer)탈중앙화된 컴퓨팅을 지원한다. 특정 노드 장애에 매우 강하다. 리소스 및 컴퓨팅 성능면에서 확장성이 뛰어나다.노드들이 자발적으로 참여하기 때문에 서비스 품질에 대한 보장이 어렵다. 보안에 대한 보장이 어렵다. 노드의 갯수에 따라 성능이 좌우된다.
이벤트-버스 (Event-bus)새로운 발행자 (publishers)와 구독자 (subscribers) 및 연결의 추가가 수월하다. 고도로 분산화된 애플리케이션에 효과적이다.모든 메시지가 동일한 이벤트 버스를 통해 전달되기 때문에 확장성 문제가 발생할 수 있다.
모델-뷰-컨트롤러 (MVC)동일한 모델에 대해 여러개의 뷰를 만들 수 있으며, 런타임에 동적으로 연결 및 해제를 할 수 있다.복잡성을 증가시키며, 사용자의 행동에 대한 불필요한 업데이트가 많이 발생할 수 있다.
블랙보드 (Blackboard)새로운 애플리케이션을 쉽게 추가할 수 있다. 데이터 공간의 구조를 쉽게 확장할 수 있다.모든 애플리케이션이 영향을 받기 때문에 데이터 공간의 구조를 변경하기가 어렵다. 동기화 및 접근 제어가 필요할 수 있다.
인터프리터 (Interpreter)매우 동적인 설계가 가능하다. 최종 사용자가 프로그래밍하기 좋다. 인터프리터 프로그램을 쉽게 교체할 수 있기 때문에 유연성이 향상된다.인터프리터 언어는 일반적으로 컴파일 언어보다 느리기 때문에 성능 문제가 발생할 수 있다.





참고 자료
https://towardsdatascience.com/10-common-software-architectural-patterns-in-a-nutshell-a0b47a1e9013

profile
안녕하세요! 질문과 피드백은 언제든지 환영입니다:)

0개의 댓글