소프트웨어공학

설계

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

 

반응형

댓글