본문 바로가기
OOP/<오브젝트>, 조영호

4장 설계 품질과 트레이드오프 (캡슐화)

by 민휘 2024. 1. 17.

 

팀원들과 이야기 나눈 내용

  • 처음 객체를 설계할 때부터 무엇부터 생각하는지에 따라 설계 결과가 완전히 달라지는 것이 신기하다. 첫 단추가 중요한 것 같다.
  • 코드를 완전히 처음 작성하는게 아닌 이상 이렇게 이상적인 객체지향적 접근을 적용하기 어려워 보인다.
  • 아직 경험이 부족하므로 이렇게 좋은 품질의 객체지향 설계를 하는 것은 어렵다고 생각한다. 그래도 4장에서 짚어보았던 것처럼, 캡슐화가 제대로 되지 않은 코드를 알아보는 것부터 연습해보는 것이 필요할 것 같다. 캡슐화가 제대로 되지 않은 코드가 있다면 어떤 문제가 발생할 수 있는지, 변경의 여파가 어디까지 커지는지 확인하는 것부터 연습해보자.
  • ORM이 객체중심의 애플리케이션과 데이터 중심의 데이터베이스 패러다임 차이를 해결한다고 하는 점이 이해가 잘 안됐었는데, 4장을 읽고나니 비로소 차이점이 보이는 것 같다. 헥사고날 아키텍처에서 비즈니스 로직의 엔티티 객체와 JPA 애노테이션을 매핑한 엔티티를 분리해서 사용하는 것을 본 적이 있는데, 이렇게 하면 확실히 비즈니스 엔티티를 더 객체중심적으로 다룰 수 있을 것 같다.
  • 코틀린이나 다트의 null safety 타입은 캡슐화를 위반하는 것이 아닐까? null safety 타입을 반환하는 메소드를 호출했을 때, 클라이언트는 이 결과가 null일 수도 있고 아닐 수도 있다는 구현 내용에 종속되는걸까? 그런 논리면 자바의 Optional도 캡슐화를 깨뜨리는거 아냐? 뭐야 모르겠는데요

 

데이터 중심 설계의 문제점

  • 캡슐화 실패!
  • 너무 이른 시기에 구현을 결정한다.
  • 협력이라는 문맥을 고려하지 않고 오퍼레이션을 결정하므로 인터페이스에 구현이 노출된다.

 

설계를 판단하는 기준

  • 캡슐화 : 구현은 숨기고 인터페이스는 공개하여 변경의 여파를 통제하는 방법
  • 캡슐화를 잘 하면 응집도가 높아지고 결합도는 낮아진다.
  • 응집도가 높은 객체는 하나의 관심사에만 집중하고, 결합도가 낮은 객체들은 꼭 필요한 의존성만 남기고 제거된다.
  • 이렇게 되면 특정 기능을 위해 코드를 수정할 때 변경할 범위가 좁혀진다.

 

캡슐화의 진정한 의미

  • 변경될 수 있는 모든 것을 감추는 것
  • 리턴 타입, 파라미터, 메소드 이름, 예외 등의 구현 사항이 인터페이스에 노출되지 않도록 주의하자. 이런 코드가 보인다면 캡슐화를 위반한 것이고, 어떤 문제를 유발할 수 있는지 생각해보자.

 

추측에 의한 설계 방식의 문제점

  • 어떤 데이터가 필요할지부터 생각하고, 과도한 게터 세터를 사용하는 방식
  • 캡슐화 위반 : 구현이 존재한다는 사실이 퍼블릭 인터페이스에 보이게 된다.
  • 높은 결합도 : 구현에 의존하므로 함께 변경된다.
  • 낮은 응집도 : 변경 이유가 하나여도 여러 클래스가 수정된다. 한 클래스의 변경 이유가 많다.

 

캡슐화 시도

  • 어떤 데이터가 필요한지 생각하고, 수행해야 하는 오퍼레이션이 무엇인지 고민한다.
  • 데이터를 갖고 있는 객체가 메소드를 구현하므로 스스로를 책임진다.

 

그럼에도 남아있는 문제점

  • 내부 캡슐화 실패 : 파라미터 타입, 반환 타입, 메서드 명을 통해 구현이 외부에 노출된다.
  • 높은 결합도 : 내부 구현이 바뀌면 의존성이 있는 객체도 함께 변경해야 한다.
  • 낮은 응집도 : 타입 하나를 추가하더라도 여러 클래스의 코드가 변경되어야 한다.