1. 소프트웨어 설계 - 애플리케이션 설계(소프트웨어 아키텍처 ~ 객체지향 분석 및 설계)

21. 소프트웨어 아키텍처

: 소프트웨어의 골격이 되는 기본 구조. 소프트웨어의 구성 요소들 간의 관계를 표현하는 시스템의 구조

  • 소프트웨어 개발 시 적용되는 원칙과 지침이자 이해 관계자들의 의사소통 도구
  • 어플리케이션을 분할하는 모듈과 그 기능, 모듈 간 인터페이스를 결정
  • 소프트웨어 아키텍처 설계는 좋은 품질을 유지하면서 비기능적 요구사항으로 인한 제약을 반영하고, 기능적 요구사항의 구현 방법을 찾는 과정

 

※ 소프트웨어 설계 단계

  상위 설계 하위 설계
별칭 아키텍처 설계, 예비 설계 모듈 설계, 상세 설계
설계 대상 시스템의 전체적 구조 시스템 내부 구조 및 행위
세부 목록 구조, 데이터베이스, 인터페이스 컴포넌트, 자료 구조, 알고리즘 etc.

 

1) 소프트웨어 아키텍처 설계의 기본 원리

1. 모듈화 (Modularity)

: 시스템의 기능을 모듈 단위로 나누는 것

  • 소프트웨어의 성능 향상 가능
  • 시스템의 수정과 재사용, 유지보수가 용이해짐

 

2. 추상화 (Abstraction)

: 문제를 전체적, 포괄적 개념부터 설계한 후, 차례로 세분화하여 구체화해 나가는 방식

  • 최소 비용으로 상황 대체가 가능
  • 시스템 구조 및 구성 파악에 대한 대략적 파악이 가능
  • 추상화의 유형
    • 과정 추상화 : 자세한 수행 과정 정의 없이 전반적 흐름만 파악
    • 데이터 추상화 : 데이터의 세부적 속성 및 용도 정의 없이 대표적 표현으로 대체
    • 제어 추상화 : 정확한 절차나 방법 정의 없이 대표적 표현으로 대체

3. 단계적 분해 (Stepwise Refinement) by Niklaus Wirth

: 문제를 상위 중요 개념부터 하위 개념으로 구체화 시키는 하향식 설계 전략

  • 추상화를 반복하여 세분화
  • 상위 개념인 소프트웨어 기능부터 시작하여 점차적으로 구체화
  • 알고리즘이나 자료 구조 등의 상세 개념은 뒤로 미루어 진행

 

4. 정보 은닉 (Information Hiding)

: 한 모듈 내부의 절차와 자료들은 정보가 감추어져 다른 모듈의 접근과 변경이 불가능함

  • 모듈 간 커뮤니케이션 시에는 필요한 정보만 인터페이스를 통해 주고 받음
  • 모듈의 독립성을 증가시켜 모듈의 수정, 시험, 유지보수가 용이함

 

2) 소프트웨어 아키텍처의 품질 속성

: 소프트웨어 아키텍처의 품질 평가 요소들을 시스템 측면, 비즈니스 측면, 아키텍처 측면으로 구분하여 구체화한 것.

 

1. 시스템 측면

  • 성능
  • 보안
  • 가용성
  • 기능성
  • 사용성
  • 변경 용이성
  • 확장성
  • 테스트 용이성, 배치성, 안정성 etc.

 

2. 비즈니스 측면

  • 시장 용이성 : 정해진 시간에 맞춰 프로그램을 출시하는 것
  • 비용과 혜택 : 개발 비용과 유연성 사이의 균형 유지
  • 예상 시스템 수명 : 시스템의 수명에 따라 변경 용이성과 확장성 또한 고려
  • 목표 시장, 공개 일정, 기존 시스템과의 통합 etc.

 

3. 아키텍처 측면

  • 개념적 무결성 : 전체 시스템과 구성 요소들 사이의 일관성
  • 정확성/완결성 : 요구사항과 제약사항을 모두 충족
  • 구축 가능성 : 모듈을 적절히 분배하여 유연한 일정 변경을 가능케 함
  • 변경성, 시험성, 적응성, 일치성, 대체성 etc.

 

3) 소프트웨어 아키텍처 설계 과정

1. 설계 목표 설정 

: 요구사항을 분석하여 전체 시스템의 설계 목표 설정

 

2. 시스템 타입 결정

: 시스템 및 서브 시스템의 타입 결정. 설계 목표를 고려하여 아키텍처 패턴 선택

 

3. 아키텍처 패턴 적용

: 아키텍처 패턴을 참고하여 시스템의 표준 아키텍처 설계

 

4. 서브시스템 구체화

: 서브시스템의 기능과 서브시스템간 동작 및 인터페이스 정의

 

5. 검토

: 설계 목표, 요구사항, 기본 원리 등에 비추어 설계된 아키텍처 검토

 

※ 시스템 타입

  • 대화형 시스템 : 사용자의 요구에 따라 처리하고 반응하는 시스템 ex) 쇼핑몰 등의 웹 애플리케이션
  • 이벤트 중심 시스템 : 외부의 상태 변화에 따라 반응하는 시스템 ex) 비상벨 등의 내장 소프트웨어
  • 변환형 시스템 : 입력된 데이터에 대해 정해진 작업을 수행하고 결과를 출력하는 시스템 ex) 컴파일러
  • 객체 영속형 시스템 : 데이터베이스를 통해 파일을 저장, 검색, 갱신하는 시스템 ex) 서버 관리 시스템

 

※ 협약에 의한 설계

: 컴포넌트 설계 시 클래스에 대한 여러 가정을 명세한 것

  • 선행조건 (Precondition) : 오퍼레이션이 호출되기 전에 참이 되어야 하는 조건
  • 결과조건 (Postcondition) : 오펴레이션이 수행된 후 만족되어야 하는 조건
  • 불변조건 (Invariant) : 오퍼레이션 수행 동안 항상 만족되어야 하는 조건

22. 아키텍처 패턴

: 아키텍처 설계 시 참조 가능한 전형적인 해결 방식이나 예제 (아키텍처 스타일, 표준 아키텍처)

  • 시스템의 구조 구성을 위한 기본적 윤곽 제시
  • 시스템을 구성하는 서브시스템들과 그 역할을 정의하고, 서브시스템 간 관계와 규칙 등을 포함
  • 장점
    • 개발 시간 단축 및 안정적 개발 가능
    • 이해 관계자들 간 의사소통이 용이해짐
    • 구조 이해가 쉬워 개발에 참여하지 않은 사람도 유지보수가 가능
    • 개발 전에 시스템의 특성을 예측할 수 있도록 함

 

1) 레이어 패턴 (Layers Pattern)

: 시스템을 계층으로 구분하여 구성하는 방식

대표적 레이어 패턴인 OSI 7 계층 모델. 네트워크에 이용된다.

  • 각각의 서브시스템들이 계층 구조를 이루며, 상위 계층은 하위 계층에 대한 서비스 제공자(Server)가, 하위 계층은 클라이언트(Client)가 된다.
  • 서로 접한 두 레이어 사이에서만 상호작용이 이루어짐 -> 변경 작업이 용이
  • 특정 계층만을 교쳬해 시스템을 개선하는 것이 가능
  • ex) OSI 참조 모델

 

2) 클라이언트-서버 패턴 (Client-Server Pattern)

: 하나의 서버 컴포넌트와 다수의 클라이언트 컴포넌트로 구성 (1:N 방식)

클라이언트-서버 패턴의 예시. 웹 브라우저와 웹 서버 간의 통신.

  • 사용자는 클라이언트와만 의사소통함
  • 사용자가 클라이언트를 통해 서버에 서비스를 요청하면 서버가 클라이언트에 응답하여 서비스를 제공
  • 클라이언트와 서버는 요청/응답을 위한 동기화를 제외하고는 독립적이다.
  • 서버는 요청에 응답하기 위해 항상 대기 상태를 유지한다.

 

3) 파이트-필터 패턴 (Pipe-Filter Pattern)

: 데이터 스트림 절차의 각 단계를 필터 컴포넌트로 캡슐화하여 파이프를 통해 데이터를 전송하는 패턴

파이프-필터 패턴을 이용하는 유닉스의 Shell

  • 필터 컴포넌트는 재사용성이 좋고 확장이 용이함
  • 필터 컴포넌트들을 재배치하여 다양한 파이프라인 구축이 가능
  • 필터 간 데이터 이동 시 변환으로 인한 오버헤드 발생 가능
  • ex) 데이터 변환, 버퍼링, 동기화, Unix shell

 

4) 모델-뷰-컨트롤러 패턴 (Model-View-Controller Pattern, MVC Pattern)

: 서브시스템을 모델, 뷰, 컨트롤러의 세 부분으로 구조화하는 패턴

MVC 패턴을 이용한 웹 서버와 브라우저 사이의 통신

  • 모델 : 서브시스템의 핵심 기능과 데이터 보관
  • 뷰 : 사용자와 직접 상호작용하는 부분, 사용자에게 정보 표시
  • 컨트롤러 : 모델과 뷰 제어, 사용자의 입력 처리
  • 모델, 뷰, 컨트롤러는 분리되어 있으며 서로 영향을 받지 않음
  • 한 개의 모델에 대해 여러가지의 뷰를 필요로 하는 대화형 어플리케이션에 적합

 

5) 마스터-슬레이브 패턴 (Master-Slave Pattern)

: 마스터 컴포넌트를 동일한 구조의 슬레이브 컴포넌트로 작업을 분할하고 슬레이브 컴포넌트에서 처리한 결과물을 마스터가 돌려받는 방식

마스터-슬레이브 패턴의 작동 방식

  • 마스터 컴포넌트 : 모든 작업의 주체
  • 슬레이브 컴포넌트 : 마스터 컴포넌트의 자에 하에 작업 수행 및 결과 반환
  • Controller-Agent Pattern, Primary-Secondary Pattern 등으로도 불림
  • 장애 허용 시스템, 병렬 컴퓨팅 시스템에서 주로 활용

 

6) 브로커 패턴 (Broker Pattern)

: 사용자가 원하는 서비스를 브로커 컴포넌트에 요청하면 브로커 컴포넌트가 요청에 맞는 컴포넌트를 찾아 사용자와 연결해주는 구조

브로커 패턴의 기본 구조

  • 원격 서비스 호출에 응답하는 컴포넌트들이 여러 개가 있을때 적합
  • 분산 환경 시스템에 주로 활용

 

7) 피어투피어 패턴 (Peer-to-Peer Pattern, P2P Pattern)

: 피어를 하나의 컴포넌트로 간주하고, 각 피어들이 클라이언트 또는 서버가 되어 연결될 수 있는 구조

피어투피어 패턴의 구조 예시

  • 피어투피어 패턴에서 클라이언트와 서버는 전형적인 멀티스레딩 방식을 사용

 

8) 이벤트-버스 패턴 (Event-Bus Pattern)

: 소스가 특정 채널에 이벤트 메시지를 발행하면, 해당 채널을 구독한 리스너들이 메시지를 받아 이벤트를 처리하는 방식

이벤트-버스 패턴의 구조 예시

  • 이벤트-버스 패턴의 네 가지 주요 컴포넌트
    • 이벤트를 생성하는 소스
    • 이벤트를 처리하는 리스너
    • 이벤트의 이동 통로인 채널
    • 채널들을 관리하는 버스

 

9) 블랙보드 패턴 (Blackboard Pattern)

: 모든 컴포넌트들이 공유 데이터 저장소와 블랙보드 컴포넌트에 접근하여 검색을 통해 원하는 데이터를 찾을 수 있는 구조

블랙보드 패턴의 구조 예시

  • 해결책이 명확하지 않는 문제를 처리하는데 유용
  • 음싱인식, 차량 식별, 신호 해석 등에 주로 활용

 

10) 인터프리터 패턴 (Interpreter Pattern)

: 프로그램 코드의 각 라인을 수행하는 방법을 지정하고, 기호마다 클래스를 가지는 구성

인터프리터 패턴의 클래스 다이어그램 예시

  • 특정 언어로 작성된 프로그램의 코드를 해석하는 컴포넌트 설계에 이용

23. 객체지향 (Object-Oriented)

: 현실 세계의 여러 개쳬(Entity)를 객체(Object)로 만들고 이들을 조립하여 소프트웨어를 설계하는 기법

현실 세계의 개체인 자동차를 객체화 하는 예시

  • 소프트웨어의 재사용 및 확장이 용이
  • 고품질의 소프트웨어를 빠르게 개발할 수 있고 유지보수가 용이함
  • 복잡한 구조를 단계적, 계층적으로 표현
  • 멀티미디어 데이터 및 병렬 처리를 지원
  • 사용자와 개발자 모두 쉽게 이해 가능

 

1) 객체 (Object)

: 객체의 정보인 데이터와 데이터를 처리하는 함수를 캡슐화한 하나의 소프트웨어 모듈

  • 데이터 : 객체의 속성이나 상태 등을 나타내는 정보. (속성, 애트리뷰트, 상태, 변수, 상수, 자료 구조)
  • 함수 : 객체가 데이터를 이용해 처리하는 기능. (메소드, 행위, 서비스, 동작, 연산)
  • 객체의 특성
    • 객체는 독립적으로 식별 가능한 이름을 가진다
    • 객체는 시간에 따라 변하는 조건인 상태를 가진다
    • 여러 객체들은 상호 연관성에 의해 관계가 형성된다.
    • 객체가 반응할 수 있는 메시지의 집합을 행위라고 하며, 객체는 행위의 특징을 나타낸다
    • 객체는 일정한 기억장소를 가진다
    • 객체는 다른 객체로부터 메시지를 받아서 정해진 기능을 수행한다.

 

2) 클래스 (Class)

: 공통된 데이터와 함수를 갖는 객체의 집합. 객체의 타입

  • 객체들의 속성과 메소드를 정의하는 틀이자, 객체지향 프로그램에서 데이터를 추상화하는 단위
  • 클래스에 의해 생성되는 각 객체를 인스턴스(Instance)라 함
  • 한 클래스의 각 인스턴스들은 같은 속성과 메소드를 가지지만, 그 속성에 대한 정보가 다름
  • 슈퍼클래스/서브클래스
    • 슈퍼클래스 (Superclass) : 특정 클래스의 상위에 존재하는 클래스. 부모 클래스
    • 서브클래스 (Subclass) : 특정 클래스의 하위에 존재하는 클래스. 자식 클래스
    • 최상위 클래스 : 위에 슈퍼클래스가 존재하지 않는 가장 상위의 클래스

 

3) 캡슐화 (Encapsulation)

: 데이터와 데이터를 처리하는 함수를 하나로 묶는 것

  • 캡슐화된 객체는 인터페이스르를 제외한 세부내용이 은폐되어 외부에서 접근이 제한됨
  • 캡슐화는 객체의 인터페이스를 단순화하고 객체 간 결합도를 낮춰 모듈 재사용성을 높이고 외부 환경 변경으로 인한 영향을 최소화함

 

4) 상속 (Inheritance)

: 이미 정의된 상위 클래스의 모든 속성과 연산을 하위 클래스가 물려받는 것

  • 상속받은 하위 클래스는 별도의 정의 없이 상위 클래스의 속성과 함수를 자신의 것으로 이용 가능
  • 하위 클래스는 상속받은 속성과 함수 외에 새로운 속성 및 함수를 첨가하여 사용 가능함
  • 소프트웨어의 재사용성을 높임
  • 다중 상속 (Multiple Inheritance) 가능 : 한 개의 클래스가 여러 개의 부모 클래스로부터 상속받는 것.

 

5) 다형성 (Polymorphism)

: 하나의 메시지에 대해 각 클래스가 자신만의 고유한 방법으로 응답 및 처리를 수행할 수 있는 능력

  • 여러 객체가 동일한 메소드명을 사용하여 다른 방식으로 같은 의미의 응답을 하는 것이 가능
  • 응용 프로그램 상에서 하나의 함수나 연산자가 두 개 이상의 다른 클래스의 인스턴스들을 같은 클래스 인스턴스처럼 수행할 수 있도록 하는 것

 

6) 연관성 (Relationship)

: 두 개 이상의 객체들이 상호 참조하는 관계

  • 연관화 (Association, is member of) : 2개 이상의 객체가 상호 관련되어 있음
  • 분류화 (Classification, is instance of) : 동일한 특성을 갖는 객체들을 모아 구성
  • 집단화 (Aggregation, is part of) : 관련있는 객체들을 묶어 하나의 상위 객체를 구성
  • 일반화 (Generalization, is a) : 공통적인 성질로 추상화한 상위 객체를 구성
  • 특수화/상세화 (Specialization, is a) : 상위 객체를 구체화하여 하위 객체를 구성

24. 객체지향 분석 및 설계

1) 객체지향 분석 (OOA; Object Oriented Analysis)

: 사용자의 요구사항을 분석하여 요구된 문제와 관련된 객체, 객체의 속성 및 함수, 객체 간 관계 등을 정의 및 모델링하는 작업

  • 소프트웨어 개발 업무를 객체와 속성, 클래스와 멤버, 전체와 부분 등으로 나누어 분석
  • 클래스, 객체, 속성, 연산 등을 표현하여 문제를 모형화

 

- 객체지향 분석 방법론

  1. Rumbaugh 방법 : 분석 활동을 객체 모델, 동적 모델, 기능 모델로 나누어 수행
  2. Booch 방법 : 미시적 개발 프로세스와 거시적 개발 프로세스를 모두 사용하는 방법
  3. Jacobson 방법 : 유스케이스를 강조하여 사용하는 방법
  4. Coad/Yourdon 방법 : E-R 다이어그램 (Entity-Relationship diagram)을 이용하는 방법
  5. Wirfs-Brock 방법 : 고객 명세서를 평가하여 설계 작업을 수행하는 방법

 

2) Rumbaugh(럼바우) 분석 방법

: 모든 소프트웨어 구성 요소를 그래픽 표기법을 이용하여 모델링하는 기법. 객체 모델링 기법(OMT; Object-Modeling Technique)

객체 모델링  동적 모델링 기능 모델링

1. 객체 모델링 (Object Modeling)

  • 시스템에서 요구하는 객체를 찾아 그 속성과 연산을 식별하고 객체들 간 관계를 규정하여 객체 다이어그램으로 표시
  • 정보 모델링

 

2. 동적 모델링 (Dynamic Modeling)

  • 상태 다이어그램을 이용하여 시간 흐름에 따른 객체들의 동적 행위를 표현

 

3. 기능 모델링 (Functional Modeling)

  • 자료흐름도를 이용해 여러 프로세스들 간의 자료 흐름을 중심으로 처리 과정을 표현

 

3) 객체지향 설계 원칙 (SOLID 원칙)

: 변경이나 확장에 유연한 시스템 설계를 위해 지켜야할 객체지향 설계의 다섯가지 원칙

각 원칙의 머릿글자를 따 SOLID 원칙이라고도 불린다

1. 단일 책임 원칙 (SRP; Single Responsibility Principle)

: 객체는 단 하나의 책임만을 가진다

 

2. 개방-폐쇄 원칙 (OCP; Open-Closed Principle)

: 소프트웨어 요소는 확장에는 열려있고 변경에는 닫혀있어야 한다. 

-> 기존의 코드 변경없이 기능 추가가 가능해야 한다

 

3. 리스코프 치환 원칙 (LSP; Liskov Substitution Principle)

: 슈퍼클래스의 객체는 자신의 서브클래스의 객체로 대체해도 작동에 문제가 없어야 한다

-> 자식 클래스는 부모 클래스의 연산은 모두 수행할 수 있어야 한다

 

4. 인터페이스 분리 원칙 (ISP; Interface Segregation Principle)

: 자신이 사용하지 않는 인터페이스와 의존 관계가 형성되거나 영향을 받지 않아야 한다

 

5. 의존 역전 원칙 (DIP; Dependency Inversion Principle)

: 상위 클래스는 하위 클래스에 의존해서는 안된다. 추상화는 세부사항에 의존해서는 안된다.