Skip to content

Latest commit

 

History

History
310 lines (181 loc) · 12.2 KB

SWEng6-Design_Principles.md

File metadata and controls

310 lines (181 loc) · 12.2 KB

Design Principles

1. 설계 (Design)

설계

어떻게 실현할 것인가 (<-> 요구분석: 무엇을 만들 것인가)

  • 문제를 해결하여 솔루션을 구축해가는 과정
  • 기본 구조 설계; 아키텍처 설계로 각 모듈의 역할과 인터페이스를 정의
  • 상세 설계: 모듈 내부의 알고리즘, 데이터를 명세화

설계 방법

  • 전통적 방법
    • 분할 정복, top-down, 추상화 등
    • 기능 실현에 중점
  • 최근 방법
    • 아키텍처 기반의 설계 방법 (복잡한 문제 처리, 변경에 대처)
    • 품질 중심 설계

2. 설계 기본 개념

소프트웨어 아키텍처

시스템을 구성하는 컴포넌트와 컴포넌트 상호작용의 집합

컴포넌트

  • 독립적으로 취급될 수 있는 단위 (서브시스템 or 모듈)

  • 재사용 가능하게 설계

  • 서브시스템

    • 시스템의 복잡도를 줄이기 위해 분할한 것

    • 분업, 커뮤니케이션 줄임, 서브시스템끼리 영향 덜 받음

      예) java에서는 패키지로 구현

  • 모듈

    • 프로그래밍 언어의 문법 구조에서 정의된 컴포넌트

      예) 메서드, 클래스, 패키지, 파일, 함수 등

설계 관점

  • 소프트웨어 구조 (컴포넌트와 그것들의 관계)를 바라보는 일관된 방법
  • 과거와는 달리 관점에 근거한 품질 중심 설계로 변화됨
  • 종류
측면 모듈 관점(정적) 컴포넌트 관점(동적) 할당 관점
내용 일정한 책임을 구현한 코드 단위인 모듈과 그 관계 실행될 떄 동작하는 요소들과 상호작용 소프트웨어의 하드웨어 설치, 작업 할당 , 구현, 데이터 저장에 대한 관점
설계 스타일 분할, 사용 관계, 계층구조, 데이터 모델 클라이언트 서버, 파이프, 출판 구독, 이벤트, 저장소 배치, 설치, 작업할당, 데이터 저장

설계 작업

  • 의사 결정 과정이면서 동시에 시스템을 알아가는 과정

  • 개발될 시스템의 유형이 중요 -> 아키텍처 스타일에 많은 영향을 줌

    예) 대화형 시스템 -> 계층 구조 스타일

    예) 임베디드 시스템 -> event-driven 스타일

    예) 기존 시스템에 속하지 않는 시스템 -> 맞춤형 아키텍처 스타일

  • 설계 목적 -> 설계 결과(품질)에 영향을 줌

    예) 보안이 주요 목적이라면 인증 모듈, 정보보호 인터페이스 고려


3. 품질 목표

품질 특성

  • 비기능적 요구
  • 설계에 대한 목표가 될 수 있음 -> 구체적으로 명시
  • 이 설계 목표를 위한 설계안을 만들고 최적안을 골라내는 작업
    • 서로 상충되는 요구(예: 성능 <-> 안정성)가 있을 때 최적안 선택
  • ISO 25010 품질 특성 모델
    • 성능: 단위시간당 처리량이 높은가, 트랜잭션당 응답 시간이 짧은가
    • 상호운영성: 외부 시스템과의 데이터 전송/교환이 용이한다
    • 사용용이성: 시스템의 효율적 사용으로 인해 사용자가 만족하는가
    • 신뢰성: 시스템이 정의된 조건 아래 계속 동작할 수 있는가
    • 보안성: 악의적, 우발적 행동으로부터 시스템을 보호하는가
    • 유지보수성: 변경을 시스템이 얼마나 잘 수용할 수 있는가
    • 이식성: HW, SW, 사용 환경을 다른 곳으로 쉽게 변환할 수 있는가

4. 전통적인 설계 원리

전통적인 중요한 특성

단순성 효율성 분할, 계층화 추상화 모듈화
복잡한 여러가지 요소를 교통 정리하여 단순화 하거나 복잡함을 최소화 한다. 사용하는 자원이 적정하고 효과적이도록 한다. 다루기 쉬운 덩어리로 분리하여 계층화 한다. 자세한 부분에 좌우되지 않게 컴포넌트를 정의한다. 각 모듈이 외부와의 결합이 낮고 내부 요소가 응집되도록 한다.
  • 단순성

    유지보수성에 영향을 주는 가장 중요한 특성

  • 효율성

    시스템 자원(처리시간, 기억공간)이 적정하고 효과적 -> 비용 절약

  • 추상화

    • 특정 목적에 관한 정보에 집중

    • 구현에 대한 자세한 사항을 고려하지 않음

      예) 자동차를 추상화하면, 엑셀 밟으면 가속하고 브레이크 밟으면 감속하는 객체

    • 데이터나 절차적인 동작 관점으로 정의

      예) 클라이언트와 서버의 정보교환을 주고받은 메시지의 추상화

  • 캡슐화

    • 추상화된 대상이 제공하는 서비스를 쉽게 접근하게 하는 개념
    • 자세한 구현 내용을 숨김 -> 정보 은닉 (information hiding)
    • 더 높은 수준의 추상화 유지
  • 모듈화 -> 외부 결합은 낮고, 내부 응집은 높게 설계함

    • 문제를 작은 요소로 분할 (패키지, 클래스 등)
    • 재사용 가능성 극대화
    • 의존성 최소화

결합

The degree of interdependence between two modules

  • 모듈 간에 서로 의존하는 정도
    • 모듈 간 인터페이스 수
    • 각 인터페이스의 복잡성(통신 유형에 따라 결정됨)
  • 낮은 결합이 바람직함

응집

The measure of the strength of functional relatedness of elements within a module

  • 하나의 모듈 안에서 수행되는 작업들이 서로 관련된 정도
  • 모듈 안의 여러 요소들이 하나의 목적을 위하여 유기적으로 관련되어 있는 것이 좋음
  • 높은 응집이 바람직함
    • 재사용 쉬움
    • 이해하기 쉬움
    • 수정에 의하여 받는 영향이 적음

결합 종류

숫자가 작을수록 결합도 높음.

  1. 내용 결합

    한 모듈이 다른 모듈 내부의 내용을 직접 참조

    예: 모듈 a가 모듈 b의 상태 변경

  2. 공통 결합

    한 모듈이 다른 모듈이 읽은 전역 변수 값을 쓰거나 변경

    예: 두 모듈이 같은 전역변수 접근

  3. 제어 결합

    한 모듈이 다른 모듈의 제어흐름 경로(어떤 동작을 해야하는지)를 결정

    예: function A calls B with a 'flag' saying what to do

  4. 스탬프 결합

    여러 모듈이 복합 데이터 구조(구조체)를 공유하고 각기 일부만 사용함

    구조체를 분해해서 각 모듈에 요구되는 최소 데이터 구조를 사용함

  5. 데이터 결합

    모듈들이 주고받는 매개변수가 간단한 타입이거나 레코드 안의 필드이더라도 단순 타입인 경우

    예: display time of arrival (w/ flight number)

응집 종류

숫자가 작을수록 낮은 응집

  1. 우연적 응집: 단위 안의 요소들이 의미적으로 아무 관계가 없음

  2. 논리적 응집: 본질적으로 다르더라도 같은 범주의 기능을 수행하므로 논리적으로 분류

    예: 마우스 및 키보드 입력 처리 루틴을 모듈로 묶음

  3. 시간적 응집: 시간의 흐름에 따라 수행되는 동작을 묶음

  4. 절차적 응집: 모듈 안에서 수행되는 연산이 프로그램에서 수행되는 순서와 관련

  5. 교환적 응집: 동일한 데이터를 조작하는 것끼리 그룹화

    예: DB record read/write

  6. 기능적 응집: 단 하나의 기능에 모두 기여하고 밀접하게 관련

    예: XML 문자열의 어휘 분석에 관련된 기능들 모음

  7. 정보적 응집: 여러 동작이 고유한 시작점, 독립된 코드가 있고, 같은 데이터에 대해 실행하며, 각 기능이 정확히 한가지 동작만 해야 함


5. 객체지향 설계 원리

객체지향 개념(상속과 인터페이스 등)의 발전 -> 재사용, 수정용이성 상승

객체지향 설계 원칙 (SOLID) by Robert C. Martin

  • 인터페이스(interface)와 구현(implementation)의 분리

  • 단일 책임의 원칙 (Single Responsibility Principle)

    Class는 하나의 기능만 가지며, 그 Calss가 제공하는 모든 서비스는 그 기능을 수행하는 데 집중되어야 한다.

  • 개방/폐쇄의 원칙 (Open/Close Principle)

    소프트웨어 개체(클래스, 모듈, 함수 등)는 확장에 대해 열려있어야하고, 수정에 대해서는 닫혀 있어야 한다.

  • 리스코프 치환 원칙 (Liskov Substitution Principle)

    프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.

  • 인터페이스 분리의 원칙 (Interface Segregation Principle)

    클라이언트는 자신이 사용하지 않는 메서드에 의존 관계를 맺으면 안된다.

  • 의존관계 역전의 원칙 (Dependency Inversion Principle)

    구체화가 아닌 추상화에 의존해야 한다.

단일 책임의 원칙

클래스의 역할과 책임을 단일화

-> 클래스를 변경해야 할 이유를 하나로 제한

개방/폐쇄의 원칙

  • 수정에 영향을 받지 않아야 함
  • 쉽게 확장하여 재사용 가능하게 함
  • 상속 (다형성) 이용

리스코프 치환 원칙

  • Class B 가 Class A 를 상속했을 때
    • 프로그램의 동작을 방해하지 않고 A를 B로 대체 가능
    • B는 A의 기능을 손상시키면 안됨

인터페이스 분리의 원칙

사용하지 않는 인터페이스를 강제로 구현해서는 안됨

  • Dummy 메서드 구현을 강제하는 상황을 만들면 안됨 -> 'fat interface' or 'polluted interface'
  • 예: eat(), slepp(), walk(), fly() 메소드를 가진 하나의 Animal Interface
    • CanEat, CanSleep, CanWalk, CanFly 라는 4개의 Interface 로 쪼개어 정의함
    • 그러면, 각 동물은 위 Interface를 선택적으로 상속하여 정의 할 수 있음

의존관계 역전의 원칙

  • 높은 수준의 모듈이 낮은 수준의 추상화된 인터페이스에 의존하게 설계함
  • 높은 수준의 모듈이 낮은 수준의 모듈에 종속되어서는 안됨

6. 설계 메트릭 (Design Metrics)

설계 모델에 대한 측정방법

전통적인 메트릭

  • 크기 - 시스템 규모 (모듈, 인터페이스, 클래스, 메서드 개수)

  • 복잡도 - 시스템 복잡한 정도 (모듈, 데이터, 시스템 등)

  • 결합도 - 모듈 사이의 연결된 정도 (매개변수, 전역변수, 호출 함수 수)

  • 응집도 - 단일 목적을 위해 얼마나 잘 협동하는지

  • 정보흐름 - 얼마나 많은 정보가 흘러가는지

    (전달하는 매개변수, 전역변수, 입출력의 수, 모듈 호출 수 등)

객체지향 메트릭

설계 메트릭 타입 설명
클래스 당 가중 메소드 (WMC) 복잡도 클래스 안에 있는 메소드의 복잡도 메트릭스의 합
상속 트리의 깊이 (DIT) 상속 깊이 상속 트리의 루트로부터 해당 클래스까지 가장 깊은 상속 경로
지식 노드의 개수 (NOC) 상속 너비 클래스의 상속 구조에서 직계 자식 클래스의 수
클래스 사이의 결합 (CBO) 결합도 당 클래스가 의존하고 있는 클래스의 개수
클래스의 책임 (RFC) 크기 클래스의 메소드 개수에 그 클래스의 메소드가 호출하는 메소드의 개수
메소드의 응집 결핍 응집도 소속된 클래스의 속성을 공유하지 않는 메소드 쌍의 수