본문 바로가기
Book

[독서 기록] 오브젝트 4장 설계 품질과 트레이드오프

by Renechoi 2023. 1. 15.
 
오브젝트
객체지향으로 향하는 첫걸음은 클래스가 아니라 객체를 바라보는 것에서부터 시작한다. 객체지향으로 향하는 두번째 걸음은 객체를 독립적인 존재가 아니라 기능을 구현하기 위해 협력하는 공동체의 존재로 바라보는 것이다. 세번째 걸음을 내디딜 수 있는지 여부는 협력에 참여하는 객체 들에게 얼마나 적절한 역할과 책임을 부여할 수 있느냐에 달려 있다. 객체지향의 마지막 걸음은 앞에서 설명한 개념들을 여러분이 사용하는 프로그래밍 언어라는 틀에 흐트러짐 없이 담아낼 수 있는 기술을 익히는 것이다. 《객체지향의 사실과 오해》가 첫번째 걸음과 두번째 걸음인 객체와 협력에 초점을 맞췄다면 《오브젝트: 코드로 이해하는 객체지향 설계》는 세번째와 네번째 걸음인 책임의 할당과 그 구현에 초점을 맞춘다. 이 책을 읽고 나면 객체에 적절한 역할과 책임을 부여하는 방법과 유연하면서도 요구사항에 적절한 협력을 설계하는 방법을 익히게 될 것이다. 나아가 프로그래밍 언어라는 도구를 이용해 객체지향의 개념과 원칙들을 오롯이 표현할 수 있는 방법 역시 익힐 수 있을 것이다. ★ 이 책에서 다루는 내용 ★ ◎ 역할, 책임, 협력에 기반해 객체지향 프로그램을 설계하고 구현하는 방법 ◎ 응집도와 결합도를 이용해 설계를 트레이드오프하는 방법 ◎ 설계를 유연하게 만드는 다양한 의존성 관리 기법 ◎ 타입 계층을 위한 상속과 코드 재사용을 위한 합성의 개념 ◎ 다양한 설계 원칙과 디자인 패턴
저자
조영호
출판
위키북스
출판일
2019.06.17

 

 

 

오브젝트 4장 설계 품질과 트레이드오프


 

 

데이터 중심의 관점에서 객체는 자신이 포함하고 있는 데이터를 조작하는 데 필요한 오퍼레이션을 정의한다. 책임 중심의 관점에서 객체는 다른 객체가 요청할 수 있는 오퍼레이션을 위해 필요한 상태를 보관한다. 데이터 중심의 관점은 객체의 상태에 초점을 맞추고 책임 중심의 관점은 객체의 행동에 초점을 맞춘다. 전자는 객체를 독립된 데이터 덩어리로 바라보고 후자는 객체를 협력하는 공동체의 일원으로 바라본다.

 

... 객체의 상태는 구현에 속한다. 구현은 불안정하기 때문에 변하기 쉽다. 상태를 객체 분할의 중심축으로 삼으면 구현에 관한 세부사항이 객체의 인터페이스에 스며들게 되어 캡슐화의 원칙이 무너진다. 

 

- 98p 

 

책임 중심의 설계가 '책임이 무엇인가'를 묻는 것으로 시작한다면 데이터 중심의 설계는 객체가 내부에 저장해야 하는 '데이터가 무엇인가'를 묻는 것으로 시작한다. 먼저 Movie에 저장될 데이터를 결정하는 것으로 설계를 시작하자. 

 

package ch4;

import java.time.Duration;

public class Movie {
    private String title;
    private Duration runningTime;
    private Money fee;
    private List<DicountCondition> discountConditions;
    
    private MovieType movieType;
    private Money discountAmount;
    private double discountPercent; 
    
    
}

 

가장 두드러지는 차이점은 할인 조건의 목록이 인스턴스 변수로 Movie 안에 직접 포함돼 있다는 것이다. 또한 할인 정책을 DiscountPolicy라는 별도의 클래스로 분리했던 이전 예제와 달리 금액 할인 정책에 사용되는 할인 금액(discountAmount)과 비율 할인 정책에 사용되는 할인 비율(discountPercent)을 Movie 안에서 직접 정의하고 있다. 

 

- 99p 

 

 

movieType의 값이 AMOUNT_DISCOUNT라면 discountAmount에 저장된 값을 사용하고 PERCENT_DISCOUNT라면 discountPercent에 저장된 값을 사용한다. NONE_DISCOUNT인 경우에는 할인 정책을 적용하지 말아야 하기 때문에 discountAmount와 discountPercent 중 어떤 값도 사용하지 않는다. 

 

- 100p 

 

 

데이터 중심의 설계에서는 객체가 포함해야 하는 데이터에 집중한다. 이 객체가 포함해야 하는 데이터는 무엇인가? 객체의 책임을 결정하기 전에 이런 질문의 반복에 휩쓸려 있다면 데이터 중심의 설계에 매몰돼 있을 확률이 높다. 특히 Movie 클래스의 경우처럼 객체의 종류를 저장하는 인스턴스 변수(MovieType)와 인스턴스의 종류에 따라 배타적으로 사용될 인스턴스 변수(discountAmount, discountPercent)를 하나의 클래스 안에 함께 포함시키는 방식은 데이터 중심의 설계 안에서 흔히 볼 수 있는 패턴이다. 

 

- 100p 

 

 

변경될 가능성이 높은 부분을 구현이라고 부르고 상대적으로 안정적인 부분을 인터페이스라고 부른다는 사실을 기억하라.

- 109p 

 

캡슐화란 변경 가능성이 높은 부분을 객체 내부로 숨기는 추상화 기법이다. 객체 내부에 무엇을 캡슐화해야 하는가? 변경될 수 있는 어떤 것이라도 캡슐화해야 한다. 

- 109p 

 

유지보수성이 목표다. 여기서 유지보수성이란 두려움 없이, 주저함 없이, 저항감 없이 코드를 변경할 수 있는 능력을 말한다. ... [Bain08]

- 109p 

 

캡슐화의 정도가 응집도와 결합도에 영향을 미친다는 사실을 강조하고 싶다. 캡슐화를 지키면 모듈 안의 응집도는 높아지고 모듈 사이의 결합도는 낮아진다. 캡슐화를 위반하면 모듈 안의 응집도는 낮아지고 모듈 사이의 결합도는 높아진다. 따라서 응집도와 결합도를 고려하기 전에 먼저 캡슐화를 향상시키기 위해 노력하라.

- 112p 

 

Movie가 캡슐화의 원칙을 어기게 된 근본적인 원인은 객체가 수행할 책임이 아니라 내부에 저장할 데이터에 초점을 맞췄기 때문이다. 객체에게 중요한 것은 책임이다. 그리고 구현을 캡슐화할 수 있는 적절한 책임은 협력이라는 문맥을 고려할 때만 얻을 수 있다.

- 114p 

 

 

결합도 측면에서 데이터 중심 설계가 가지는 또 다른 단점은 여러 데이터 객체들을 사용하는 제어 로직이 특정 객체 안에 집중되기 때문에 하나의 제어 객체가 다수의 데이터 객체에 강하게 결합된다는 것이다.

- 115p 

 

 

class AnyClass {
	void anyMethod(Rectangle rectangle, int multiple) {
    	rectangle.setRight(rectangle.gerRight() * multiple);
        rectangle.setBottom(rectangle.getBotto() * multiple); 
    ...
   }

해결 방법은 캡슐화를 강화시키는 것이다. Rectangle 내부에 너비와 높이를 조절하는 로직을 캡슐화하면 두 가지 문제를 해결할 수 있다. 

 

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

- 119p 

 

 

데이터 중심의 설계를 시작할 때 던졌던 첫 번째 질문은 "이 객체가 포함해야 하는 데이터가 무엇인가?"다. 데이터는 구현의 일부라는 사실을 명심하라. 

- 131p 

 

데이터 중심 설계 방식에 익숙한 개발자들은 일반적으로 데이터와 기능을 분리하는 절차적 프로그래밍 방식을 따른다. 이것은 상태와 행동을 하나의 단위로 캡슐화하는 객체지향 패러다임에 반하는 것이다. 데이터 중심의 관점에서 객체는 그저 단순한 데이터의 집합체일 뿐이다. 이로 인해 접근자와 수정자를 과도하게 추가하게 되고 이 데이터 객체를 사용하는 절차를 분리된 별도의 객체 안에 구현하게 된다. 앞에서 설명한 것처럼 접근자와 수정자는 public 속성과 큰 차이가 없기 때문에 객체의 캡슐화는 완전히 무너질 수밖에 없다. 

- 131p 

 

 

올바른 객체지향 설계의 무게 중심은 항상 객체의 내부가 아니라 외부에 맞춰져 있어야 한다. 객체가 내부에 어떤 상태를 가지고 그 상태를 어떻게 관리하는가는 부가적인 문제다. 중요한 것은 객체가 다른 객체와 협력하는 방법이다. 

- 132p 

 

 

반응형