logo
작성일

CH5. 소프트웨어 설계 원리

Authors
  • avatar
    Name
    seren-wib
    Twitter
Contents

5. 소프트웨어 설계 원리

5.1 분할-정복 접근 방식

분할-정복: 큰 문제를 바로 풀 수 있을 만큼 작게 쪼개서 풀고 다시 합치는 방식 (예: 합병 정렬)

  • 절차
    1. 분해(Divide): 더 못 나눌 때까지 하위 문제로 재귀적으로 쪼갬
    2. 정복(Conquer): 쪼갠 하위 문제를 재귀로 하나씩 해결
    3. 결합(Combine): 하위 문제 답을 합쳐 원래 문제의 답을 만듦

5.2 모듈화

모듈화: 문제를 표준 인터페이스를 가진 독립 모듈로 나누고, 재사용 가능한 모듈을 조합해 전체를 해결하는 방식 (예: 부품 조립해서 완성품 만드는 하드웨어)

  • 기능 하나짜리 모듈은 한 번만 만들고 계속 재사용
  • 모듈: 독립적으로 만들고 유지보수할 수 있어 다른 시스템에서도 재사용되는 코드 조각
  • 모듈식 프로그래밍: 프로그램 기능을 독립적이고 상호 교환 가능한 모듈로 분리하는 설계 기법
  • 분할정복과 차이: 쪼개는 건 같음, 모듈화는 쪼갠 조각에 인터페이스·독립성·재사용이 붙음
  • 모듈의 의미
    1. 다른 모듈과 최대한 독립적
    2. 다른 시스템에서 재사용, 시스템 안에서 상호 교환 가능
    3. 시스템 코드의 한 부분이자 기능 (구조 단위)
  • 기본 원칙
    • 잘 된 모듈화: 일부를 바꿔도 다른 부분에 영향 적음
    • 응집력은 높게, 결합(커플링)은 느슨하게
    • 구조적(절차적)·객체지향 프로그래밍과 밀접, 1960년대쯤 시작
  • 장점
    1. 시스템 이해가 쉬움
    2. 유지관리가 쉬움
    3. 재사용: 만든 모듈은 다시 안 짜도 됨

5.3 추상화

추상화(컴퓨터과학): 복잡한 자료·모듈·시스템에서 핵심 개념이나 기능만 추려 간단하게 표현하는 방법 (예: 항공사진 → 도로·건물만 남긴 지도)

  • 추상화하는 방법
    1. 일반화: 공통점은 취하고 차이점은 버림 (학부생·대학원생 → 학생)
    2. 세부 사항 제거: 중요한 부분만 남기고 불필요한 디테일 삭제
  • 데이터: 현실 세계 사물을 문자·숫자·소리·영상·비디오·텍스트로 나타낸 값
  • 데이터 종류
    • 정량적(수치) 데이터: 직접 측정되는 물리적인 값 (온도, 가격, 매출액)
    • 정성적(범주형) 데이터: 숫자로 써도 물리값이 아닌 논리적인 값, 명목형·순서형 (성별, 혈액형, 성적 등급)
  • 추상화 대상
    • 운영 데이터: 조직 운영·관리에 꼭 필요한 데이터, 이것만 추상화
    • 추상화 대상: 문제 해결에 필요한 데이터 집합
    • 비운영 데이터: 나머지 전부, 무시해도 됨
    • 운영/비운영 구분은 시스템 목적에 따라 상대적 (학사관리면 학생·성적, 시설물관리면 도로·건물)
  • 운영 데이터는 클래스가 됨: 학생 → Student { id, name, address, mobile, major }, 필요 없는 속성은 버림

5.4 단계적 정제

단계적 정제: 높은 추상화 수준에서 시작해 단계마다 세부 사항을 더하며 내려가는 하향식(top-down) 설계 방식 (예: "평균 출력" → 입력·합·나누기·출력 → 의사 코드 → Java)

  • 작업은 하위 작업으로, 데이터는 데이터 구조로 분해
  • 큰 추상화 단계에서 쪼개면서 작은 작업으로 내려감, 의사 코드가 나올 때까지 반복
  • 분할정복과 차이: 쪼개는 건 같음, 분할정복은 하위 답을 다시 결합, 단계적 정제는 추상 수준을 낮추며 구체화해 코드까지 감

5.5 정보 은닉

추상화(뭘 남길지) → 캡슐화(묶기) → 정보 은닉(private로 숨기고 public 메소드로만 열기)

정보 은닉: 클래스 내부 정보를 숨기고 정해진 메소드로만 접근하게 하는 것, 추상화에서 시작 (예: private name + public getName())

  • 과정
    1. 추상화로 요구사항의 공통점 찾기
    2. 목표와 관련 없는 것 제거
    3. 공통점을 캡슐화
    4. 캡슐화 대상에 데이터 타입 부여해서 숨김
  • 기본 개념
    • 클래스 내부 속성은 접근 제한, 인터페이스(메소드)로만 접근
    • 좋은 정보 은닉은 좋은 클래스 추상화에서 나옴
  • 객체지향과의 관계
    • 객체지향 프로그래밍은 정보 은닉에서 시작
    • 객체지향의 목표 = 유연성(기능 확장, 교체, 변경), 정보 은닉은 이를 가능하게 하는 추진 전략
  • 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가지

  • 자체 개발, 상용 솔루션 커스터마이징, 아웃소싱에 의한 외부 개발
  • 고려할 것: 업무적인 필요성, 회사 내부 경험, 프로젝트의 소요 기술, 프로젝트 관리 능력, 추진 기간