본문 바로가기
소프트웨어공학

[소프트웨어공학] 5장. 설계

by CuckooBird 2024. 6. 13.

01 설계의 이해

  • 요구분석과 설계의 차이
  • 좋은 설계의 조건
    • 요구분석명세서의 내용을 설계서에 모두 포함해야 한다.
    • 유지보수가 용이하도록 추적이 가능해야 한다. 
    • 변화에 쉽게 적응할 수 있어야 한다.
    • 시스템 변경으로 인한 영향이 최소화되도록 국지적이어야 한다.
    • 설계서는 읽기 쉽고, 이해하기 쉽게 작성해야 한다.
    • module의 독립성
    • strongly cohesion
    • lossely coupling

02 설계의 원리

  • 분할과 정복(divided & conquer), 추상화(abstraction), 캡슐화(encapsulation), 정보은닉(information hiding), 상속(inheritance), 다형성(polymorphism)
  • 분할과 정복(divided & conquer)
    • 큰 문제를 소 단위로 나누고, 소 단위의 작업을 하나씩 처리하여 전체 일을 끝내는 방법
    • 가장 세분화된 작은 시스템을 개발하고, 위로 올라가면서 완성시키는 방법으로 개발

    • 모듈의 크기가 작으면 → 모듈의 개수↑ → 모듈 간의 통신 횟수↑ → 효율성↓
    • 모듈이 크기가 크면 → 모듈의 개수↓  → 분할 효과↓ → 분할 의미 퇴색
      → 모듈 크기를 고려한 분할 수준 결정
  • 추상화(abstraction)
    • 자신에게 필요한 특징만 표현한 것
    • 객체지향에서의 추상화
      • 유사한 특성을 가진 것 끼리 그룹화한 뒤 공통점을 뽑아 이름을 붙인 것
      • 객체의 공통적인 속성과 기능을 추출하여 정의하는 것
    • 추상화 방법
      • procedure abstraction: program을 algorithm 형태로 작성 (상세 부분은 생략하고 전체 흐름만 파악할 수 있도록 알고리즘 형태로 작성)
      • data abstraction: data와 method를 모아 데이터 구조 형태로 표현. data와 method를 clss 형태로 캡슐화하여 숨겨놓고, 사용자에게는 꼭 필요한 기능만 사용할 수 있게 개방한 구조
      • control abstraction: 여러 줄의 내용을 간략하게 줄여 표현. 프로그래밍 언어에서 쓰는 제어 구조를 추상화 한 것.
  • 캡슐화(encapsulation)
    • 서로 관련된 정보(data)와 처리 방식(method)을 묶고(class), 외부에 감추어(가시성 사용) 두는 것
    • 캡슐화의 장점
      • data 보호: 사용자의 data 직접 접근 불가 때문
      • 제공자와 이용자를 명확히 분리
      • 사용법이 쉬움: method의 기능만 알면 됨
  • 정보은닉(information hiding)
    • 외부에서 객체의 내부를 직접 접근할 수 없다. → method
    • information hiding vs encapsulation
      • encapsulation = object(data + method), 캡슐 내부와 외부를 결정 지음. → 캡슐화 자체만으로는 내부의 정보가 외부에 숨겨지지 않음 → 해결방법: information hiding
    • interface와 구현의 분리
      • 한 모듈에서 interface와 구현의 분리
    • message 전달 방법: message 전달 → interface(method)를 통해서만 가능 → 효과: 다른 모듈이 내부 정보변경하는 것이 불가능함
    • data와 구현 변경
      • 모듈 내의 자료구조와 method에 사용된 algorithm을 변경하려면 외부에서 그 값을 직접 변경하지 못하므로 공개 interface로 정의된 method를 통해서만 접근 가능하다.
    • information hiding 방법
      • public(+): 외부 접근 허용 → 외부 객체와 정보를 주고 받는 통로 역할. 다른 객체에게 서비스 내용 알려줌
      • private(-): 외부 접근 직접 차단(내부 보호 역할) →  외부로부터 데이터의 손상과 오용을 막아 보호
      • protected(#): 외부 접근 불허, 상속 class에만 허용
    • information hiding 장점
      • block-box 역할: data와 method를 숨김, 객체 사용자와 제공자 역할 분리
      • interface를 통한 접근: 모듈 구현 형태를 몰라도 interface를 통한 사용법만 알면 이용 가능
      • 자료구조 변경 용이: 객체 내부 자료구조를 변경해도 사용자에게는 영향 안 줌
      • 독립성 향상: 다른 모듈과의 관계가 적기 때문
      • 수정 용이: interface만 바뀌지 않으면 내부 구조 변경 시 사용자에게 영향 안 줌
      • 이해도 증진: 모듈 구현 내용 알 필요 없이 제공하는 기능만 알면 사용 가능
      • 확장성 증가: 모듈 내의 변경이 쉬워 기능 추가 하기도 쉽다
  • 상속(Inheritance)
    • inheritance 장점
      • 이해 용이: 상속 관계로 묶음으로써 class 간의 체계화된 전체 구조 파악 용이
      • 재사용성 향상: data와 method의 overloading을 피하고 기존 class의 재사용 가능
      • 확장성 용이: 새로운 class, data, method를 추가하기 쉽다
      • 유지보수 용이: data/method 변경 시 상위 class만 수정 → 전체적으로 일관성 유지
      • 추상화 가능: 일반화/특수화 관계를 통해 추상화 단계 표현 가능
  • 다형성(Polymorphism)
    • 어떤 객체의 속성이나 기능이 상황에 따라 여러 가지 형태를 가질 수 있는 성질
    • overloading (중복 정의)
      • operator overloading(+): 연산자 하나를 다른 용도로 다시 중복 정의하여 사용하는 것
      • method overloading: 한 class에 이름이 동일한 method가 중복 정의되어 있는 경우
        → parameter의 개수(또는 type)를 다르게 한다. → 구별방법: signature
    • overriding (redefinition)
      • 다시 정의, 덮어쓰기
      • 앞에서 정의한 것을 다 무시하고 내가 새로 정의해서 사용하겠다는 것
      • 상위 class에서 정의한 method는 무시, 하위 class에서 새로 정의해 사용.
      • method overriding을 잘못 사용하면 → 설계 원칙 위반
      • 잘못 사용된 method overriding
        • 일반 class, 일반 method 사용 → 리스코프 설계 원칙 위반: 상위 class의 객체는 언제나 자신의 하위 class의 객체로 교체할 수 있어야한다. → 해결책: 추상 class, 추상 method
      • 올바르게 사용된 method overriding
        • abstract class, abstract method 사용

03 모듈화

  • 모듈화: 작은 단위로 나누는 것
    • 모듈
      • '규모가 큰 것을 여러 개로 나눈 조각', 'SW 구조를 이루는 기본적인 단위'
        → 독립 프로그램도 하나의 모듈, 함수(method)들도 하나의 모듈
    • 모듈 특징
      • 다른 것들과 구별될 수 있는 독립적인 기능을 갖는 단위이다.
      • 유일한 이름이어야 한다.
      • module에서 또 다른 module을 호출할 수 있다.
      • 다른 프로그램에서도 module을 호출할 수 있다.
    • 모듈화 원칙
      • 모듈을 너무 작게 나눴을 때: 모듈 개수↑ → 모듈 간 interface 및 통신 횟수↑ → 복잡도 증가
        → 성능 감소
      • 모듈을 너무 크게 나눴을 때: 모듈 개수 ↓ → 모듈 간 interface 및 통신 횟수↓ → 복잡도 감소
        → 모듈화 효과 감소
    • 모듈화 적정 수준
      정답은 없다 - 문제의 유형이나 특성을 고려해 설계자가 결정
    • 모듈화 장점
      • divided and conquer의 원리가 적용 → 복잡도 감소
      • 문제에 대한 이해성 향상
      • 변경하기 쉽고, 변경으로 인한 영향 미비
      • 유지보수의 용이
      • 프로그램의 효율적 관리 가능
      • 오류로 인한 파급효과의 최소화
      • design 및 code의 재사용
    • 모듈간의 관계
      • 모듈의 특성
        • 하나의 모듈은 여러 개의 요소로 구성된다.
        • 모듈은 다른 모듈과 상호 의존 관계를 갖는다.
      • 모듈간의 관계 형태
        • 모듈 A가 모듈 B를 호출하는 관걔 → 호출 관계
        • 매개변수 등을 이용한 데이터 전달로 이루어지는 관계 → 데이터 전달
        • 모듈 A가 모듈 B에게 flag를 통해 이루어지는 관계 → 제어
      • 좋은 모듈 설계 → 모듈 간의 관계가 적은 서로 독립적인 관계의 설계
  • 모듈 평가 기준
    • 응집도(cohesion): 한 모듈 내의 구성 요소들 간의 연관 정도
    • 결합도(coupling): 모듈과 모듈 간의 연관 정도

    • 모듈 평가 기준1: 응집도(cohesion)
      • module 내부에 존재하는 구성 요소들 사이의 밀접한 정도
      • 하나의 module안에서 구성 요소들 간에 똘똘 뭉쳐 있는 정도의 평가
      • 하나의 클래스가 기능에 집중하기 위한 모든 정보와 역할을 갖고 있어야 한다는 의미이다.
      • 응집도가 높은 클래스의 특징
        • 단일 책임을 가진 클래스 (Single Responsibility Principle)
        • 다른 클래스와 잘 협력하는 클래스
      • (모듈 내 구성 요소 간) 응집도의 강도
        • 기능적 응집(functional cohesion): 응집도가 가장 높다. 단일 기능의 요소로 하나의 module을 구성한다.
        • 순차적 응집(sequential cohesion): 요소1의 출력을 요소2의 입력으로 사용 → 두 요소가 하나의 모듈로 묶임
        • 교환적(정보적) 응집(communication cohesion): 같은 입력을 사용하는 구성 요소들을 하나의 module로 구성. 구성 요소들이 동일한 출력을 만들어 낼 때도 교환적 응집
        • 절차적 응집(procedure cohesion): 순서가 정해진 몇 개의 구성 요소가 하나의 모듈로 구성
        • 시간적 응집(temporal cohesion): 구성 요소들이 같은 시간대에 함께 실행된다는 이유로 하나의 모듈로 구성
        • 논리적 응집(logical cohesion): 요소들 간에 공통점 존재/관련된 임무 존재/비슷한 기능
        • 우연적 응집(coincidental cohesion): 묶일 만한 특별한 이유가 없으며, 구성 요소들이 말 그대로 우연히 모여 구성됨
    • 모델 평가 기준 2: 결합도(coupling)
      • 좋은 설계
        • loosely coupled: 상호 의존성 ↓,  module의 독립성  ↑, module 간 영향 ↓
      • (모듈 간) 결합도의 강도
        • 데이터 결합(data coupling): 가장 좋은 모듈 간 결합
          매개변수를 통합 데이터 교환 → 간섭의 최소화 → 독립성 보장 → 관계의 단순화 → 변경으로 인한 영향 미흡 → 유지보수 용이
        • 스탬프 결합(stamp coupling): 필요한 데이터 뿐만 아니라 불필요한 데이터까지(데이터 구조 등) 주게 되는 관계
        • 제어 결합(control coupling): 제어 플래그(flag)를 매개변수로 사용하여 간섭하는 관계
        • 공통 결합(common coupling): 모듈들이 공통 변수 (전역변수)를 같이 사용하여 발생하는 관계
        • 내용 결합(content coupling):  모듈 간에 인터페이스를 사용하지 않고 직접 왔다 갔다 하는 경우의 관계
    • 모듈 간의 좋은 관계
      • 모듈 간에는 꼭 필요한 데이터만 주고받도록 적은 interface의 수를 통한 약한 결합 유지
      • 매개변수로 control flag보다 데이터를 사용 → 유지보수 용이성 향상
      • 낮은 결합도(loosely coupling) 와 높은 응집도(strongly cohesion)

04 사용자 인터페이스 설계

  • 소프트웨어에서의 UI: 시스템이 사용자에게 제공하는 모든 화면
  • 사용자 인터페이스의 역사
    • 문자 UI(Character UI, Command Line Interface)
      • 사용자가 문자로 명령어 입력 → 컴퓨터가 이를 처리한 후 문자 형태로 보여줌
      • 단점: 사용자가 많은 명령어를 알고 있어야 함
    • Graphic UI
      • 현재 많이 사용하는 화면 중심의 UI
    • Natural UI
      • 사용자의 촉각, 음성, 행동을 기반으로 하는 동작 등의 인지 능력을 통해 제어
  • 사용자 인터페이스 설계 지침
    • 사용법이 배우기 쉬워야 한다
    • 사용하기 편리해야 한다
    • 사용자가 데이터 입력을 제어할 수 있어야 한다
    • 사용자의 입력에 반응해야 한다
    • 도움말을 제공해야 한다
    • 일관성을 유지해야 한다
    • 입력 작업은 최소로 해야 한다
    • 효율성을 고려해야 한다
    • 사용자 오류에 댛나 되돌리기 기능을 제공해야 한다
    • 삭제 또는 취소 버튼 클릭 시 재확인을 요구해야한다
    • 사용하기 쉽게 직관적이어야 한다