[오브젝트: 코드로 이해하는 객체지향 설계/조영호]4장: 설계 품질과 트레이드오프

2025. 11. 14. 23:35·IT서적/오브젝트
728x90

04 설계 품질과 트레이드오프

객체지향 설계의 핵심은 역할, 책임, 협력이다.

  • 협력: 애플리케이션의 기능을 구현하기 위해 메시지를 주고받는 객체들 사이의 상호작용
  • 책임: 객체가 다른 객체와 협력하기 위해 수행하는 행동
  • 역할: 대체 가능한 책임의 집합

책임 주도 설계는 역할, 책임, 협력 중에 책임이 중요하다.
객체지향 설계는 올바른 객체에게 올바른 책임을 할당하면서 낮은 결합도와 높은 응집도를 가진 구조를 창조하는 활동이다.

  1. 객체지향 설계의 핵심이 책임
  2. 책임을 할당하는 작업이 응집도와 결합도 같은 설계 품질과 연관돼 있다는 것이다.

휼룡한 설계란 합리적인 비용 안에서 변경을 수용할 수 있는 구조를 만드는 것이다.
객체의 상태가 아니라 행동에 초점을 맞춘다.

객체를 데이터 집합으로 바라보는 시각은 객체 내부 구현을 퍼블릭 인터페이스에 노출시키는 결과를 낳기 때문에 설계가 변경에 취약해진다.
이러한 문제를 피할 수 있는 가장 좋은 방법은 객체의 책임에 초점을 맞춘다

1.데이터 중심의 영화 예매 시스템

이번 장은 영화 예매 시스템을 책임이 아닌 상태를 표현하는 데이터 중심의 설계를 살펴보고 객체지향적으로 설계한 구조와 어떤 차이점이 있는지 살펴보는 챕터입니다.

방법1. 상태 분활의 중심축으로 삼는다
방법2. 책임을 분활의 중심축으로 삼는다
객체의 상태는 객체가 저장해야 하는 데이터의 집합을 의미하기 때문에 상태와 데이터를 동일한 의미로 사용하겠다.

데이터 중심의 관점

  • 객체의 상태에 초점을 맞춘다
  • 객체를 독립된 데이터 덩어리로 바라본다
  • 객체는 자신이 포함하고 있는 데이터를 조작하는데 필요한 오퍼레이션을 정의한다

책임 중심의 관점

  • 객체의 행동에 초점을 맞춘다
  • 객체를 협력하는 공동체의 일원으로 바라본다
  • 객체는 다른 객체가 요청할 수 있는 오퍼레이션을 위한 필요한 상태를 보관한다.

☆ Enum을 사용하는 이유: 타입안정성
Enum 사용 이전 사용 형태: final 상수, 인터페이스 상수, 자체 클래스 상수 형태가 있습니다.

2.설계의 트레이드 오프

캡슐화, 응집도, 결합도라는 3가지 품질 척도의 의미를 살펴보자

캡슐화

  • 객체의 내부 구현을 외부로부터 감추는 것입니다. 여기서 내부 구현이란 추후에 변경될 수 있는 모든 것입니다.
  • 객체를 사용하면 변경 가능성이 높은 부분은 내부에 숨기고 외부에는 인터페이스만 제공하여 어떠한 변경이 전체 시스템에 영향을 끼치지 않도록 하는 것입니다.
  • 변경될 가능성이 높은 부분을 구현이라 부르고 상대적으로 안전한 부분을 인터페이스라 부릅니다.
  • 객체를 설계하기 위한 가장 기본적인 아이디어는 변경 정도에 따라 구현과 인터페이스를 분리하고 외부에서는 인터페이스만 의존하도록 관계를 조절하는 것입니다.
  • 이렇게 객체지향에서 가장 중요한 것은 캡슐화입니다. 캡슐화는 외부에서 알 필요가 없는 부분을 감춤으로써 대상을 단순화하는 추상화의 한 종류입니다.
  • 캡슐화를 지킨다면 응집도는 높아지고 결합도는 낮아질 수 있습니다.

응집도

  • 응집도는 모듈에 포함되어 있는 내부 요소들이 연관된 정도를 나타냅니다. 모듈 내의 요소들이 하나의 목적을 위해 긴밀하게 협력한다면 높은 응집도를 가졌다고 할 수 있습니다.
  • 객체지향의 관점에서 응집도는 객체 또는 클래스에게 얼마나 관련된 높은 책임을 할당했는지를 나타냅니다.image 응집도가 높을수록 변경의 대상과 범위가 명확해지기 때문에 코드를 변경하기 쉬워진다.

결합도

  • 결합도는 의존성의 정도를 나타내며 다른 모듈에 대해 얼마나 많은 지식을 가지고 있는지 나타내는 척도입니다.
  • 어떤 모듈이 다른 모듈에 대해 너무 자세한 부분까지 알고 있다면 높은 결합도를 가지고 있다고 할 수 있습니다.
  • 결합도는 한 모듈이 변경되기 위해 다른 모듈의 변경을 요구하는 정도로 측정할 수 있습니다.
  • 내부 구현을 변경햇을 때 이것이 다른 모듈에 영향을 미치는 경우 두 모듈 사이의 결합도가 높다고 표현합니다. 반면 인터페이스를 수정했을 때만 다른 모듈에 영향을 미치는 경우에는 결합도가 낮다고 표현합니다. 따라서 구현이 아닌 인터페이스에 의존하도록 코드를 작성해야 낮은 결합도를 얻을 수 있습니다.image 결합도가 높으면 함깨 변경해야하는 모듈의 수가 늘어나기 때문에 변경하기가 어려워진다.

좋은 설계

  • 일반적으로 좋은 설계란 높은 응집도와 낮은 결합도를 가진 모듈로 구성된 설계를 의미합니다.
  • 좋은 설계란 오늘의 기능을 수행하면서 내일의 변경을 받아드릴 수 있는 설계입니다.
  • 높은 응집도와 낮은 결합도를 추구해야 하는 이유는 설계를 변경하기 쉽게 만들기 때문입니다. 변경의 관점에서 응집도란 변경이 일어났을 때 모듈 내부에서 발생하는 변경의 정도로 측정할 수 있습니다.

3.데이터 중심의 영화 예매 시스템의 문제점

데이터 중심의 설계가 가진 대표적인 문제점은 다음과 같다

  • 캡슐화 위반
  • 높은 결합도
  • 낮은 응집도

p.117
☆ 단일책임원칙의 책임과 책임주도설계의 책임이 같은가? 아니다.

image


SRP의 책임 = 변경의 이유
RDD의 책임 = 객체가 수행해야 하는 역할과 행동

RDD와 SRP의 책임 비교

구분  RDD (Responsibility-Driven Design) SRP (Single Responsibility Principle) |
성격 객체지향 설계 방법론 SOLID 원칙
단계 설계 단계 구현 및 유지보수 단계
책임의 의미 객체의 역할과 협력 정의 클래스의 변경 이유 단일화
관계 RDD를 적용하면 SRP를 만족시킬 수 있다 SRP만으로는 RDD를 만족시킬 수 없다

 

4.자율적인 객체를 향해

캡슐화를 지켜라

  • 객체는 자신이 어떤 데이터를 가지고 있는지를 캡슐화하고 외부에 공개해서는 안됩니다. 객체는 스스로의 상태를 챚임져야 하며 외부에서는 인터페이스를 통해서만 상태에 접근할 수 있어야 합니다.
  • 여기서 말하는 메서드는 단순히 속성값을 반환하거나 수정자 메서드를 의미하는게 아닙니다. 객체에게 의미있는 메서드는 객체가 책임져야 하는 무엇가를 수행하는 메서드 입니다.
  • 속성을 private로 설정했다고해서 getter, setter를 통해 속성을 외부로 제공하고 있다면 캡슐화를 위반하는 것입니다.

캡슐화를 위반하는 예제

Getter
@Setter
public class Rectangle {

    private int left;
    private int right;
    private int top;
    private int bottom;

    public Rectangle(int left, int right, int top, int bottom) {
        this.left = left;
        this.right = right;
        this.top = top;
        this.bottom = bottom;
    }
    // getter, setter
}

class AnyClass {
  void anyMethod(Rectangle rectangle, int multiple) {
        rectangle.setRight(rectangle.getRight() + mutiple); // 캡슐화 위반
        rectangle.setBottom(rectangle.getBottom() + mutiple); 
    }
}

인스턴스 변수를 노출시킨다.

캡슐화를 지키는 예제

public class Rectangle {
    public void enlarge(int multiple) {
      right += multiple;
      bottom += multiple;
    }
}

Rectang의 상태를 변경하는 주체를 외부에서 Rectangle 내부로 이동시켰다.
자신의 크기를 스스로 조절하도록 '책임을 이동'시킨 것이다. 이것이 바로 객체가 자기 스스로 책임진다는 의미이다.

5.하지만 여전히 부족하다

image

6.데이터 중심의 설계의 문제점

데이터 중심의 설계가 변경에 취약한 이유는 두 가지다.

  • 데이터 중심의 설계는 본질적으로 너무 이른 시기에 데이터에 관해 결정하도록 강요한다.
  • 데이터 중심의 설계에서는 협력이라는 문맥을 고려하지 않고 객체를 고립시킨 채 오퍼레이션을 결정한다.
    올바른 객체지향 설계의 무게 중심은 항상 객체의 내부가 아니라 외부에 맞춰져 있어야 한다
728x90
반응형

'IT서적 > 오브젝트' 카테고리의 다른 글

[오브젝트: 코드로 이해하는 객체지향 설계/조영호]6장: 메시지와 인터페이스  (0) 2025.11.14
[오브젝트: 코드로 이해하는 객체지향 설계/조영호]5장: 책임 할당하기  (0) 2025.11.14
[오브젝트: 코드로 이해하는 객체지향 설계/조영호]3장: 역할, 책임, 협력  (0) 2025.11.14
[오브젝트: 코드로 이해하는 객체지향 설계/조영호]2장: 객체지향 프로그래밍  (0) 2025.11.14
[오브젝트: 코드로 이해하는 객체지향 설계/조영호]1장: 객체, 설계  (1) 2025.11.14
'IT서적/오브젝트' 카테고리의 다른 글
  • [오브젝트: 코드로 이해하는 객체지향 설계/조영호]6장: 메시지와 인터페이스
  • [오브젝트: 코드로 이해하는 객체지향 설계/조영호]5장: 책임 할당하기
  • [오브젝트: 코드로 이해하는 객체지향 설계/조영호]3장: 역할, 책임, 협력
  • [오브젝트: 코드로 이해하는 객체지향 설계/조영호]2장: 객체지향 프로그래밍
lakedata
lakedata
lakedata 님의 블로그 입니다.
  • lakedata
    lakedata 님의 블로그
    lakedata
  • 전체
    오늘
    어제
    • 분류 전체보기 (188)
      • cs (82)
        • dev (28)
        • sec (29)
        • ops (25)
      • 자격증 (32)
        • 정보처리기사 (20)
        • 정보보안기사 (1)
        • aws dva (6)
        • aws dop (2)
      • IT서적 (27)
        • 클린아키텍처 (10)
        • 객체지향의사실과오해 (7)
        • 오브젝트 (10)
      • 코테 (42)
        • 알고리즘 (20)
        • 백준 (13)
        • 프로그래머스 (7)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • github
  • 공지사항

  • 인기 글

  • 태그

    CS
    알고리즘
    Spring
    AWS
    SQL
    Java
    docker
    Security
  • 최근 댓글

  • 최근 글

  • 반응형
    250x250
  • hELLO· Designed By정상우.v4.10.3
lakedata
[오브젝트: 코드로 이해하는 객체지향 설계/조영호]4장: 설계 품질과 트레이드오프
상단으로

티스토리툴바