View
Section 20. 소프트웨어 아키텍처
소프트웨어 아키텍처는 소프트웨어의 골격이 되는 기본 구조이자,
소프트웨어를 구성하는 요소들 간의 관계를 표현하는 시스템의 구조 또는 구조체이다.
- 비기능적 요구사항으로 나타난 제약을 반영하고, 기능적 요구사항을 구현하는 방법을 찾는 해결 과정
* 기능적 요구사항 : 시스템이 갖춰야할 필수적인 기능에 대한 요구항목
비기능적 요구사항 : 그 외의 품질이나 제약사항에 관한 것
- 설계 기본 원리 : 모듈화, 추상화, 단계적 분해, 정보은닉
1. 모듈화
소프트웨어의 성능을 향상시키거나 시스템의 수정 및 재사용, 유지 관리 등이 용이하도록 시스템의 기능들을 모듈 단위로 나누는 것
* 모듈 : 전체 프로그램의 기능 중에서 특정 기능을 처리할 수 있는 소스 코드
2. 추상화(Abstaraction)
문제의 전체적이고 포괄적인 개념을 설계한 후 차례로 세분화하여 구체화시켜 나가는 것 (불필요한 부분 생략)
- 과정 추상화 : 자세한 수행 과정을 정의하지 않고 전반적인 흐름만 파악할 수 있게 설계하는 방법
- 데이터 추상화 : 데이터의 세부적인 속성이나 용도를 정의하지 않고, 데이터 구조를 대표할 수 있는 표현으로 대체하는 방법
- 제어 추상화 : 이벤트 발생의 정확한 절차나 방법을 정의하지 않고, 대표할 수 있는 표현으로 대체하는 방법
3. 단계적 분해(Stepwise Refinement)
문제를 상위의 중요 개념으로부터 하위의 개념으로 구체화시키는 분할 기법
4. 정보 은닉(Information Hiding)
한 모듈 내부에 포함된 절차와 자료들의 정보가 감추어져 다른 모듈이 접근하거나 변경하지 못하도록 하는 기법
5. 소프트웨어 아키텍처의 품질 속성
- 시스템 측면
품질 속성 | 내용 |
성능 | 사용자의 요청과 같은 이벤트가 발생했을 때, 이를 적절하고 빠르게 처리하는 것 |
보안 | 허용되지 않은 접근을 막고, 허용된 접근에는 적절한 서비스를 제공하는 것 |
가용성 | 장애 없이 정상적으로 서비스를 제공하는 것 |
기능성 | 사용자가 요구한 기능을 만족스럽게 구현하는 것 |
사용성 | 사용자가 소프트웨어를 사용하는데 헤매지 않도록 명확하고 편리하게 구현하는 것 |
변경 용이성 | 소프트웨어가 처음 설계 목표와 다른 하드웨어나 플랫폼에서도 동작할 수 있도록 구현하는 것 |
확장성 | 시스템의 용량, 처리능력 등을 확장시켰을 때 이를 효과적으로 활용할 수 있도록 구현하는 것 |
테스트 용이성 | |
배치성 | |
안정성 |
- 비즈니스 측면
- 아키텍처 측면
6. 소프트웨어 아키텍처의 설계 과정
- 설계 목표 설정
- 시스템 타입 결정 : 대화형 시스템/ 이벤트 중심 시스템/ 변환형 시스템/ 객체 영속형 시스템
- 아키텍처 패텅 적용
- 서브시스템 구체화
- 검토
Section 21. 아키텍처 패턴
아키텍처를 설계할 때 참조할 수 있는 전형적인 해결 방식 또는 예제
- 소프트웨어 시스템의 구조를 구성하기 위한 기본적인 윤곽을 제시
- 서브시스템들과 그 역할이 정의되어 있으며, 서브시스템 사이의 관계와 여러 규칙등이 포함
1. 레이어 패턴
시스템을 계층(Layer)으로 구분하여 구성하는 방법
- 각각의 서브시스템들이 계층 구조를 이루며, 상위 계층은 하위 계층에 대한 서비스 제공자가 되고, 하위 계층은 상위 계층의 클라이언트가 된다.
- 서로 마주보는 두 개의 계층 사이에서만 상호작용이 이루어지며, 따라서 변경 작업이 용이하다.
- 특정 계층만을 교체해 시스템을 개선하는 것이 가능
- OSI 참조 모델 : 국제표준화기구에서 네트워크 프로토콜을 계층별로 구분한 모델
2. 클라이언트-서버 패턴
하나의 서버 컴포넌트와 다수의 클라이언트 컴포넌트로 구성되는 패턴
* 컴포넌트 : 독립적인 업무 또는 기능을 수행하는 실행코드 기반으로 작성된 모듈
- 사용자는 클라이언트와만 의사소통 ( 사용자 <--클라이언트--> 서버 )
- 서버는 클라이언트의 요청에 대비해 항상 대기 상태를 유지
- 클라이언트와 서버는 서로 독립적
3. 파이프-필터 패턴
데이터 스트림 절차의 각 단계를 필터 컴포넌트로 캡슐화하여 파이프를 통해 데이터를 전송하는 패턴
* 데이터 스트림 : 데이터가 송수신되거나 처리되는 일련의 연속적인 흐름
- 앞의 컴포넌트에서 처리한 결과를 파이프를 통해서 전송하면 뒤의 컴포넌트에서 결과를 받아 다음 작업을 수행
- 재사용성이 좋고, 추가가 쉬워 확장이 용이
- 재배치하여 다양한 파이프라인을 구축하는 것이 가능
- 데이터 변환, 버퍼링, 동기화 등에 주로 사용
- UNIX의 쉘(Shell)
4. 모델-뷰-컨트롤러 패턴
서브시스템을 3개의 부분으로 구조화하는 패턴
- 각 부분은 별도의 컴포넌트로 분리되어 있으므로 서로 영향을 받지 않고 개별 작업을 수행할 수 있다.
- 한 개의 모델에 대해 여러 개의 뷰를 필요로 하는 대화형 애플리케이션(사용자의 요구가 발생하면 시스템이 이를 처리하고 반응하는 소프트웨어)에 적합
- 모델 : 서브시스템의 핵심 기능과 데이터를 보관
- 뷰 : 사용자에게 정보를 표시
- 컨트롤러 : 사용자로부터 받은 입력을 처리
5. 기타 패턴
마스터-슬레이브 패턴 | ![]() |
브로커 패턴 | ![]() |
피어-투-피어 패턴 | ![]() |
이벤트-버스 패턴 | ![]() |
블랙보드 패턴 | ![]() |
인터프리터 패턴 | ![]() |
Section22. 객체지향(Object-Oriented)
현실 세계의 개체(Entity)를 기계의 부품처럼 하나의 객체(Object)로 만들어 기계적인 부품들을 조립하여 제품을 만들 듯이 소프트웨어를 개발할 때에도 객체들을 조립해서 작성할 수 있는 기법
객체지향의 주요 구성 요소
1. 객체 : 데이터와 데이터를 처리하는 함수를 묶어 놓은(캡슐화한) 하나의 소프트웨어 모듈
데이터 | 객체가 가지고 있는 정보로 속성이나 상태,분류 등을 나타낸다. |
속성(Attribute), 상태, 변수, 상수, 자료 구조라고도 한다. | |
함수 | 객체가 수행하는 기능으로 객체가 갖는 데이터(속성,상태)를 처리하는 알고리즘 |
객체의 상태를 참조하거나 변경하는 수단이 되는 것으로 메소드, 서비스, 동작, 연산이라고도 한다. |
- 객체는 독립적을 식별 가능한 이름을 가지고 있다.
- 객체가 가질 수 있는 조건을 상태(State)라고 한다.
- 객체와 객체는 상호 연관성에 의한 관계가 형성된다.
- 객체가 반응할 수 있는 메시지의 집합을 행위라고 하며, 객체는 행위의 특징을 나타낼 수 있다.
- 객체는 일정한 기억장소를 가지고 있다.
- 객체의 메소드는 다른 객체로부터 메시지를 받았을 때 정해진 기능을 수행한다.
* 구조적 기법 : 프로시저에 근간을 두고 하나의 커다란 작업을 여러 개의 작은 작업으로 분할하고, 분할된 각각의 소작업을 수행하는 모듈을 작성한 다음 이들을 한곳에 모아 큰 작업을 수행하는 하나의 완벽한 프로그램으로 작성하는 기법
* 구조적 기법의 문제점
- 유지보수는 고려하지 않고 개발 공정에만 너무 집중한다.
- 개발이 시작된 이후 추가적인 요구사항에 대응하기 어렵다.
- 재사용이 어렵다.
2. 클래스 : 공통된 속성과 연산(행위)을 갖는 객체의 집합으로 객체의 일반적인 타입을 의미
- 각각의 객체들이 갖는 속성과 연산을 정의하고 있는 틀
- 클래스에 속한 각각의 객체를 인스턴스(Instance)라 한다.
- 클래스로부터 새로운 객체를 생성하는 것을 인스턴스화라고 한다.
- 슈퍼 클래스는 특정 클래스의 상위(부모) 클래스이고, 서브 클래스는 특정 클래스의 하위(자식) 클래스를 의미한다.
3. 캡슐화 : 데이터(속성)와 데이터를 처리하는 함수를 하나로 묶는 것을 의미
- 캡슐화된 객체는 인터페이스를 제외한 세부 내용이 은폐(정보 은닉)되어 외부에서의 접근이 제한적이기 때문에 외부 모듈의 변경으로 인한 파급 효과가 적다.
- 캡슐화된 객체는 객체 내의 응집도는 높아지고, 객체 간의 결합도는 낮아진다.
- 캡슐화된 객체들은 재사용이 용이하다.
4. 상속 : 이미 정의된 상위 클래스(부모 클래스)의 모든 속성과 연산을 하위 클래스(자식 클래스)가 물려받는 것이다.
- 상속을 이용하면 하위 클래스는 상위 클래스의 모든 속성과 연산을 자신의 클래스내에서 다시 정의하지 않고서도 즉시 자신의 속성으로 사용할 수 있다.
- 하위 클래스는 상위 클래스로부터 상속받은 속성과 연산 외에 새로운 속성과 연산을 첨가하여 사용할 수 있다.
- 소프트웨어의 재사용을 높인다.
- 다중 상속(Multiple Inheritance) : 한개의 클래스가 두 개 이상의 상위 클래스로부터 속성과 연산을 상속받는 것
5. 다형성(Polymorphism) : 메시지에 의해 객체(클래스)가 연산을 수행하게 될 때 하나의 메시지에 대해 각각의 객체(클래스)가 가지고 있는 고유한 방법(특성)으로 응답할 수 있는 능력을 의미
- 하나의 메시지에 대해 여러 가지 형태의 응답이 있다는 것을 의미
- 객체(클래스)들은 동일한 메소드명을 사용하며 같은 의미의 응답을 한다.
- 응용 프로그램 상에서 하나의 함수나 연산자가 두 개 이상의 서로 다른 클래스의 인스턴스들을 같은 클래스에 속한 인스턴스처럼 수행할 수 있도록 하는 것 (ex. + 연산자는 숫자 클래스에서는 덧셈, 문자 클래스에서는 문자열의 연결 기능으로 사용된다.)
Section 23. 모듈
모듈은 모듈화를 통해 분리된 시스템의 각 기능들로,
서브루틴, 서브시스템, 소프트웨어 내의 프로그램, 작업 단위 등과 같은 의미로 사용
* 모듈화 : 소프트웨어의 성능을 향상시키거나 시스템의 수정 및 재사용, 유지 관리 등이 용이하도록 시스템의 기능들을 모듈 단위로 분해하는 것을 의미
* 루틴 : 기능을 가진 명령들의 모임
* 메인 루틴 : 프로그램 실행의 큰 줄기가 되는 것
* 서브 루틴 : 메인 루틴에 의해 필요할 때 마다 호출되는 루틴
- 모듈은 단독으로 컴파일이 가능하며, 재사용할 수 있다.
- 모듈의 독립성은 결합도와 응집도에 의해 측정되며,
- 독립성을 높이려면 모듈의 결합도는 약하게, 응집도는 강하게, 모듈의 크기는 작게 만들어야 한다.
1. 결합도(Coupling) : 모듈 간에 상호 의존하는 정도 또는 두 모듈 사이의 연관관계를 의미
- 결합도가 약할수록 품질이 높고, 강할수록 품질이 낮다.
- 결합도가 강하면 시스템 구형 및 유지보수 작업이 어렵다.
- 결합도의 종류
자료 결합도 | ![]() |
스탬프(검인) 결합도 | ![]() |
제어 결합도 | ![]() |
외부 결합도 | ![]() |
공통(공유) 결합도 | ![]() |
내용 결합도 | ![]() |
2. 응집도(Cohesion) : 정보 은닉 개념을 확장한 것으로, 명령어나 호출문 등 모듈의 내부 요소들의 서로 관련되어 있는 정도, 즉 모듈이 독립적인 기능으로 정의되어 있는 정도를 의미 (cf. 방의 물건을 용도나 종류에 따라 상자에 정리)
- 응집도가 강할수록 품질이 높고, 약할수록 품질이 낮다.
- 응집도의 종류
기능적 응집도 | 모듈 내부의 모든 기능 요소들이 단일 문제와 연관되어 수행될 경우의 응집도 |
순차적 응집도 | 모듈 내 하나의 활동으로부터 나온 출력 데이터를 그 다음 활동의 입력 데이터로 사용할 경우의 응집도 |
교환(통신)적 응집도 | 동일한 입력과 출력을 사용하여 서로 다른 기능을 수행하는 구성 요소들이 모였을 경우의 응집도 |
절차적 응집도 | 모듈이 다수의 관련 기능을 가질 때 모듈 안의 구성 요소들이 그 기능을 순차적으로 수행할 경우의 응집도 |
시간적 응집도 | 특정 시간에 처리되는 몇 개의 기능을 모아 하나의 모듈로 작성할 경우의 응집도 |
논리적 응집도 | 유사한 성격을 갖거나 특정 형태로 분류되는 처리 요소들로 하나의 모듈이 형성되는 경우의 응집도 |
우연적 응집도 | 모듈 내부의 각 구성 요소들이 서로 관련 없는 요소로만 구성된 경우의 응집도 |
3. 팬인(Fan-In) / 팬아웃
3.1 팬인 : 어떤 모듈에 제어(호출)하는 모듈의 수
3.2 팬아웃 : 어떤 모듈에 의해 제어(호출)되는 모듈의 수
- 팬인과 팬아웃을 분석하여 시스템의 복잡도를 알 수 있다.
- 팬인이 높다는 것은 재사용 측면에서 설계가 잘 되어있다고 볼 수 있으나, 단일 장애점이 발생할 수 있다.
- 팬아웃이 높은 경우 불필요하게 다른 모듈을 호출하고 있는지 검토하고, 단순화시킬 수 있는지 여부에 대한 검토가 필요하다.
- 시스템의 복잡도를 최적화하려면 팬인은 높게, 팬아웃은 낮게 설계해야 한다.
Section 24. 공통 모듈 : 여러 프로그램에서 공통적으로 사용할 수 있는 모듈
공통 모듈을 구현할 때는 다른 개발자들이 해당 기능을 명확히 이해할 수 있도록 다음의 명세 기법을 준수해야 한다.
정확성(Correctness) | 시스템 구현 시 해당 기능이 필요하다는 것을 알 수 있도록 정확히 작성한다. |
명확성(Clarity) | 해당 기능을 이해할 때 중의적으로 해석되지 않도록 명확하게 작성한다. |
완전성(Completeness) | 시스템 구현을 위해 필요한 모든 것을 기술한다. |
일관성(Consistency) | 공통 기능들 간 상호 충돌이 발생하지 않도록 작성한다. |
추적성(Traceability) | 기능에 대한 요구사항의 출처, 관련 시스템 등의 관계를 파악할 수 있도록 작성한다. |
1. 재사용 : 비용과 개발 시간을 절약하기 위해 이미 개발된 기능들을 파악하고 재구성하여 새로운 시스템 또는 기능 개발에 사용하기 적합하도록 최적화 시키는 작업
- 재사용되는 대상은 외부 모듈과의 결합도는 낮고, 응집도는 높아야 한다.
- 재사용 규모에 따른 분류
함수와 객체 | 클래스나 메소드 단위의 소스 코드를 재사용한다. |
컴포넌트 | 컴포넌트자체에 대한 수정 없이 인터페이스를 통해 통신하는 방식으로 재사용한다. |
애플리케이션 | 공통된 기능들을 제공하는 애플리케이션을 공유하는 방식으로 재사용한다. |
* 함수=메소드 : 객체의 데이터를 처리하는 알고리즘
객체 : 데이터와 함수를 캡슐화한 소프트웨어 모듈
클래스 : 객체를 정의하는 틀
컴포넌트 : 하나 이상의 클래스로 작성되는 실행코드 기반의 모듈
애플리케이션 : 어떠한 목적을 갖고 개발된 소프트웨어
2. 효과적인 모듈 설계 방안
모듈의 제어 영역안에서 그 모듈의 영향 영역을 유지시킨다.
- 모듈의 제어 영역 : 프로그램의 계층 구조 내에서 어떤 특정 모듈이 제어하는 하위 모듈
- 모듈의 영향 영역 : 특정 모듈이 다른 모듈들에게 미치게 되는 영향의 범위
Section 25. 코드
컴퓨터를 이용하여 자료를 처리하는 과정에서 분류,조합 및 집계를 용이하게 하고, 특정 자료의 추출을 쉽게 하기 위해서 사용하는 기호
1. 코드의 주요 기능
식별 기능 | 데이터의 간의 성격에 따라 구분이 가능하다 |
분류 기능 | 특정 기준이나 동일한 유형에 해당하는 데이터를 그룹화 할 수 있다. |
배열 기능 | 의미를 부여하여 나열할 수 있다. |
2. 코드의 종류
순차 코드 (Sequence Code) | 자료의 발생 순서, 크기 순서 등 일정 기준에 따라서 최초의 자료부터 차례로 일련번호를 부여하는 방법으로 순서 코드 또는 일련번호 코드라고도 한다. (ex. 1,2,3,4...) |
블록 코드 (Block Code) | 코드화 대상 항목 중에서 공통성이 있는 것끼리 블록으로 구분하고, 각 블록 내에서 일련번호를 부여하는 방법으로 구분 코드라고도 한다. (ex.1001~1100 : 총무부, 1101~1200 : 영업부) |
10진 코드 (Decimal Code) | 코드화 대상 항목을 0~9까지 10진 분할하고, 다시 그 각각에 대하여 10진 분할하는 방법을 필요한 만큼 반복하는 방법으로, 도서 분류식 코드라고도 한다. (ex. 1000 : 공학, 1100 : 소프트웨어 공학, 1110 : 소프트웨어 설계) |
그룹 분류 코드 (Group Classification Code) | 코드화 대상 항목을 일정 기준에 따라 대분류, 중분류, 소분류 등으로 구분하고, 각 그룹 안에서 일련번호를 부여하는 방법이다. (ex. 1-01-001 : 본사-총무부-인사계, 2-01-001 : 지사-총무부-인사계) |
연상 코드 (Mnemonic Code) | 코드화 대상 항목의 명칭이나 약호와 관계있는 숫자나 문자, 기호를 이용하여 코드를 부여하는 방법 (ex.TV-40 : 40인치 TV, L-15-220 : 15W 220V의 램프) |
표의 숫자 코드 (Significant Digit Code) | 코드화 대상 항목의 성질, 즉 길이,넓이,부피,지름,높이 등의 물리적 수치를 그대로 코드에 적용시키는 방법으로 유효 숫자 코드라고도 한다. (ex. 120-720-1500 : 두께x폭x길이가 120x720x1500인 강판) |
합성 코드 (Combined Code) | 필요한 기능을 하나의 코드로 수행하기 어려운 경우 2개 이상의 코드를 조합하여 만드는 방법이다. (ex.연상코드 + 순차코드 KE-711 : 대한항공 711기, AC-253 : 에어캐나다 253기) |
3. 코드 부여 체계
이름만으로 개체의 용도와 적용 범위를 알 수 있도록 코드를 부여하는 방식
Section 26. 디자인 패턴
각 모듈의 세분화된 역할이나 모듈들 간의 인터페이스와 같은 코드를 작성하는 수준의 세부적인 구현 방안을 설계할 때 참조할 수 있는 전형적인 해결 방식 또는 예제
아키텍처 패턴 vs. 디자인 패턴
- 아키텍처 패턴은 디자인 패턴보다 상위 수준의 설계에 사용된다.
- 아키텍처 패턴이 전체 시스템의 구조를 설계하기 위한 참조 모델이라면,
- 디자인 패턴은 서브시스템에 속하는 컴포넌트들과 그 관계를 설계하기 위한 참조 모델이다.
1. 생성 패턴 : 객체의 생성과 참조 과정을 캡슐화하여 객체가 생성되거나 변경되어도 프로그램의 구조에 영향을 크게 받지 않도록 하여 프로그램에 유연성을 더해준다.
추상 팩토리 (Abstract Factory) | ![]() |
빌더 | ![]() |
팩토리 메소드 | ![]() |
프로토타입 | ![]() |
싱글톤 | ![]() |
2. 구조 패턴 : 클래스나 객체들을 조합하여 더 큰 구조로 만들 수 있게 해주는 패턴
- 구조가 복잡한 시스템을 개발하기 쉽게 도와준다.
어댑터 - 변압기 | ![]() |
브리지 다리 | ![]() |
컴포지트 - 합성 | ![]() |
데코레이터 -장식 | ![]() |
퍼싸드- 리모컨 | ![]() |
플라이웨이트 - 가볍게 | ![]() |
프록시(Proxy) - 대리 | ![]() |
3. 행위 패턴 : 클래스나 객체들이 서로 상호작용하는 방법이나 책임 분배 방법을 정의하는 패턴
- 하나의 객체로 수행할 수 없는 작업을 여러 객체로 분배하면서 결합도를 최소화 할 수 있도록 도와준다.
책임 연쇄 (Chain of Responsibility) - 물레방아 | ![]() |
커맨드(Command) - 명령어 | ![]() |
인터프리터(Interpreter) - 언어 번역가 | ![]() |
반복자(lterator) | ![]() |
중재자(Mediator) - 인터넷사이트 | ![]() |
메멘토 - 기억 속의 그때로 돌아가는 것 | ![]() |
옵서버 - 지켜보고 알려주는 것 | ![]() |
상태(State) | ![]() |
전략(Strategy) | ![]() |
템플릿 메소드 - 방법 | ![]() |
방문자 | ![]() |