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

설계

by Debin 2022. 4. 10.
반응형

요구분석과 설계의 차이

구분 요구분석 설계
산출물 요구분석명세서 설계서
관점 무엇 what 어떻게 how
특성 개념적, 추상적 사용환경을 반용해 구체적
비고 미고려 대상 : OS, DBMS, 프레임워크 고려 대상 : 비기능 요구사항, 제약사항
플랫폼(OS, 미들웨어, 프레임워크)

좋은 설계가 되기 위한 조건

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

설계의 원리

분할과 정복

  • 분할 : 큰 소프트웨어 하나를 개발할 때 여러 개의 서브시스템으로 세분화해 나누는 작업
  • 정복 : 어느 정도 수준까지 분할했다면 말단에 있는 것부터 하나씩 개발하는 작업
  • 분할과 정복의 원리 : 프로젝트를 수행할 때 작은 단위로 분할한 뒤 말단에 있는 작은 시스템부터 개발하면서 하나씩 위로 올라가며 완성

분할의 기준

  • 분산 시스템은 클라이언트와 서버로 분할
  • 시스템은 여러 시스템으로 분할
  • 서브시스템은 하나 이상의 패키지로 분할
  • 패키지는 유스케이스나 여러 클래스로 분할

분할의 주의사항

  • 여러 개의 모듈로 분할하면 모듈끼리 통신 횟수가 많아지면서 모듈로 분할하는 장점보다 복잡도가 오히려 증가할 수 있다.
  • 설계자는 어느 수준까지 모듈을 분할할지 결정할 때 복잡도 증가로 인한 부작용과 모듈 분할로 얻는 이득을 함께 고려한다.

추상화

  • 자신에게 필요한 특징만 표현한 것이 추상화다.
  • 주어진 문제에서 현재의 관심사에 초점을 맞추기 위해 특정한 목적과 관련된 필수 정보만 추출해 강조한다.
  • 관련 없는 세부 사항은 생략해 본질적인 문제에 집중할 수 있도록 하는 작업이다.
  • 객체지향 설계에서 추상화란 유사한 특성을 가진 것끼리 그룹화한 뒤 공통점을 뽑아 이름을 붙이는 것.

객체지향 설계에서 추상화의 예

과정 추상화

  • 정의 : 주어진 문제에 대해 프로그래밍하기 전에 상세 부분은 생략하고 전체 흐름만 파악할 수 있는 알고리즘 형태로 작성하는 것이다.

데이터 추상화

  • 데이터와 데이터 구조를 감추는 것으로 대표적인 예가 C++ 언어의 클래스
  • 데이터와 메서드를 클래스 형태로 캡슐화해 숨겨 놓고 사용자에게는 꼭 필요한 기능만 사용할 수 있게 개방한 구조

제어 추상화

  • 프로그래밍 언어에서 쓰는 제어 구조를 추상화
  • 제어 추상화는 단계가 올라갈수록 표현이 더욱 간결해지고 특징만 나타내는 장점
  • 프로그래밍에서 조건을 나타내는 if 문이나 반복을 나타내는 for 문도 사용자가 사용하기 쉽게 추상화하는 것이다.

캡슐화

  • 캡슐화는 사용자에게 해당 객체의 기능(서비스)과 사용법만 제공해 사용하기 쉽게 하고 내부는 함부로 변경할 수 없게 감추는 개념이다.
  • 예를 들어 세탁기와 같은 전자 제품도 기능과 사용법만 알면 되지 내부가 어떻게 구성되어 있으며 어떤 방식으로 돌아가는지 등은 전혀 신경 쓸 필요가 없다.

캡슐화의 장점

  • 추상화를 통해 문제를 쉽게 개념화할 수 있다.
  • 객체 제공자와 객체 이용자(외부 객체)를 명확하게 분리할 수 있다.
  • 메서드의 구현 방법이 바뀌어도 사용자에게는 영향을 미치지 않아 사용하기 쉽다.
  • 메서드의 기능만 알면 객체를 쉽게 사용할 수 있다.
  • 객체 내 자료구조나 알고리즘이 바뀌어도 다른 객체에 미치는 영향이 적다.
  • 캡슐화로 객체 사이의 독립성이 구조적으로 보장된다.
  • 그 객체와 인터페이스로 통신하는 사용자에게는 영향을 주지 않으므로 부담 없이 자료구조를 변경할 수 있다.
  • 프로그램을 개발할 때 제공하는 기능만 알면 되므로 사용자(프로그래머)가 모듈을 이해하기 쉽다.
  • 모듈 내의 데이터와 알고리즘을 변경하기 쉬우므로 기능을 추가하기 쉽다.

은닉화

  • 외부(다른 객체)에서 객체의 내부(데이터)를 들여다볼 수 없는 개념
  • 캡슐화는 캡슐의 내부와 외부를 구분하지만 그 자체로 내부 정보가 외부에 숨겨지지는 않음. 이때 정보은닉이 필요하다.

정보 은닉의 속성

  • + 공개, public : 모든 곳에서 접근. 주로 메서드가 public
  • - 은닉, private : 해당 클래스의 메서드를 통해서만 접근. 클래스에서 대부분의 속성은 private
  • # 부분 공개, protected : 다른 클래스가 접근 불가. 해당 클래스의 메서듸와 클래스를 상속받은 하위 클래스만 접근 가능하다.

상속

  • 상위 클래스의 모든 것을 하위 클래스가 물려받아 내 것처럼 사용함을 의미한다.
  • 물려주는 클래스 : 상위 클래스, 부모 클래스
  • 물려받는 클래스 : 하위 클래스, 자식 클래스
  • 클래스 간의 상속 관계는 속이 빈 삼각형 모양의 화살표를 사용한다.

상속의 장점

  • 상속 관계를 이용하면 개별 클래스를 상속 관계로 묶어서 구조를 파악하기 쉽다.
  • 상속 관계에 속한 클래스, 데이터, 메서드를 추가하기 쉽다.
  • 데이터와 메서드를 변경할 때 상위에 있는 것만 수정할 수 있다.

상속의 개념

다형성

오버로딩 (중복 정의)

  • 연산자 중복 정의
  • 메서드 중복 정의
  • 같은 메서드를 구별하는 법 : 매개변수의 개수, 매개변수의 자료형으로 구분
  • 시그니처 : 동일한 메서드가 호출되었을 때 구별할 수 있는 매개변수의 개수나 자료형 같은 요소

오버라이딩 (재정의)

  • 메서드 재정의
  • 상위 클래스에서 정의한 메서드는 무시하고 하위 클래스에서 다시 정의해 사용하는 것
  • 메서드 재정의를 잘못 사용하면 설계 원칙에 위배된다.
  • 상위 클래스도 일반 클래스이고 메서드도 일반 메서드를 사용하고 있어 리스코프 교체 원칙을 위반
  • 추상 클래스와 추상 메서드를 사용하면 리스코프 교체 원칙을 위반하지 않는다.
  • 리스코프 교체 원칙은 상위 클래스의 객체는 언제나 자신의 하위 클래스의 객체로 교체할 수 있어야 한다.

모듈화

  • 모듈이란 규모가 큰 것을 여러 개로 나눈 조각, 소프트웨어 구조를 이루는 기본 단위다.
  • 독립 프로그램도 하나의 모듈이 될 수 있고, 함수도 하나의 모듈이 될 수 있다.

모듈의 특징

  • 다른 것과 구별되는 독립적인 기능을 갖는 단위
  • 유일한 이름을 가진다.
  • 모듈에서 또 다른 모듈을 호출할 수 있다.
  • 다른 프로그램에서도 모듈을 호출할 수 있다.

모듈의 원칙

  • 모듈화를 하기 전에 먼저 어느 정도의 크기로 나눌 것인지를 생각한다.
  • 문제의 유형이나 특성을 고려해서 결정한다.
  • 모듈 간의 결합은 느슨하게 해야 한다.
  • 모듈 내 구성 요소 간의 응집은 강하게 해야 한다.

모듈화의 장점

  • 분할과 정복의 원리가 적용되어 복잡도가 감소한다.
  • 변경하기 쉽고 변경으로 인한 영향도 적다.
  • 프로그램을 효율적으로 관리할 수 있다.
  • 설계 및 코드를 재사용할 수 있다.
  • 문제를 이해하기 쉽게 만든다.
  • 유지보수가 용이하다.
  • 오류로 인한 파급 효과를 최소화할 수 있다.

모듈 개수와 모듈화의 효과

모듈 평가 기준 1: 응집도

  • 모듈 내부에 존재하는 구성 요소 사이의 밀접한 정도, 즉 하나의 모듈 안에서 구성 요소 간에 뭉쳐 있는 정도로 평가
  • 응집도가 높을수록 꼭 필요한 구성 요소만 모여 있고, 응집도가 낮을수록 서로 관련성이 적은 구성 요소들이 모인다.
  • 응집도가 가장 높은 것은 모듈 하나가 단일 기능으로 구성된 경우다.
  • 응집도가 가장 낮은 것은 구성 요소가 필요에 의해 모듈에 존재하는 것이 아니라 우연히 함께 묶인 경우다.

모듈 내 구성 요소 간의 응집도

기능적 응집

  • 함수적 응집이라고도 하며 응집도가 가장 높은 경우로 단일 기능의 요소가 하나의 모듈로 구성된다.
  • 단일 기능을 갖는 함수가 해당된다.

순차적 응집

  • 두 요소가 하나의 모듈로 구성된 경우다. 아래의 예시를 확인하자.
  • 물론 두 요소를 개별 모듈로 만들어도 되지만, 한 모듈의 결과를 다른 모듈이 입력으로 사용하기 때문에 두 요소를 하나의 모듈로 묶어 놓았다. 
  • 두 요소가 아주 밀접하므로 하나의 모듈로 묶을 만한 충분한 이유가 된다.

순차적 응집

교환적 응집

  • 정보적 응집이라고도 하며 입력을 사용하는 구성 요소가 하나의 모듈로 구성된다.
  • 구성 요소가 동일한 출력을 만들어낼 때도 교환적 응집이 된다.
  • 요소 간의 순서는 중요하지 않다.
  • 순차적 응집 보다 묶인 이유가 조금 약하므로 순차적 응집보다는 응집력이 약하다고 볼 수 있다.

교환적 응집의 예

절차적 응집

  • 순서가 정해진 몇 개의 요소가 하나의 모듈로 구성된 경우다.
  • 순차적 응집과는 어떤 구성 요소의 출력이 다음 구성 요소의 입력으로 사용되지 않고 순서에 따라 수행된다는 점이 다르다.
  • 한 요소의 출력이 다음 요소의 입력으로 사용되지 않으므로 순차적 응집보다는 묶인 이유가 조금 약한 편이다.

절차적 응집의 예

시간적 응집

  • 모듈 내 구성 요소의 기능이 각기 다르고 요소의 출력을 입력으로 사용하는 것도, 요소 간에 순서가 정해진 것도 아니다.
  • 구성 요소들이 같은 시간대에 함께 실행된다는 이유로 하나의 모듈로 구성한다.
  • 초깃값 설정 모듈이 시간적 응집의 예라고 볼 수 있다.

같은 시간대에 일어나는 일을 하나의 모듈로 묶음. 시간적 응집의 예

논리적 응집

  • 구성 요소 간에 공통점이 있거나 관련된 임무가 존재하거나 기능이 비슷해서 하나의 모듈로 구성된 경우
  • 예를 들어 행렬 덧셈과 정수 덧셈을 모듈로 모아둔 것이 논리적 응집의 예이다.

우연적 응집

  • 구성 요소들이 말 그대로 우연히 모여 구성된 것이다. 특별한 이유 없이 몇 개의 모듈로 나누는 과정에서 우연히 같이 묶인 것이다. 구성 요소 간에 관련이 별로 없어 응집도가 가장 낮다.

모듈 평가 기준 2: 결합도

  • 모듈과 모듈 사이의 관계에서 관련 정도를 나타낸다.
  • 모듈 간의 결합에도 간섭하는 관계와 좋은 관계(간섭 적은)가 있다.
  • 모듈 간에는 관련이 적을수록 상호 의존성이 줄어 모듈의 독립성이 높아지고 독립성이 높으면 모듈 간에 영향이 적다.
  • 결합에서 좋은 관계는 데이터만 주고받은 관계 / 나쁜 관계는 필요한 데이터만 주지 않고 직접 관여(간섭)하는 관계

모듈 간의 결합도

데이터 결합

  • 가장 좋은 모듈 간 집합
  • 모듈이 매개변수를 통해 데이터만 주고받음으로써 서로 간섭을 최소화
  • 모듈 간의 독립성이 보장되고, 관계가 단순해 하나의 모듈을 변경해도 다른 모듈에 미치는 영향이 아주 적다.
  • 유지보수도 매우 쉽다.

스탬프 결합

  • 두 모듈이 정보를 교환할 때 필요한 데이터만 주고받을 수 없고 필요 없는 데이터까지 전체를 주고받아야 하는 경우다.
  • 스탬프에 해당하는 것은 레코드나 배열 같은 자료구조로 하나의 데이터만 필요한데도 레코드 전체가 넘어온다.
  • C 언어의 구조체도 스탬프 결합의 예
  • 데이터 하나가 변경되면 관련된 모듈에 있는 자료구조를 모두 바꿔야 하므로 데이터 결합보다 모듈 간의 관련성이 더 높다.

제어 결합

  • 호출하는 모듈이 호출되는 모듈의 내부 구조를 잘 알고 논리적 흐름을 변경하는 관계로 묶이는 관계다.
  • 데이터 결합이 데이터를 매개변수로 정보를 교환했다면 제어 결합은 제어 플래그를 매개변수로 사용한다.
  • 정보은닉을 크게 위배하여 다른 모듈의 내부에 관여해 관계가 복잡해지고 그로 인해 유지보수도 매우 어려워짐
  • 스탬프 결합보다 모듈 간의 결합도가 더 높고 모듈의 독립성은 더 낮다.

공통 결합

  • 모듈이 공통 변수를 함께 사용하므로 모듈이 전역 변수를 사용할 때 공통 결합이 성립
  • 변숫값이 변하면 모든 모듈이 함께 영향을 받는 문제가 있다.
  • 공통 영역에서 문제가 발생하거나 데이터가 변경되면 관련된 모듈을 모두 검토해야 하므로 유지보수가 어렵다.
  • 데이터를 개별 모듈 내부에서 지역 변수로 선언하며 보완한다.

내용 결합

  • 모듈 간에 인터페이스를 사용하지 않고 직접 왔다 갔다 하는 것
  • 상대 모듈의 데이터를 직접 변경할 수 있어 서로 간섭을 가장 많이 한다.
  • 가장 바람직하지 못한 관계로, 모듈이 서로 종속되어 독립적으로 설계하거나 변경할 수 없다.
  • 한 모듈이 다른 모듈 내부의 데이터를 직접 참조해 모듈의 독립성이 보장되지 않으므로 유지보수가 매우 어렵다.

모듈 간의 좋은 관계

  • 모듈 간에는 꼭 필요한 데이터만 주고받는 것이 좋다.
  • 약한 결합을 유지하는 것이 바람직하므로 인터페이스의 수가 적고 복잡하지 않아야 한다.
  • 그러려면 매개변수로 제어 플래그를 사용하는 것보다 데이터를 사용하는 것이 유지보수의 용이성을 높일 수 있어 좋다.
  • 결론적으로, 설계를 할 때 가장 좋은 형태는 모듈 간의 결합도는 낮게, 응집도는 높게 하는 것이다.

사용자 인터페이스 설계

  • 사용자 인터페이스 : 사람과 사람, 사람과 사물, 사물과 사물 사이를 연결해주는 매개체 (tv 리모컨, 성적조회 화면 등)
  • 예전에는 CUI, CLO를 많이 사용했지만 많은 명령어를 필요해 불편했다.
  • 지금은 GUI, NUI가 많이 사용된다.

사용자 인터페이스의 설계 지침

  • 사용법을 배우기 쉬워야 한다.
  • 사용하기 편리해야 한다.
  • 사용자가 데이터 입력을 제어할 수 있어야 한다.
  • 사용자의 입력에 반응해야 한다.
  • 도움말을 제공해야 한다.
  • 일관성을 유지해야 한다.
  • 입력 작업은 최소로 해야 한다.
  • 효율성을 고려해야 한다.
  • 사용자 오류에 대한 되돌리기 기능을 제공해야 한다.
  • 삭제 또는 취소 버튼 클릭 시 재확인을 요구해야 한다.
  • 사용하기 쉽게 직관적이어야 한다.

 

이상으로 포스팅을 마칩니다. 감사합니다.

 

참고자료

쉽게 배우는 소프트웨어 공학 2판 (5단원 설계)

http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9791156645429 

 

서비스 점검 - 교보문고

서비스 점검 중입니다 안녕하세요. 교보문고입니다. 홈페이지의 원활한 서비스를 위하여 임시 점검을 실시합니다. 점검 중에는 서비스를 이용하실 수 없으니 고객님의 양해 부탁드립니다. 점검

notice.kyobobook.co.kr

 

반응형