alt
Home 객체지향 개론 2. 설계
Post
Cancel

객체지향 개론 2. 설계

: 객체지향적 설계란 응집도, 결합도, 캡슐화의 측면에서 변경이 쉽도록 짜는 것이다.

  • 설계는 항상 두가지 사용자를 다 염두해야 한다. 기능을 사용하는 사람, 코드를 건드는 사람
  • 설계의 트레이드오프
    • (절차지향) 심플하게 만들 것인가?
    • (객체지향) 복잡하더라도 변경에 유연하게 만들 것인가?
  • 객체지향적, 개발론적인 모든 원칙들은 변경에 관련된 것이다. e.g) SOLID 등
  • 다양한 디자인 패턴의 목적은 변경을 감추는 것
  • 변경하기 쉬운 설계: 1. 높은 응집도, 2. 낮은 결합도, 3. 캡슐화


  • TDD로 개발을 해보면, 메시지를 날리는 것을 중심적으로 설계하게 된다고 한다. TDD는 테스트방법이 아닌 설계방법.
  • 프레임워크(바뀌지 않는 것) 코드를 잘 보면 객체지향이 잘 적용되어있다. e.g) 스프링


응집도

: 모듈(클래스) 내부 요소들이 서로 관련 있는 정도.

  • 다르게 말하면, 응집도란 모듈 내부 요소들이 함께 변경되는 정도이다.
  • 변경 관점에서 보아야 한다.
  • 높은 응집도 - 모듈 전체가 동일한 이유로 변경된다.
    • 변경될 이유가 하나여야 한다. -> SRP 만족. (SRP는 응집도에 대한 이야기)
  • 낮은 응집도 - 모듈이 다양한 이유로 변경된다. -> 단적인 예로 merge 과정에서 conflict가 자주 발생한다.


결합도

: 한 모듈이 다른 모듈에 의존하는 정도. 다른 모듈에 대해 알고 있는 지식의 양

  • 결합도가 강하다, 느슨하다로 표현
  • 변경 관점에서 보아야한다.
  • 느슨한 결합도: 구현(내부)이 변경될 때 함께 변경되지 않는다. 안정적인 추상화(자주 바뀌지 않는 것)에 의존 == 인터페이스에 의존
    • 싱글턴: 하나의 오브젝트가 전역적으로 쓰이기 때문에 결합도가 높다.


구현과 추상화

  • 구현과 추상화의 분리

  • 구현 - 자주 변경되는 불안정한 부분. 자주 바뀌면 인터페이스라도 구현이다.

  • 추상화 - 자주 변경되지 않는 안정적인 부분. 인터페이스를 구현했는데 이게 자주바뀌면 아무 의미없다.

    e.g) 한 클래스 내에선 다 구현이라고 할 수 있다. getter / setter로 전달해주는 것과 속성을 public으로 노출하는 것은 큰 차이 없다.


캡슐화

: 인터페이스를 외부에 공개하고 자주 변하는 데이터를 인터페이스 뒤로 감춰놓는 것

  • 상태와 행동을 하나로 묶어놓는 것

  • 단순히 getter setter로 묶어놓는 것이 아니라 인터페이스로 노출한다는 관점

  • 타입 캡슐화: 자주 변하는 객체의 타입을 추상화 뒤로 캡슐화

    e.g) Movie의 입장에서 DiscountPolicy 타입이 숨겨진다. (AmountDiscount인지 PercentDiscount인지 숨겨진다.)

  • DIP(의존성 역전 원칙) : 상위 모듈(Movie)과 하위 모듈(AmountDiscount과 PercentDiscount) 모두 추상화(DiscountPolicy)에 의존

  • 컴포지트 디자인 패턴: 갯수가 변하는 것을 감춘다.(캡슐화)


객체지향 설계가 적합할 때?

: 복잡성을 알고리즘에서 분리하고 객체 간의 관계로 만들 수 있다. 유효성 검사, 계산, 파생 등이 포함된 복잡하고 끊임없이 변하는 비즈니스 규칙을 구현해야 한다면 객체 모델을 사용해 비즈니스 규칙을 처리하는 것이 현명하다. - 마틴 파울러


대부분 처음부터 객체지향적으로 잘 설계하는 것은 절대 불가능하다.

  • 요구사항이 어떻게 변경될 지 모르기 때문이다.
  • 리팩토링이 필수: 변경이 발생할 때마다 변경하기 쉬운 코드로 변경하는 것
  • 일단 절차지향적으로 작성하고, 변경이 발생해 응집도가 낮아지고, 결합도가 높아지는 시점마다 객체지향적으로 바꾸기.



Reference)

객체지향의 사실과 오해 조영호님 강의

This post is licensed under CC BY 4.0 by the author.