[오브젝트] 14장 일관성 있는 협력

ppparkta·2025년 6월 7일
0

오브젝트

목록 보기
13/14

일관성 있는 협력

객체는 협력에 따라 동작하므로 협력 관계를 어떻게 설정하는지에 따라 유지보수성이 결정된다.

→ 즉, 협력 구조의 일관성이 중요하다.

협력 구조가 일관되면 약간의 기억력, 적응력만 있으면 손쉽게 코드를 파악할 수 있기 때문이다.

핸드폰 과금 시스템 변경

기본 정책을 확장해서

  • 고정 요금
  • 시간대별 요금
  • 요일별 요금
  • 구간별 요금

을 만들어야 한다.

고정 요금

고정 요금은 기존 구현 했던 코드의 이름을 바꾸기만 하면 된다.

시간대 별 요금

시간대 별 요금에서 고려해야 할 것이 늘어났다.

기존 코드는 날짜가 같은 경우만을 고려해서 작성했기 때문에 한 통화에 통화 날짜가 변경되면 이를 처리하지 못하는 버그가 있다.

총 3일에 걸친 통화 예시이다.

이런 처리를 위해서 DateTimeInterval 객체를 추가한다.

  1. 통화 기록을 일자 별로 분리한다
  2. 날짜 별로 시간을 계산한다

이러한 처리는 정보 전문가에게 할당하는 것이 가장 합리적이다.

날짜 별로 시간을 분리해내는 정보는 DateTimeInterval이 가장 잘 알고있다.

그리고 TimeOfDayDiscountPolicy에서 날짜 별로 시간을 계산하는 정보를 가장 잘 알고 있다. 따라서 각각의 객체들이 정보 전문가 패턴을 따라서 협력한다.

여기서 각 시간에 대한 요금 정보는 List를 이용해서 저장한다.

public class TimeOfDayDiscountPolicy extends BasicRatePolicy {
		private List<LocalTime> starts = new ArrayList<>();
		private List<LocalTime> ends = new ArrayList<>();
		private List<Duration> durations = new ArrayList<>();
		private List<Money> amounts = new ArrayList<>();
}

요일 별 요금

요일 별 요금을 계산할 때 필요한 정보는 요일 목록, 단위 시간, 단위 요금이다.

앞에서는 계산에 필요한 정보를 List로 저장했으나, 여기서는 DayOfWeekDiscountRole라는 객체로 구현한다.

마찬가지로 요일 별 방식도 여러 날짜에 걸쳐있을 수 있다.

구간 별 요금

구간 별 방식은 상속으로 풀어냈다.

짚고 넘어가기

⛔ 앞서 나온 방식들은 유사한 문제를 해결중이다.
그러나 각 방식에 일관성이 없어서 좋은 코드라고 하기 어렵다.

비 일관성의 문제점

  1. 새로운 구현 추가 시 방식을 설정하기 어렵다
  2. 기존 구현을 이해하기 어렵다

설계에 일관성 부여하기

유지보수성을 높이기 위해서 설계에 일관성을 부여하는 것이 좋다. 그렇다면 어떻게 일관성을 부여할 수 있을까?

  1. 다양한 설계 경험을 익혀라
  2. 널리 알려진 디자인패턴을 학습하고 변경이라는 문맥 안에서 디자인패턴을 적용하라

여기서 중요한 점은 다음과 같다.

  • 변하는 개념을 변하지 않는 개념으로부터 분리하라
  • 변하는 개념을 캡슐화하라

💡 이런 지침은 훌륭한 구조를 설계하기 위한 기본적인 원칙이기도 하다.
대부분 변경의 캡슐화라는 목표를 향한다.

조건 로직 대 객체 탐색

객체 지향에서 변경을 다루는 전통적인 방법은 조건 로직객체 사이의 이동으로 바꾸는 것이다.

Movie는 discountPolicy에 필요한 메시지를 전송할 뿐이다. 내부에 필요한 조건문은 discountPolicy로 이동한다.

💡다형성이란?
객체 사이의 이동으로 바꾸기 위해서 객체지향이 제공하는 설계기법이다.

Movie는 discountPolicy가 자신의 요청을 잘 처리해줄 것이라고 믿고 메시지를 전송할 뿐이다. DiscountPolicy와 DiscountCondition의 관계 역시 마찬가지다.

추상 수준에서의 협력 구조

객체지향적인 코드는 조건을 판단하지 않는다. 단지 다음 객체로 이동할 뿐이다.

이를 위해서 커다란 클래스를 더 작은 클래스로 분리할 수 있다. 그렇다면 어떻게 분리해야 할까?

💡 분리 방법

  • 변경의 이유: 단 하나의 이유에 의해서만 변경돼야 한다.
  • 주기: 클래스 안의 모든 코드는 함께 변경돼야 한다.

→ 작은 클래스로 분리하면 인스턴스들 사이의 협력 패턴에 일관성을 부여하기 쉬워진다.

유사한 행동을 하는 클래스 간 역할이라는 추상화로 묶이게 되며 일관성을 유지하도록 이끈다.

일관성 있는 협력을 위한 지침

  1. 변하는 개념을 변하지 않는 개념으로부터 분리하라.
  2. 변하는 개념을 캡슐화하라.

캡슐화 다시 살펴보기

흔히 캡슐화는 데이터 은닉을 떠올린다. 그러나 캡슐화는 데이터 은닉 그 이상이다.

GoF의 디자인 패턴을 보면 캡슐화란 소프트웨어 안에서 변할 수 있는 모든 개념을 감춘 것을 의미한다.

💡 캡슐화
변하는 어떤 것이든 감추는 것이다.
코드 수정으로 인한 파급효과를 제어할 수 있는 모든 기법을 캡슐화라고 한다.

  • 변하는 부분을 분리해서 타입 계층을 만든다.
  • 변하지 않는 부분의 일부로 타입 계층을 합성한다.

일관성 있는 기본 정책 구현하기

변경 분리하기

일관성 있는 기본 정책을 구현하기 위한 첫번째 단계는 변하는 개념과 변하지 않는 개념을 분리하는 것이다.

  • 기본 정책은 하나 이상의 규칙으로 구성된다.
  • 하나의 규칙은 적용 조건과 단위 요금의 조합이다.

시간대, 요일, 구간 별 방식은 하나 이상의 규칙들의 집합이다. 단, 조건의 세부 내용은 모두 다르다.

즉, 세부 내용은 변화에 해당한다.

공통점은 변하지 않는 부분,

차이점은 변하는 부분이다.

따라서 규칙으로부터 적용 조건을 분리해야 한다.

변경 캡슐화하기

일관성 있는 협력을 위해서 변경을 캡슐화 해서 파급효과를 줄여야 한다.

→ 변하지 않는 부분으로부터 변하는 부분을 캡슐화한다. (변하는 부분의 공통점은 추상화한다)

  • 변하는 것: 적용 조건
  • 변하지 않는 것: 규칙

규칙으로부터 적용 조건 추상화 후 추상화의 서브타입으로 만든다. (서브타입 캡슐화)

협력 패턴 설계하기

올바른 방향으로 나아가고 있는지 확인할 방법은 직접 구현하는 것 뿐!

추상화 수준에서 협력 패턴 구현하기

변하는 것과 변하지 않는 것을 분리하고 변하는 것을 캡슐화한 코드는 오로지 변하지 않는 것과 추상화에 대한 의존성만으로도 전체적인 협력을 구현할 수 있다.

변하는 것은 추상화 뒤에 캡슐화되어 숨겨져 있기 때문에 전체적인 협력의 구조에 영향을 미치지 않는다.

구체적인 협력 구현하기

변하는 부분을 변하지 않는 부분으로부터 분리했기 때문에 변하지 않는 부분을 재사용할 수 있다.

새로운 기능을 추가하기 위해 오직 변하는 부분만 구현하면 되기 때문에 원하는 기능을 쉽게 완성할 수 있다. 따라서 코드의 재사용성이 향상되고 테스트해야 하는 코드의 양이 감소한다.

기능을 추가할 때 따라야 하는 구조를 강제할 수 있기 때문에 기능을 추가하거나 변경할 때도 설계의 일관성이 무너지지 않는다.

💡 개념적 무결성
유사한 기능에 대해 유사한 협력 패턴을 적용하는 것은 객체지향 시스템에서 개념적 무결성을 유지할 수 있는 효과적인 방법이다. 개념적 무결성은 일관성과 동일한 뜻으로 간주해도 무방하다.

협력 패턴에 맞추기

💡 지속적으로 개선하라
처음에는 일관성을 유지하는 것처럼 보이던 협력 패턴이 시간이 흐르면서 새로운 요구사항이 추가되는 과정에서 일관성의 벽에 조금씩 금이 가는 경우를 자주 보게 된다.
협력 설계 초기 단계에서 모든 요구사항을 미리 예상할 수 없기 때문에 잘못이 아니며 꽤나 자연스러운 현상이다. 오히려 새로운 요구사항을 수용할 수 있는 협력 패턴을 향해 설계를 진화시킬 수 있는 좋은 신호로 받아들이자.
협력은 고정된 것이 아니다. 요구사항의 변경에 따라 협력 역시 지속적으로 개선해야 한다. 중요한 것은 현재의 설계에 맹목적으로 일관성을 맞추는 것이 아니라 달라지는 변경의 방향에 맞춰 지속적으로 코드를 개선하려는 의지다.

패턴을 찾아라

일관성 있는 협력의 핵심은 변경을 분리하고 캡슐화하는 것이다.

  • 변경을 캡슐화하는 방법이 협력에 참여하는 객체들의 역할과 책임을 결정한다.
  • 결정된 협력이 코드의 구조를 결정한다.

협력 패턴에 대해 언급할만한 가치가 있는 두 단어는 패턴프레임워크다.

다음 장에서 알아보자.

profile
겉촉속촉

0개의 댓글