1️⃣ 소프트웨어 설계
✅ 소프트웨어 설계란?
- 요구사항 분석을 바탕으로 소프트웨어 기능을 설계하는 과정
- 알고리즘과 데이터 구조를 설계하고 문서화
✅ 대표적인 설계 방식
- 절차 지향 설계 (Process Oriented Design)
- 작업 처리 절차 중심 설계
- 컴퓨터의 처리 구조와 유사하여 속도가 빠름
- 유지보수 어려움
2. 객체 지향 설계 (Object Oriented Design)
- 데이터와 절차를 객체로 묶어 설계
- 설계 난이도 높지만 유지보수 및 재사용성이 뛰어남
✅ 설계 방법론
- 상향식(Bottom-up) 설계: 작은 단위의 모듈을 먼저 개발 후 조합
- 하향식(Top-down) 설계: 전체적인 요구사항을 먼저 분석 후 하위 모듈 구현
✅ 소프트웨어 설계 모델
- 데이터 설계 → 정보 분석 후 데이터 구조 변환
- 아키텍처 설계 → 시스템 구성 요소의 관계 정의
- 인터페이스 설계 → 사용자와 시스템의 상호작용 방식 정의
- 절차 설계 → 모듈별 기능을 절차적으로 구성
✅ 소프트웨어 설계 추상화 기법
- 제어 추상화 → 세부 제어 대신 포괄적인 표현 사용
- 과정 추상화 → 전체적인 흐름만 파악하도록 표현
- 자료 추상화 → 데이터의 속성을 대표적인 표현으로 대체
✅ 바람직한 설계 기준
- 요구사항 명세서의 모든 내용을 구현
- 유지보수 시 변경이 용이해야 함
- 기능별 명확한 분리 (독립적인 모듈, 자료구조 표현, 계층적 설계)
2️⃣ 공통 모듈
✅ 공통 모듈이란?
- 여러 기능과 프로그램에서 공통적으로 사용할 수 있는 모듈
- 누구나 쉽게 사용할 수 있도록 공개되어야 하며, 유지보수가 쉬워야 함
- 공유도와 응집도는 높이고, 결합도는 낮추는 것이 핵심
✅ 모듈화란?
- 프로그램을 효율적으로 관리할 수 있도록 시스템을 분해하고 추상화하는 기법
- 모듈화를 통해 성능 향상, 수정 용이, 재사용, 유지보수 용이
✅ 모듈의 개수에 따른 차이
- 모듈 개수가 많을 경우
- 모듈이 작아져 유지보수 편리하지만 통합 비용 증가
2. 모듈 개수가 적을 경우
- 모듈이 커지지만 통합 비용 감소
3️⃣ 소프트웨어 재사용 (Re-Use)
✅ 소프트웨어 재사용이란?
- 이미 개발된 기능을 다시 활용하여 시간과 비용을 절감하는 기법
- 목적 시스템에 맞게 기존 기능을 최적화하여 재사용
✅ 재사용의 범위
- 함수와 객체 재사용 → 클래스나 메서드 단위의 소스 코드 활용
- 컴포넌트 재사용 → 수정 없이 인터페이스를 통해 재사용
- 애플리케이션 재사용 → 공통 기능을 제공하는 애플리케이션 활용
✅ 소프트웨어 재사용 기술
- 생성 중심(Generation Based) → 모듈화를 기반으로 패턴 구성
- 합성 중심(Composition Based) → 블록 조립형 방식으로 구성
4️⃣ 소프트웨어 재공학 (Re-Engineering)
✅ 소프트웨어 재공학이란?
- 기존 시스템을 보완·개선하여 새롭게 구축하는 방법
- 개발 규모가 커질수록 유지보수 중심으로 해결
✅ 소프트웨어 재공학 주요 방법
- 분석(Analysis) → 기존 소프트웨어를 분석하여 개선할 부분 식별
- 재구성(Restructuring) → 기능은 그대로 두고 코드 구조 개선
- 역공학(Reverse Engineering) → 기존 코드를 분석하여 설계 정보 추출
- 이식(Migration) → 기존 시스템을 다른 플랫폼에서도 사용 가능하도록 변환
📌 소프트웨어 유지보수를 극대화하는 개념인 재사용(Re-Use), 역공학(Reverse Engineering), 재공학(Re-Engineering)을 묶어 ‘3R’이라고 부름
4️⃣ 공통 모듈 식별 프로세스
✅ 공통 기능을 분석하고, 표준화하여 중복 없이 효율적으로 관리하는 과정
✅ (1) 단위 업무 기능 분석
- 시스템에서 공통적으로 사용될 기능을 찾는 단계
- 중복되는 기능이 있는지 검토
- 💡 예시: 회원 가입, ID 찾기, 비밀번호 찾기 → "본인 인증"이 공통 기능
✅ (2) 유스케이스 분석
- 유스케이스 다이어그램을 통해 공통 기능을 추출하는 과정
- 각 기능이 <<include>> 관계를 가지는지 검토
✅ (3) 검토 회의 진행
- 팀원들과 공통 기능을 어떻게 적용할지 논의
- 담당자를 지정하여 최종 결정
✅ (4) 상세 기능 명세
- 공통 기능에 대한 설명, 입출력 데이터, 처리 방식 등을 문서화
✅ (5) 식별된 기능 통합
- 각 시스템에서 중복된 공통 기능을 통합
- 단위 시스템 간의 동일한 기능이 발견되면 전체 공통 기능으로 통합
✅ (6) 관리 프로세스 수립
- 공통 기능을 어떻게 관리할지 정의
- 저장소, 데이터 처리 방식, 기능 변경/삭제 절차 마련
5️⃣ 공통 모듈 명세 원칙
✅ 공통 기능을 명확하고 일관되게 정의하여, 오류를 방지하는 과정
원칙
|
설명
|
정확성 (Correctness)
|
해당 기능이 정확하게 필요한지 판단
|
명확성 (Clarity)
|
한 가지 의미로만 해석 가능하도록 명확하게 작성
|
완전성 (Completeness)
|
구현에 필요한 모든 요구사항을 포함
|
일관성 (Consistency)
|
다른 공통 기능과 충돌 없이 일관된 방식 유지
|
추적성 (Traceability)
|
해당 기능이 어느 요구사항에서 나왔는지 식별 가능하도록 작성
|
6️⃣ 모듈의 품질 개선
✅ 모듈의 품질을 높이기 위해 응집도를 높이고, 결합도를 낮추는 것이 중요
✅ (1) 모듈 응집도(Cohesion)란?
- 모듈 내부 요소들이 얼마나 밀접하게 관련되어 있는지 나타내는 정도
- 응집도가 높을수록 모듈이 독립적으로 동작할 수 있음
✅ 기능적 응집도가 가장 높음 → 하나의 기능을 수행하는 모듈로 구성됨
✔️ 좋은 설계 원칙:
- 모듈은 하나의 목적을 가져야 함
- 관련 없는 기능들이 한 모듈에 섞이지 않도록 설계
7️⃣ 모듈 응집도(Cohesion) 종류
✅ 모듈 내부 요소들이 얼마나 밀접하게 관련되어 있는지를 나타내는 정도
✅ 응집도가 높을수록 좋은 설계 (독립적, 재사용 가능, 유지보수 쉬움)
1️⃣ 기능적(Functional) 응집도 ✅ (가장 좋은 구조!)
✔ 하나의 문제 해결을 위해 모든 요소가 협력하는 경우
✔ 대부분의 모듈이 이 구조를 목표로 설계됨
2️⃣ 순차적(Sequential) 응집도
✔ 한 기능의 출력이 다음 기능의 입력으로 사용되는 경우
3️⃣ 통신적(Communication) 응집도
✔ 같은 데이터를 공유하는 여러 기능이 함께 수행되는 경우
📌 차이점:
- 순차적 응집도는 결과를 다음 기능의 입력으로 사용
- 통신적 응집도는 같은 데이터를 기반으로 여러 기능 수행
4️⃣ 절차적(Procedural) 응집도
✔ 여러 기능이 특정 순서대로 실행되는 경우
5️⃣ 시간적(Temporal) 응집도
✔ 기능 간 직접적인 연관성은 없지만 같은 시기에 실행되는 경우
6️⃣ 논리적(Logical) 응집도
✔ 비슷한 성격의 기능들을 한 모듈에서 수행하는 경우
7️⃣ 우연적(Coincidental) 응집도 ❌ (가장 나쁜 구조)
✔ 관련 없는 기능들이 한 모듈에 섞여 있는 경우
❌ 유지보수 어렵고, 재사용 불가능
8️⃣ 모듈 결합도(Coupling) 종류
✅ 모듈과 모듈 간의 의존성이 얼마나 강한지를 나타냄
✅ 결합도가 낮을수록 좋은 설계 (독립성 증가, 유지보수 쉬움)
1️⃣ 자료(Data) 결합도 ✅ (가장 좋은 구조!)
✔ 모듈 간 필요한 데이터만 전달 (인수, 매개변수 사용)
2️⃣ 스탬프(Stamp) 결합도
✔ 관련 있는 여러 데이터를 함께 전달하는 경우
📌 차이점:
- 자료 결합도는 필요한 데이터만 전달
- 스탬프 결합도는 불필요한 데이터까지 함께 전달
3️⃣ 제어(Control) 결합도
✔ 어떤 기능을 수행할지 결정하는 데이터를 함께 전달하는 경우
5️⃣ 외부(External) 결합도
✔ 인수를 전달하지 않고, 특정 모듈이 다른 모듈의 내부 데이터를 참조
✔ 외부 시스템(DB, API, 환경 변수 등)에 의존함
🚨 문제점:
- 외부 환경에 영향을 받으므로 유지보수가 어려움
6️⃣ 공유(Common) 결합도
✔ 모듈들이 전역 변수(Global Variable)를 공유하여 데이터 처리
✔ 여러 모듈이 동일한 변수를 참조하면 예측하기 어려운 오류 발생 가능
🚨 문제점:
- 서로 관련 없는 모듈들도 전역 변수에 접근 가능 → 오류 발생 위험 높음
7️⃣ 내용(Content) 결합도 ❌ (가장 나쁜 결합도, 절대 피해야 함)
✔ 한 모듈이 다른 모듈의 내부 기능(변수, 메서드 등)을 직접 접근하여 사용
✔ 즉, 하나의 모듈이 다른 모듈의 세부 구현을 알아야 하는 경우
🚨 문제점:
- 이 모듈이 변경되면, 다른 모듈들도 모두 영향을 받음 → 유지보수 최악
🔟 복잡도 (Complexity)
✅ 모듈 간의 관계를 분석하여 효율적인 구조를 설계하는 과정
✅ 공유도(Fan-In)와 제어도(Fan-Out)를 통해 분석 가능
1️⃣ 공유도(Fan-In)
✔ 자신을 호출(공유)하는 모듈의 개수
✔ 공유도가 높을수록 재사용성이 높아 설계가 잘된 것
✔ 하지만 공유도가 너무 높으면, 단일 실패 지점(Single Point of Failure) 발생 위험
📌 공유도가 높으면?
- A 모듈이 재사용성이 뛰어나지만, A에 문제가 생기면 B, C, D 모두 영향을 받음
2️⃣ 제어도(Fan-Out)
✔ 자신이 호출(제어)하는 모듈의 개수
✔ 제어도가 높을수록 복잡도가 증가하고 유지보수가 어려움
📌 제어도가 너무 높으면?
- A가 너무 많은 모듈을 직접 제어하면 유지보수가 어려워짐
- 해결 방법: 기능을 분리하여 의존성을 줄이기
총정리
1️⃣ 소프트웨어 설계
✅ 소프트웨어 설계란?
- 요구사항을 분석하여 알고리즘과 데이터 구조를 체계적으로 설계하는 과정
✅ 설계 방식
- 절차 지향 → 속도 빠르지만 유지보수 어려움
- 객체 지향 → 유지보수 및 재사용성 우수
✅ 설계 방법론
- 상향식(Bottom-up) → 작은 모듈부터 조합
- 하향식(Top-down) → 전체 분석 후 세부 구현
✅ 바람직한 설계 기준
- 유지보수 용이, 독립적인 모듈, 명확한 자료구조 표현
2️⃣ 공통 모듈
✅ 공통 모듈이란?
- 여러 기능에서 공통적으로 사용되는 모듈
- 응집도 높이고, 결합도 낮추는 것이 핵심
✅ 모듈화 필요성
- 유지보수 및 재사용성 증가
✅ 모듈 개수 영향
- 많으면 유지보수 편리하지만 통합 비용 증가
- 적으면 유지보수 어렵지만 통합 비용 감소
3️⃣ 소프트웨어 재사용 (Re-Use)
✅ 재사용의 범위
- 함수/객체 단위 → 클래스, 메서드 활용
- 컴포넌트 단위 → 인터페이스 통해 재사용
- 애플리케이션 단위 → 공통 기능 제공
✅ 재사용 기법
- 생성 중심 → 패턴 기반 모듈화
- 합성 중심 → 블록 조립형 구성
4️⃣ 소프트웨어 재공학 (Re-Engineering)
✅ 기존 시스템을 보완 및 개선하는 기법
✅ 주요 방법
- 분석(Analysis) → 기존 시스템 개선할 부분 식별
- 재구성(Restructuring) → 코드 구조 개선
- 역공학(Reverse Engineering) → 기존 코드에서 설계 정보 추출
- 이식(Migration) → 다른 플랫폼에서도 사용 가능하도록 변환
📌 재사용(Re-Use) + 역공학(Reverse Engineering) + 재공학(Re-Engineering) = 3R
5️⃣ 공통 모듈 식별 프로세스
✅ 공통 기능을 찾고 표준화하여 중복을 제거하는 과정
1️⃣ 업무 기능 분석 → 중복되는 기능 찾기
2️⃣ 유스케이스 분석 → 기능 간 <<include>> 관계 검토
3️⃣ 검토 회의 → 적용 가능 여부 논의
4️⃣ 상세 기능 명세 → 입출력 데이터, 처리 방식 문서화
5️⃣ 기능 통합 → 중복된 기능을 하나의 모듈로 통합
6️⃣ 관리 프로세스 수립 → 변경 및 유지보수 절차 정의
6️⃣ 공통 모듈 명세 원칙
✅ 공통 기능을 명확하게 정의하여 오류 방지
- 정확성(Correctness) → 기능이 필요한지 판단
- 명확성(Clarity) → 한 가지 의미로만 해석 가능
- 완전성(Completeness) → 요구사항 모두 포함
- 일관성(Consistency) → 다른 기능과 충돌 방지
- 추적성(Traceability) → 요구사항 출처와 관계 명확히 식별
7️⃣ 모듈 품질 개선 (응집도 & 결합도 최적화)
✅ 응집도 높이고, 결합도 낮추는 것이 핵심
✅ 모듈 응집도 (높을수록 좋음)
1️⃣ 기능적 응집도 → 하나의 기능만 수행 ✅ (최고)
2️⃣ 순차적 응집도 → 이전 기능의 출력이 다음 기능의 입력
3️⃣ 통신적 응집도 → 같은 데이터를 공유
4️⃣ 절차적 응집도 → 특정 순서대로 실행
5️⃣ 시간적 응집도 → 같은 시점에 실행
6️⃣ 논리적 응집도 → 비슷한 기능을 묶음
7️⃣ 우연적 응집도 → 관련 없는 기능 섞임 ❌ (최악)
✅ 모듈 결합도 (낮을수록 좋음)
1️⃣ 자료 결합도 → 필요한 데이터만 전달 ✅ (최고)
2️⃣ 스탬프 결합도 → 데이터 구조 전체 전달
3️⃣ 제어 결합도 → 실행 흐름을 제어 데이터로 전달
4️⃣ 외부 결합도 → 외부 API, DB에 의존
5️⃣ 공통 결합도 → 전역 변수 공유 ❌
6️⃣ 내용 결합도 → 직접 다른 모듈 내부에 접근 ❌ (최악)
8️⃣ 복잡도 분석 (공유도 & 제어도 최적화)
✅ 공유도(Fan-In)는 높게, 제어도(Fan-Out)는 낮게 유지해야 함
✅ 공유도(Fan-In) → 자신을 호출하는 모듈 개수
- 높을수록 재사용성 높음
- 하지만 너무 높으면 단일 실패 지점(SPoF) 위험 증가
✅ 제어도(Fan-Out) → 자신이 호출하는 모듈 개수
- 높을수록 의존성이 커져 유지보수 어려움
- 해결책: 기능을 분리하여 모듈 독립성 증가
🎯 최종 핵심 요약
✔ 소프트웨어 설계 → 기능을 체계적으로 설계하는 과정
✔ 공통 모듈 → 중복 제거, 유지보수 및 재사용성 향상
✔ 재사용(3R) → 기존 기능을 효율적으로 활용 (Re-Use, Re-Engineering, Reverse Engineering)
✔ 응집도 높이기 → 기능별 독립성 유지 (기능적 응집도 최상)
✔ 결합도 낮추기 → 모듈 간 의존성 줄이기 (자료 결합도 최상)
✔ 공유도(Fan-In)는 높게 → 재사용성 향상
✔ 제어도(Fan-Out)는 낮게 → 복잡성 감소