ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • '오브젝트' 책 보고 공부하기 - ④ 설계 품질과 트레이드오프
    JAVA공부/JAVA 2023. 5. 29. 02:42

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

     

    객체의 상태 변경은 인터페이스 변경이 일어나며, 의존하는 모든 객체에 영향이 끼친다.

    이전 기억을 떠올려 보니 객체의 상태변경시 마다 바꾸어야 될 코드가 많았던게 기억이난다.

     

    데이터 중심의 영화예매 시스템은 '할인정책', '할인조건' 이 모두 Movie객체에서 처리한다.

    Enum Type으로 정책구분을 하는데, 내가 짜왔던 코드와 많이 비슷해서 흠짓했다.

    후에는 회사 팀원분들의 조언으로 Enum Type으로 맞는 인터페이스의 구현체를 호출하는 방법도 많이 해보았는데,

    확실히 가독성이 뛰어났다.

    객체의 상태를 호출해와서 해당 상태로 또다른 상태를 호출하는 이런방식의 코드도 많이 닮아있다.

    즉, 캡슐화 & 추상화가 되어있지 않은 코드가 생겼다.

     

     


     

    2) 설계 트레이드오프

     

    캡슐화

     

    상태와 행동을 하나의 객체 안에 모으는 이유는 객체 내부 구현을 외부로 부터 감추기 위함인데.

    데이터 중심의 설계에서는 내부 상태와 행동을 외부 객체가 탐색과 사용을 해버림으로써 구현에 대한 불안정함이 생겨버렸다.

     

     

     

    응집도와 결합도

     

    응집도는 모듈 내부에 포함된 내부 요소들이 연관되어 있는 정도를 나타낸다.

    하나의 요구사항을 반영하기 위해 하나의 모듈만 수정하는 것은 응집도가 높다는 것이다.

     

    결합도는 의존성의 정도이며, 다른 모듈에 대해 얼마나 많은 지식을 갖고 있는지를 나타내는 척도이다.

    마찬가지로 하나의 요구사항을 반영하기 위해 하나의 모듈만 수정하게  하는것이 결합도가 낮다는 것이다.

     

    퍼블릭 인터페이스에 의존하도록 코드를 구현하여 결합도를 낮추도록 하자.

     

    캡슐화가 잘될 수록 응집도는 높아지며 결합도는 낮아질 수 있다.

     

     


     

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

     

    데이터 중심이나 객체 지향이나 기능에서는 동일한 작용을 한다. 그런데 무엇이 문제일까??

    설계관점에서의 차이가 매우 크다!

     

    이유는 앞서 말했던 캡슐화가 되지 않음으로써 응집도는 낮고 결합도는 높은 코드가 되었다.

    특히, get 메서드를 통해 모든 상태가 public하게 공유되고 있다. 

     

    나도 객체 생성시에 get메서드를 항상 작성해주는데, 이 책에서 말해주는 다양한 상황에서 사용하게 되는 것을 대비해서

    작성해주었다. 사실 dto나  entity에 무작정 작성해주는데, 캡슐화를 하나도 안했던것 같아 나의 잘못된 코드들이 생각난다.

     

    get메서드로 호출해온 상태값을 변수에 담은 코드를 만들 경우, 추후 해당 상태 타입 변경시에  get메서드의 반환타입 뿐아니라

    받는 타입들도 다 변경해주어야 하기 때문에 결합도 측면에서도 매우 안좋다.

     

    데이터중심의 구현에서는 여러가지 책임이 한 곳에 모여 있어 응집도가 매우 낮다.

    가령 정책을 추가한다거나, 조건을 추가한다거나 하나의 책임이 변경되어야 한다고하면 조건에 유의하면서 수정해야한다.

     

     


     

    4) 자율적인 객체를 향해

     

    캡슐화를 하자. 객체 내부 상태의 변경은 객체 자신에게 맡기자. 그러면 객체 내부의 상태가 어떤타입, 이름, 값으로 변해도 

    변경에 취약하지 않다. 

    그러나 드는 생각이 객체 생성시점에는 올바른 상태값을 전달해줘야하지 않나? 이런생각은 들기도 한다.

    그래도 접근자와 수정자를 통해 속성을 외부로 제공하지 말자.

    객체가 어떤 데이터를 포함해야하는가객체가 데이터에 대해 수행해야 하는 오퍼레이션은 무엇인가? 를 조합하여

    설계하자. 어떤 데이터에 대해 오퍼레이션이 일어나지 않는다면 해당 데이터는 쓸모없는 데이터만 쌓일 것이다.

    가령 DB에서 사용하지 않는 컬럼이 존재하는 것처럼 말이다.

     


     

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

     

    파급효과를 항상 생각해야한다. 협력하는 객체의 상태를 변경했을때, 해당 메서드를 사용해야하는 클라이언트도 변경해야 한다면

    무언가 잘 못 된것이 아닌지 체크해보고, 리팩토링하자.

     


     

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

     

    객체의 행동보다는 상태에 초점을 맞추는데, 이는 너무 이른시기에 내부 구현에 초점을 맞추게한다.

    접근자와 수정자가 난무한다. 즉, 필드가 public하게 공유되는것과 동일시 된다. 이로인해 캡슐화가 깨진다.

    이에 익숙해지면서 데이터와 기능을 분리하는 절차적프로그래밍에 이르는 것이다.

     

    데이터를 먼저 결정하고 데이터를 처리하는데 필요한 오퍼레이션을 나중에 결정하는 방식은 데이터 관한 지식이

    객체의 인터페이스에 드러나게 되면서 캡슐화, 변경에 취약해진다.

     

    계속 강조되지만, 협력이라는 문맥안에서 책임을 결정하고 이를 수행할 적절한 객체를 찾자.

    객체의 상태를 찾아 헤메는 것이 아닌 어떤 객체와 협력하는 것을 찾아 헤메자.

     

    객체의 인터페이스에 구현이 노출되지 않도록 하자, 발견하면 리팩토링하자, 그렇지 않으면 내부 구현 변경시 협력 객체가

    모두 영향 받을 수 있다.

     

     

     

    정리

    • 캡슐화 & 추상화를 통해 코드를 작성하자. 변경과 리팩토링에 강하게 만들자.
    • 객체 결합간에 퍼블릭 인터페이스를 사용하게 하여 구현에 대한 내용은 최대한 숨기도록 하자.
    • 오퍼레이션이 없는 데이터는 쓸모 없다.
    • 필드뿐 아니라 메서드를 통한 접근도 최소화하자.
Designed by Tistory.