[Object] 4. 설계 품질과 트레이드 오프
in Programming on Java
객체지향 설계의 핵심은 역할, 책임, 협력이다. 그 중에서 가장 중요한것은 책임이다. 채임을 어떻게 할당하냐에 따라 객체지향 어플리케이션 전체의 품질을 좌우한다.
훌륭한 설계란 합리적인 비용 안에서 변경을 할 수 있는 구조를 만드는것이다. 이를 위해서는 높은 응집도와 낮은 결합도가 필요하다. 그러려면 설계할때 객체의 책임에 초점을 맞춰야한다.
그런데 기존에는 주로 데이터중심관점에서 개발이 많이 이루어졌다. 데이터 중심의 설계를 살펴보고 어떤 단점이 있는지를 파악하여 책임 할당 원칙을 더 쉽게 이해해보자.
데이터 중심의 시스템 설계
데이터중심의 설계에서는 객체가 내부에 저장하는 “데이터가 무엇인가” 를 묻는 것으로 시작한다.
영화예매시스템을 짠다고 생각할때,
public class Movi{
private String title;
private Duration runningTime;
private Money fee
}
위의 객체부터 짠다면 전형적인 데이터 중심 설계이다.
어쨌든 캡슐화를 하기 위해서는 아래와 같이 접근자와 수정자를 추가할것이다.
public void setTitle(String title){
this.title = title;
}
public String getTitle(){
return this.title;
}
이런식으로 쭉 객체들을 짜고나서 예매시스템을 구현하고자 한다면?
예매 절차를 구현하는 class가 필요해질것이다.
public class ReservationAgency{
public Reservation reserve(Movie movie, Screen, screen...등등){
boolean discountable = false;
할인가격 계산하는 로직;
예약하는 로직; 등등....
}
}
설계 트레이드오프
이제 위에서 짠 코드를 평가하기 전에 설계의 척도인 캡슐화, 응집도, 결합도에 대해서 알아보자.
캡슐화
객체의 내부 구현을 외부로부터 감춘다. 변경 가능성이 높은부분(구현)을 내부로 숨기고 상대적으로 안정적인부분(인터페이스)만 공개한다. 불안정한부분과 안정된부분을 분리하여 변경의 영향을 통제할수 있게 된다.
응집도
응집도는 모듈에 포함된 내부 요소들이 연관되어있는 정도이다. 객체에 얼마나 관련 높은 책임들을 할당했는지를 나타낸다.
변경이 발생할 때 모듈 내부에서 발생하는 변경의 정도로 측정할 수 있다.
응집도가 높아야 좋은 설계. 하나의 변경에 대해 한 모듈만 변경되어야 응집도가 높은것.
결합도
결합도는 의존성의 정도를 나타내며 한 객체가 다른 객체에 대해 얼마나 많은 지식을 갖고있는지를 나타낸다. 협력에 필요한 적절한 수준의 관계만을 유지하고있는지를 나타낸다.
한 모듈이 변경되기 위해 다른 모듈의 변경을 요구하는 정도.
결합도가 낮아야 좋은 설계. 변경을 했을때 오직 하나의 모듈만 영향을 받아야 결합도가 낮은것.
데이터 중심 설계 시스템의 문제점
데이터 중심의 설계는 캡슐화를 위반하기때문에 응집도가 낮고 결합도가 높은 객체들을 양산하게 될 가능성이 높다.
캡슐화 위반
접근자와 수정자 (get,set 메소드)는 내부에 어떤 변수가 존재하는지 적나라하게 드러낸다. 즉, 캡슐화 위반인것이다.
협력이라는 문맥을 고려한 책임 할당이 올바른 캡슐화를 만든다.
협력에 관해 고민하지 않으면 과도한 접근자, 수정자를 가지게되는것이다.
높은 결합도
ReservationAgency에 제어 로직이 다 쏠리게되며 이 객체는 모든 데이터 객체에 의존하게된다. 높은 결합도로 인해 모듈 하나를 변경하면 다른 모듈들도 영향을 받게 되는것이다.
낮은 응집도
ReservationAgency에는 할인 가격을 계산한다는 이유로 변경 이유가 서로 다른 코드를 전부 뭉쳐놓는다. 따라서 하나의 요구사항을 반영하기 위해서는 여러 모듈을 수정해야한다. 응집도가 낮은것이다.
자율적인 객체
- 캡슐화를 지켜라
- 스스로 자신의 데이터를 책임져라
데이터 중심 설계의 문제점
- 너무 이른시기에 데이터에 관해 결정하도록 강요한다
- 협력이라는 문맥을 고려하지 않고 객체를 고립시킨채 operation을 결정한다.