1. 소프트웨어 설계 - 애플리케이션 설계(모듈 ~ 디자인 패턴)

1. 모듈

: 모듈화를 통해 분리된 시스템의 각 기능 (서브루틴, 서브시스템, 프로그램, 작업 단위 etc.)

  • 모듈은 단독으로 컴파일이 가능하고 재사용 할 수 있음
  • 모듈의 기능적 독립성 : 소프트웨어를 구성하는 각 모듈의 기능이 서로 독립됨을 의미
  • 모듈의 독립성은 모듈이 하나의 기능만을 수행하고 다른 모듈과 과도하게 상호작용하지 않음으로써 이루어짐
  • 모듈의 독립성을 위해 결합도는 약하게, 응집도는 강하게, 모듈의 크기는 작게 만들어야 함.

 

1) 결합도 (Coupling)

: 모듈 간에 서로 의존하는 정도 또는 두 모듈 간의 연관 관계

  • 결합도가 약할수록 모듈의 독립성이 높고 품질이 높아짐
  • 결합도가 강하면 시스템 구현 및 유지보수가 어려워짐
자료 결합도 스탬프 결합도 제어 결합도 외부 결합도 공통(공용) 결합도 내용 결합도
결합도 약함<--------------------------------------------------------------------------------------->결합도 강함

1. 자료 결합도 (Data Coupling)

: 모듈 간의 인터페이스가 자료 요소로만 구성될 때의 결합도

  • 한 모듈이 다른 모듈 호출 시에 매개 변수나 인수로 데이터를 넘겨주고 호출받은 모듈은 받은 데이터에 대한 처리 결과를 반환하는 방식
  • 모듈이 서로 내용을 알 필요가 없으므로 서로 영향을 미치지 않는 가장 바람직한 결합도

 

2. 스탬프 결합도 (Stamp Coupling)

: 모듈 간의 인터페이스로 자료구조(배열, 레코드 etc.)가 전달될 때의 결합도

  • 두 모듈이 동일한 자료구조를 조회하는 방식
  • 자료 구조의 변화가 모듈에 영향을 미치게 됨

 

3. 제어 결합도 (Control Coupling)

: 한 모듈이 다른 모듈 내부의 논리 흐름을 제어하기 위해 제어 신호를 이용하거나 제어 요소(function code, switch, flag etc.)를 전달 때의 결합도

  • 한 모듈이 다른 모듈의 상세한 처리 절차를 알고 이를 통제하는 경우나 한 처리 기능이 두 모듈에 분리되어 설계된 방식
  • 하위 모듈이 상위 모듈에게 처리 명령을 내리게 되는 권리 전도현상이 발생함

 

4. 외부 결합도 (External Coupling)

: 한 모듈 내부의 데이터를 다른 모듈에서 참조할 때의 결합도

  • 참조되는 데이터의 범위는 각 모듈에서 제한할 수 있음

 

5. 공통(공용) 결합도 (Common Coupling)

: 공유되는 공통 데이터 영역을 여러 모듈이 사용할 때의 결합도

  • 공통 데이터 영역의 내용을 조금만 변경하더라도 이를 사용하는 모든 모듈이 영향을 받음

 

6. 내용 결합도 (Content Coupling)

: 한 모듈이 다른 모듈 내부의 자료 및 기능을 직접 참조하거나 수정할 때의 결합도

  • 한 모듈에서 다른 모듈의 내부로 제어가 이동하는 방식

 

2) 응집도 (Cohesion)

: 모듈의 내부 요소들이 서로 관련되어 있는 정도. 모듈이 독립적인 기능으로 정의되어 있는 정도

  • 정보 은닉의 확장 개념
  • 응집도가 강할 수록 모듈의 독립성이 높고 품질이 높아짐
기능적 응집도 순차적 응집도 교환(통신)적 응집도 절차적 응집도 시간적 응집도 논리적 응집도 우연적 응집도
결합도 약함<------------------------------------------------------------------------------------->결합도 강함

1. 기능적 응집도 (Functional Cohesion)

: 모듈 내부의 모든 기능 요소들이 단일 문제와 연관되어 수행될 경우의 응집도

 

2. 순차적 응집도 (Sequential Cohesion)

: 모듈 내부에서 하나의 활동으로부터 나온 출력 데이터를 그 다음 활동의 입력데이터로 사용할 경우의 응집도

 

3. 교환(통신)적 응집도 (Communicational Cohesion)

: 동일한 입력과 출력을 사용하는 서로 다른 기능이 모였을 때의 응집도

 

4. 절차적 응집도 (Procedural Cohesion)

: 모듈이 가지는 다수의 관련 기능이 순차적으로 수행될 경우의 응집도

 

5. 시간적 응집도 (Temporal Cohesion)

: 특정 시간에 처리되는 몇 개의 기능을 모아 하나의 모듈을 구성할 때의 응집도

 

6. 논리적 응집도 (Logical Cohesion)

: 유사한 성격을 갖거나 특정 형태로 분류되는 처리 요소들이 하나의 모듈을 구성할 때의 응집도

 

7. 우연적 응집도 (Coincidental Cohesion)

: 모듈 내부의 구성 요소들이 서로 관련이 없을 경우의 응집도

 

3) 팬인 / 팬아웃

: 시스템의 복잡도를 알 수 있는 개념. 팬인이 높을수록, 팬아웃이 낮을 수록 시스템의 복잡도가 최적화된다.

  • 팬인(Fan-in) : 해당 모듈을 제어(호출)하는 모듈의 수
  • 팬아웃(Fan-out) : 해당 모듈에 의해 제어(호출)되는 모듈의 수
  • 팬인이 높다면 재사용 측면에서 설계가 잘 되어있다고 평가하나, 단일 장애점이 발생할 수 있음
  • 팬아웃이 높다면 단순화시킬 수 있는지 검토가 필요함

ex. 1. 옆의 시스템 구조도에서 모듈 F의 팬인 수는?

-> 3 (B, C, D)

 

ex. 2. 옆의 시스템 구조도에서 모듈 B의 팬아웃 수는?

-> 2 (E, F)

 

ex. 3. 옆의 시스템 구조도에서 모듈 A의 팬인 수는?

-> 0 (최상위 모듈이며 팬인이 없다)

 

 

4) N-S 차트 (Nassi-Schneiderman Chart)

: 논리 기술에 중점을 둔 도형을 이용한 표현 방법 (박스 다이어그램, Chapin Chart)

같은 작업을 나타내는 플로우 차트와 NS차트의 비교

  • 연속, 선택 및 다중 선택, 반복 등의 제어 논리 구조 표현
  • GoTo 나 화살표를 사용하지 않음
  • 단일 입구와 단일 출구로 표현
  • 선택과 반복 구조를 시각적으로 표현
  • 읽고 이해하기는 쉬우나 작성이 어려움
  • 코드 변환이 용이함
  • 임의로 제어를 전이하는 것이 불가능함
  • 총체적인 구조 표현이나 인터페이스를 나타내기 어려움

26. 공통 모듈

: 여러 프로그램에서 공통적으로 사용할 수 있는 모듈

  • 자주 사용되는 계산식 또는 매번 필요한 로그인, 사용자 인증 등의 기능을 공통 모듈로 구성함
  • 모듈의 재사용성 확보와 중복 개발 회피를 위해 설계 과정에서 공통 부분을 식별하고 명세를 작성
  • 공통 모듈 구현 시의 명세 기법
    • 정확성 (Correctness) : 해당 기능이 필요함을 알 수 있도록 정확히 작성
    • 명확성 (Clarity) : 기능이 중의적으로 해석되지 않도록 명확히 작성
    • 완전성 (Completeness) : 시스템 구현을 위해 필요한 모든 부분을 기술
    • 일관성 (Consistency) : 공통 기능들 간의 충돌이 없도록 작성
    • 추적성 (Traceability) : 기능에 대한 요구사항의 출처, 관련 시스템 등의 관계를 파악할 수 있도록 작성

 

1) 재사용 (Reuse)

: 이미 개발된 기능들을 파악하고 재구성하여 새로운 기능 개발에 사용하기 적합하도록 최적화하는 작업

  • 누구나 이해하고 사용이 가능하도록 재사용 기능의 사용법을 공개해야 함
  • 재사용되는 모듈은 외부 모듈과 결합도는 낮고 응집도는 높아야 함
  • 규모에 따른 분류
    • 함수와 객체 : 클래스나 메소드 단위의 소스코드
    • 컴포넌트 : 컴포넌트 자체를 수정 없이 인터페이스를 통해 재사용
    • 애플리케이션 : 공통 기능을 제공하는 어플리케이션을 공유하여 재사용

 

2) 효과적인 모듈 설계

  • 모듈의 독립성과 재사용성을 위해 결합도는 줄이고 응집도는 높인다
  • 모듈의 제어 영역 안에 그 모듈의 영향 영역을 유지한다
  • 복잡도와 중복성을 줄이고 일관성을 유지한다
  • 기능은 예측 가능해야 하며, 지나치게 제한적이어서는 안된다
  • 유지보수가 용이해야 한다
  • 모듈은 기능과 구조를 이해하기 쉬운 크기로 분해한다
  • 하나의 입구와 하나의 출구를 갖도록 한다
  • 모듈 인터페이스를 설계해 전반적인 구조에 영향을 미치지 않도록 한다
  • 모듈 간의 계층적 관계를 정의하는 자료를 제시한다

27. 코드

: 자료 처리 과정에서 분류, 조합, 집계를 용이하게 하고 자료 추출을 쉽게하기 위해 사용하는 기호

  • 코드는 정보를 신속, 정확, 명료하게 전달하기 위함
  • 일정한 규칙에 따라 작성되며 정보에 가치에 큰 영향을 줌
  • ex) 주민등록번호, 학번, 전화번호 etc.
  • 코드의 주요 기능
    • 식별 기능 : 데이터 간 구분을 가능케 함
    • 분류 기능 : 같은 유형에 해당하는 데이터를 그룹화함
    • 배열 기능 : 데이터를 나열할 수 있게 함
    • 표준화 기능 : 다양한 데이터를 기준에 맞추어 표현할 수 있게 함
    • 간소화 기능 : 복잡한 데이터를 단순화함

1) 코드의 종류

다양한 코드의 예시

1. 순차 코드 (Sequence Code)

: 자료를 일정 기준에 따라 첫 자료부터 차례로 일련번호를 부여하는 방법 (순서 코드, 일련번호 코드)

 

2. 블록 코드 (Block Code)

: 항목 중 공통성이 있는 것끼리 블록으로 구분하고 각 블록 내에서 일련번호를 부여

ex) 1001 ~ 1100 : 총무부, 1101 ~ 1200 : 영업부 ...

 

3. 10진 코드 (Decimal Code)

: 항목을 0~9까지 10진 분할하고 다시 그 각각에 대해 10진 분할하는 과정을 반복하는 방식 (도서 분류식 코드)

ex) 500 - 기술과학 -> 510 - 의학, 520 - 농업, 농학 ....

 

4. 그룹 분류 코드 (Group Classification Code)

: 항목을 일정 기준에 따라 대분류, 중분류, 소분류 등으로 구분하고 각 그룹 안에서 일련번호를 부여

ex) 1-01-001 : 본사-총무부-인사계, 1-01-002 : 본사-총무부-행정계 ...

 

5. 연상 코드 (Mnemonic Code)

: 항목의 명칭이나 약호와 관계있는 숫자, 문자, 기호 등을 이용하여 코드 부여

ex) 40인치 TV -> TV-40

 

6. 표의 숫자 코드 (Significant Digit code)

: 항목의 물리적 수치를 그대로 코드에 적용

ex) 두께x폭x길이가 120x720x1500 인 강판의 코드를 120-720-1500으로 표시

 

7. 합성 코드 (Combined Code)

: 2가지 이상의 코드를 조합하여 코드 생성

ex) 연상 코드와 순차 코드를 합쳐 만드는 항공사의 코드

 

2) 코드 부여 체계

: 이름만으로 개체의 용도와 적용 범위를 알 수 있도록 코드를 부여하는 방식

  • 각 개체에 유일한 코드를 부여하여 개체를 식별하고 추출할 수 있도록 해야한다
  • 코드를 부여하기 전에 코드가 정의되어야 한다
  • 코드 부여 체계는 자릿수, 구분자, 구조 등이 상세히 명시되어야 한다

28. 디자인 패턴

: 모듈이나 모듈 간 인터페이스 등의 세부 구현 설계에서 참조할 수 있는 전형적인 해결 방식이나 예제

디자인 패턴의 대표적 참고서인 Head First Design Patterns

  • 디자인 패턴은 문제 및 배경, 실제 사례, 샘플 코드 등으로 구성
  • 어떤 문제에 대해 새로운 해결 방안을 구상하는 것보다 이미 검증된 디자인 패턴을 적용하는 것이 효율적
  • 한 디자인 패턴에 변형을 가하거나 특정 요구사항을 반영하면 유사한 형태의 다른 패턴으로 변화

 

- 디자인 패턴의 장단점

  • 장점
    • 범용적인 스타일로 구조 파악 용이
    • 설계 및 구현의 생산성 증대
    • 개발 시간 및 비용 절약
    • 개발자 간 원활한 의사소통 가능
    • 설계 변경 요청에 유연한 대처 가능
  • 단점
    • 초기 투자 비용 증가
    • 객체 지향 이외 기반의 애플리케이션에는 부적합

 

1) 생성 패턴 (Creational Pattern)

: 객체의 생성과 관련된 5가지 패턴. 객체의 생성과 참조를 캡슐화 함

 

1. 팩토리 메소드 패턴 (Factory Method)

: 객체의 생성을 위해 인터페이스를 만들고 이 인터페이스를 확장하는 서브클래스가 원하는 객체의 인스턴스를 생성할 수 있도록 하는 방식 (Virtual Constructor 패턴)

팩토리 메소드 패턴의 간단한 기본 구조. Creator 인스턴스를 확장하는 ConcreteCreator가 Product의 생성을 담당한다.

  • 상위 클래스에서 인터페이스만 정의하고 실제 인스턴스 생성은 서브 클래스가 담당

 

2. 추상 팩토리 패턴 (Abstract Factory)

: 연관된 혹은 상호 의존하는 객체의 집합을 생성하기 위해 추상화된 인터페이스를 이용하는 방식

추상 팩토리 패턴의 예시. ConcreteFactory1과 ConcreteFactory2는 서로 다른 Product를 이용하여 인스턴스를 생성한다. ProductA와 ProductB 역시 추상클래스를 이용한다.

  • 연관된 서브클래스를 그룹지어 한번에 교체하는 것이 가능하다.

 

3. 빌더 패턴 (Builder)

: 객체의 속성이 많은 경우 이에 대한 복잡한 생성자 필요 없이 필요한 요소만 조합하여 인스턴스를 생성할 수 있도록 하는 패턴

빌더 패턴을 활용한 코드. 빌더에 필요한 요소를 전달한 후 build()를 실행하여 인스턴스를 만들어낸다.

  • 객체의 생성과 표현을 분리하여 동일한 객체 생성에서도 다른 결과를 만들어 낼 수 있다

 

4. 프로토타입 패턴 (Prototype)

: 인스턴스 생성 시에 원본 객체를 복사하여 생성하는 방법

프로토타입 패턴의 간단한 기본 구조. clone()을 통해 원본 객체를 복사한다.

  • 객체를 직접 생성하는 것이 비용이 큰 경우에 이용한다.

5. 싱글턴 패턴 (Singleton)

: 클래스의 인스턴스가 하나만 생성되도록 하고 이 인스턴스를 어디서든 참조할 수 있도록 하는 방식

싱글턴 패턴을 이용한 클래스의 코드. 생성자를 private으로 설정하여 외부에서는 객체를 생성할 수 없도록 한다.

  • 여러 프로세스가 싱글턴 객체를 참조하는 경우 동시에 여러 개가 생성되지 않도록 동기화해야 한다. 
  • 클래스 내의 인스턴스가 하나뿐임을 보장하므로 불필요한 메모리 낭비를 최소화한다.

 

2) 구조 패턴 (Structural Pattern)

: 클래스나 객체들을 조합하여 더 큰 구조를 만들 수 있게하는 7가지 패턴

 

1. 어댑터 패턴 (Adapter)

: 한 클래스의 인터페이스를 원하는 다른 인터페이스로 변환하는 패턴

어댑터 패턴의 간단한 기본 구조. Adapter는 Target과 Adaptee를 연결한다.

  • 서로 호환성이 없는 인터페이스를 가진 클래스가 함께 동작할 수 있도록 해준다.

 

2. 브리지 패턴 (Bridge)

: 구현부와 추상층을 분리하여 서로 독립적으로 변형, 확장할 수 있도록 하는 패턴

기존의 기능과 구현이 결합되어있던 Message 클래스를 브리지 패턴을 이용하여 Message와 MessageSender로 분리하였다

  • 기능과 구현을 2개의 별도 클래스로 구현한다

 

3. 컴포지트 패턴 (Composite)

: 클라이언트가 단일 객체와 복합 객체를 동일하게 사용할 수 있도록 하는 패턴

컴포지트 패턴의 간단한 기본 구조. Leaf와 Composite 모두 Component를 구현한다.

  • 객체들을 트리 구조로 구성하여 복합 객체 내에 복합 객체가 포함되는 구조를 구현할 수 있다

 

4. 데코레이터 패턴 (Decorator)

: 객체의 결합을 통해 기능을 동적으로 확장할 수 있는 패턴

Component의 형성 시에 원하는 Decorator를 넣어 기능을 확장할 수 있다.

  • 객체에 부가적인 기능을 추가하기 위해 다른 객체를 덧붙이는 방식이다

 

5. 퍼사드 패턴 (Facade)

: 복잡한 서브클래스의 기능들을 통합한 인터페이스를 통해 간편하게 사용할 수 있도록 하는 패턴

퍼사드 패턴을 이용한 세탁기 객체의 간단한 예시. Client는 복잡 세부 과정을 알필요 없이 세탁기를 이용할 수 있다.

  • 서브 클래스들 사이의 통합 인터페이스를 제공하는 Wrapper 객체가 필요하다

 

6. 플라이웨이트 패턴 (Flyweight)

: 인스턴스를 매번 생성하는 것이 아니라 가능한 공유해서 사용할 수 있도록 하는 패턴

플라이웨이트의 간단한 예시. ShapeFactory는 HashMap을 참고하여 인스턴스를 새로 생성할지 있는 것을 사용할지 결정한다.

  • 다량의 유사한 객체를 생성하고 참조해야 할 때 사용한다

 

7. 프록시 패턴 (Proxy)

: 객체에 직접 접근하지 않고 해당 객체의 대리 (Proxy)를 통해 접근할 수 있도록 하는 패턴

프록시 패턴의 간단한 기본 구조. Client는 Proxy를 통해 Realsubject에 간접적으로 접근한다.

  • 프록시는 객체와 클라이언트를 연결하는 인터페이스 역할을 한다
  • 네트워크 연결이나 메모리 내의 대용량 객체에 대한 접근에서 주로 이용한다

3) 행위 패턴 (Behavioral Pattern)

: 클래스나 객체가 상호작용하는 방법이나 책임을 분배하는 방법을 정의하는 11가지 패턴

 

1. 책임 연쇄 패턴 (Chain of Responsibility)

: 요청을 처리하는 객체가 다수 연결되어 한 객체가 처리하지 못하면 처리될 수 있을 때까지 다음 객체로 요청을 전달하는 패턴

책임 연쇄 패턴의 간단한 기본 구조. setNext()로 연결된 ConcreteHandler 들은 요청을 직접 처리하거나 다음 handler에게 넘긴다.

2. 커맨트 패턴 (Command)
: 요청을 객체의 형태로 캡슐화하여 재사용하거나 취소할 수 있도록 저장하거나 로그에 남기는 패턴

커맨드 패턴의 간단한 기본 구조. 커맨드 패턴은 Command, Reciever, Invoker, Client 객체를 이용한다.

  • 요청에 사용되는 명령어들을 추상 클래스와 구체 클래스로 분리하여 단순화한다

 

3. 인터프리터 패턴 (Interpreter)

: 한 언어의 문법 표현을 정의하여 해석할 수 있도록 하는 패턴

인터프리터 패턴의 간단한 기본 구조. 종단 기호와 비종단 기호로 나누어서 포현을 정의한다

  • SQL이나 통신 프로토콜 등의 개발에 이용된다

 

4. 반복자 패턴 (Iterator)

: 서로 다른 구조를 가진 자료 구조에 동일한 인터페이스를 통해 접근할 수 있도록 하는 패턴

반복자 패턴의 간단한 기본 구조. Iterator를 통해 다양한 Aggregate에 대해 동일하게 접근할 수 있다

  • 컬렉션의 구현 방식이나 표현 방법을 노출하지 않고 순차적인 접근이 가능하다.

 

5. 중재자 패턴 (Mediator)

: 수많은 객체 간의 복잡한 상호작용을 캡슐화하여 객체로 정의해 처리하는 패턴

중재자 패턴의 간단한 예시 구조. Mediator는 Colleague 사이의 대화를 중재한다.

  • 객체 간 의존성을 줄여 결합도를 낮출 수 있다
  • 중재자는 객체 간의 통제와 지시의 역할을 한다

 

6. 메멘토 패턴 (Memento)

: 특정 시점에서의 객체 내부 상태를 객체화하여 해당 객체를 이전 상태로 되돌릴 수 있도록 하는 패턴

메멘토 패턴의 간단한 기본 구조와 작동 방식을 나타내는 시퀀스 다이어그램. 상태의 저장과 불러오기가 가능하다.

  • ctrl + z 처럼 되돌리기 기능을 개발할 때 주로 이용한다

 

7. 옵서버 패턴 (Observer)

: 한 객체의 상태가 변하면 이와 연관된 객체들에게 이를 알려 작업을 수행할 수 있도록 하는 패턴

옵저버 패턴을 이용한 간단한 예시. Subject에 register를 한 observer들은 subject객체가 변화하면 notifyAllObservers()를 통해 알림을 받는다.

  • 분산된 시스템 사이에서 이벤트의 publish와 subscribe 기능에서 사용된다

 

8. 상태 패턴 (State)

: 객체의 상태를 캡슐화하여 객체의 상태에 따라 동일한 메서드가 다르게 동작하도록 하는 패턴

상태 패턴을 이용한 간단한 예시. Established/Listen/Closed 상태에 따라 Open(), Close(), Acknowledge()가 다른 방식으로 작동한다

 

9. 전략 패턴 (Strategy)

: 같은 문제를 해결하는 알고리즘을 캡슐화하여 객체로 만들어 필요에 따라 교체할 수 있도록 하는 패턴

전략 패턴의 간단한 기본 구조. Strategy 인터페이스를 확장하는 ConcreteStrategy가 여러가지가 있고 원하는 전략을 선택할 수 있다.

  • 클라이언트는 독립적으로 원하는 알고리즘을 선택하여 사용할 수 있다
  • 클라이언트에 영향을 주지않고 알고리즘을 바꿀수 있다

 

10. 템플릿 메소드 패턴 (Template Method)

: 어떤 작업을 처리하는 전체 구조를 상위 클래스에서 정의하고 서브 클래스에서 세부 처리를 구체화하는 패턴

템플릿 메소드 패턴읜 간단한 기본 구조. ConcreteClass에서 작업의 세부 처리를 구체화한다.

  • 유사한 서브 클래스들을 묶어 공통된 내용을 상위 클래스에서 정의하여 코드의 양을 줄이고 유지보수를 용이하게 한다

 

11. 방문자 패턴 (Visitor)

: 개체의 데이터 구조에서 처리 기능을 분리하여 별도의 클래스로 구현하는 패턴

방문자 패턴의 간단한 기본 구조. visitor 들은 element들을 방문해가며 필요한 작업을 수행한다.

  • 분리된 처리 기능은 각 클래스를 방문하며 수행한다