- 작성일
CH5. 소프트웨어 설계 원리
- Authors

- Name
- seren-wib
Contents
5. 소프트웨어 설계 원리
5.1 분할-정복 접근 방식
분할-정복: 큰 문제를 바로 풀 수 있을 만큼 작게 쪼개서 풀고 다시 합치는 방식 (예: 합병 정렬)
- 절차
- 분해(Divide): 더 못 나눌 때까지 하위 문제로 재귀적으로 쪼갬
- 정복(Conquer): 쪼갠 하위 문제를 재귀로 하나씩 해결
- 결합(Combine): 하위 문제 답을 합쳐 원래 문제의 답을 만듦
5.2 모듈화
모듈화: 문제를 표준 인터페이스를 가진 독립 모듈로 나누고, 재사용 가능한 모듈을 조합해 전체를 해결하는 방식 (예: 부품 조립해서 완성품 만드는 하드웨어)
- 기능 하나짜리 모듈은 한 번만 만들고 계속 재사용
- 모듈: 독립적으로 만들고 유지보수할 수 있어 다른 시스템에서도 재사용되는 코드 조각
- 모듈식 프로그래밍: 프로그램 기능을 독립적이고 상호 교환 가능한 모듈로 분리하는 설계 기법
- 분할정복과 차이: 쪼개는 건 같음, 모듈화는 쪼갠 조각에 인터페이스·독립성·재사용이 붙음
- 모듈의 의미
- 다른 모듈과 최대한 독립적
- 다른 시스템에서 재사용, 시스템 안에서 상호 교환 가능
- 시스템 코드의 한 부분이자 기능 (구조 단위)
- 기본 원칙
- 잘 된 모듈화: 일부를 바꿔도 다른 부분에 영향 적음
- 응집력은 높게, 결합(커플링)은 느슨하게
- 구조적(절차적)·객체지향 프로그래밍과 밀접, 1960년대쯤 시작
- 장점
- 시스템 이해가 쉬움
- 유지관리가 쉬움
- 재사용: 만든 모듈은 다시 안 짜도 됨
5.3 추상화
추상화(컴퓨터과학): 복잡한 자료·모듈·시스템에서 핵심 개념이나 기능만 추려 간단하게 표현하는 방법 (예: 항공사진 → 도로·건물만 남긴 지도)
- 추상화하는 방법
- 일반화: 공통점은 취하고 차이점은 버림 (학부생·대학원생 → 학생)
- 세부 사항 제거: 중요한 부분만 남기고 불필요한 디테일 삭제
- 데이터: 현실 세계 사물을 문자·숫자·소리·영상·비디오·텍스트로 나타낸 값
- 데이터 종류
- 정량적(수치) 데이터: 직접 측정되는 물리적인 값 (온도, 가격, 매출액)
- 정성적(범주형) 데이터: 숫자로 써도 물리값이 아닌 논리적인 값, 명목형·순서형 (성별, 혈액형, 성적 등급)
- 추상화 대상
- 운영 데이터: 조직 운영·관리에 꼭 필요한 데이터, 이것만 추상화
- 추상화 대상: 문제 해결에 필요한 데이터 집합
- 비운영 데이터: 나머지 전부, 무시해도 됨
- 운영/비운영 구분은 시스템 목적에 따라 상대적 (학사관리면 학생·성적, 시설물관리면 도로·건물)
- 운영 데이터는 클래스가 됨: 학생 →
Student { id, name, address, mobile, major }, 필요 없는 속성은 버림
5.4 단계적 정제
단계적 정제: 높은 추상화 수준에서 시작해 단계마다 세부 사항을 더하며 내려가는 하향식(top-down) 설계 방식 (예: "평균 출력" → 입력·합·나누기·출력 → 의사 코드 → Java)
- 작업은 하위 작업으로, 데이터는 데이터 구조로 분해
- 큰 추상화 단계에서 쪼개면서 작은 작업으로 내려감, 의사 코드가 나올 때까지 반복
- 분할정복과 차이: 쪼개는 건 같음, 분할정복은 하위 답을 다시 결합, 단계적 정제는 추상 수준을 낮추며 구체화해 코드까지 감
5.5 정보 은닉
추상화(뭘 남길지) → 캡슐화(묶기) → 정보 은닉(private로 숨기고 public 메소드로만 열기)
정보 은닉: 클래스 내부 정보를 숨기고 정해진 메소드로만 접근하게 하는 것, 추상화에서 시작 (예: private name + public getName())
- 과정
- 추상화로 요구사항의 공통점 찾기
- 목표와 관련 없는 것 제거
- 공통점을 캡슐화
- 캡슐화 대상에 데이터 타입 부여해서 숨김
- 기본 개념
- 클래스 내부 속성은 접근 제한, 인터페이스(메소드)로만 접근
- 좋은 정보 은닉은 좋은 클래스 추상화에서 나옴
- 객체지향과의 관계
- 객체지향 프로그래밍은 정보 은닉에서 시작
- 객체지향의 목표 = 유연성(기능 확장, 교체, 변경), 정보 은닉은 이를 가능하게 하는 추진 전략
- Java 예제
class Student {
private int id;
private String name;
public String getName(int id);
public void setName(int newId, String iname);
}
private속성은 외부 접근 차단,public메소드로만 접근
5.6 모듈의 응집력 높이기
그림 읽는 법
- 네모 = 모듈, 동그라미 = 모듈 안 구성 요소, 색 = 목적
- 검은 선 = 모듈 안 연결(응집력), 빨간 선 = 모듈 사이 연결(커플링)
- 왼쪽(좋음): 같은 목적끼리 한 모듈에 모임 → 안쪽 연결 강하고 바깥 연결 적음
- 오른쪽(나쁨): 같은 목적이 여러 모듈에 흩어짐 → 서로 찾아가느라 빨간 선이 많아짐
응집력: 한 모듈(클래스) 안 구성 요소들이 하나의 목적으로 얼마나 뭉쳐 있는지, 높으면 좋음 (예: 성적 계산 모듈엔 성적 계산 코드만)
- 높음: 구성 요소 밀접, 목적 하나 / 낮음: 느슨, 목적 여러 개
- 높은 응집력 → 패키지·모듈·클래스를 일관성 있게 설계
- 기능적 응집력만 있는 게 제일 좋음
- 유형 (높음 → 낮음)
| 순위 | 유형 | 뜻 | 예 |
|---|---|---|---|
| 1 | 기능적(functional) | 한 기능에 필요한 요소만 전부 있음, 가장 이상적 | |
| 2 | 순차적(sequential) | 앞 출력이 다음 입력, 데이터 흐름 | 함수 호출 |
| 3 | 통신(communicational) | 같은 입력이나 같은 출력 데이터를 쓰는 기능끼리 묶음, 교환적이라고도 함 | 레코드 갱신·저장 + 프린터 출력 |
| 4 | 절차적(procedural) | 명령어 실행 순서대로 묶음, 연결 약하고 재사용 어려움 | 성적 읽기 → 합계 → 평점 → 저장 → 출력 |
| 5 | 시간적(temporal) | 같은 시간에 실행되는 작업끼리 묶음 | 시스템 전체 초기화 |
| 6 | 논리적(logical) | 기능 연관 없이 논리적으로 비슷한 것끼리 묶음 | 테이프·디스크·네트워크 입력 |
| 7 | 우연적(coincidental) | 관련 없는 것들을 목적 없이 묶음, 최악 |
5.7 모듈 간의 커플링 낮추기
커플링: 모듈 사이 상호 의존성 정도, 낮으면 좋음 (예: A가 B를 호출하면 A와 B가 커플링됨)
- 높음: 하나 바꾸면 다른 모듈도 영향 / 낮음: 독립적, 영향 거의 없음
- 높은 커플링은 처음엔 구현 쉬워 보이지만 장애 나면 디버깅·수정이 훨씬 어려움
- 필요한 데이터만 주고받는 게 제일 좋음
- 유형 (낮은 결합 → 높은 결합)
| 순위 | 유형 | 뜻 | 예 |
|---|---|---|---|
| 1 | 데이터(data) | 필요한 데이터만 주고받음 | add(a, b) |
| 2 | 스탬프(stamp) | 자료구조 통째로 넘김 | 이름만 필요한데 Student 객체 전체 전달 |
| 3 | 제어(control) | 제어 정보를 넘겨 상대 동작을 바꿈 | 비교 함수를 받는 정렬 함수 |
| 4 | 외부(external) | 소프트웨어 바깥 모듈·하드웨어에 종속 | 프로토콜, 외부 파일, 장치 형식 |
| 5 | 공통(common) | 전역 데이터를 같이 씀, 재사용·접근 제어·유지보수 어려움 | 전역 변수 공유 |
| 6 | 내용(content) | 다른 모듈 데이터를 직접 수정하거나 제어 흐름이 넘어감, 최악 | 남의 내부 변수 직접 수정 |
- 추가 5개 (순위 없음)
- 시간적: 실행 타이밍·순서에 의존 (A가 B보다 먼저 실행돼야 함)
- 순차적: 한 모듈 출력이 다른 모듈 입력, 체인 의존
- 통신: 공유 메시지·DB 같은 통신 수단을 같이 씀
- 기능: 다른 모듈의 함수를 호출하는 등 서로 기능에 의존
- 데이터 구조적: DB 테이블·데이터 파일 같은 공통 데이터 구조를 공유, 무결성 유지 어려움
- 낮은 커플링 장점: 유지보수 용이성↑, 모듈성↑(독립 개발·테스트, 재사용), 확장성↑(모듈 추가·제거 쉬움)
- 높은 커플링 단점: 복잡성↑, 유연성↓, 모듈성↓
5.8 그 밖의 소프트웨어 설계 원리
- 소프트웨어 아키텍처 설계, 클래스 설계 패턴, 리팩토링 (내용은 뒷장에서)
5.9 새로운 소프트웨어 시스템의 구축 방법
시스템 획득 전략: 새 시스템을 구축하는 방법 3가지
- 자체 개발, 상용 솔루션 커스터마이징, 아웃소싱에 의한 외부 개발
- 고려할 것: 업무적인 필요성, 회사 내부 경험, 프로젝트의 소요 기술, 프로젝트 관리 능력, 추진 기간