[오브젝트 01] 객체와 설계

초보개발·2022년 11월 29일
0

오브젝트

목록 보기
3/6

설계도

오브젝트 01 github 코드

문제점

로버트 마틴이 말하는 소프트웨어 모듈이 가져야 하는 세가지 기능

  • 모듈: 크기와 상관없이 클래스나 패키지, 라이브러리와 같은 프로그램을 구성하는 임의의 요소
  1. 모듈의 존재 이유 - 실행 중에 제대로 동작하는 것
  2. 변경을 위해 존재하는 것
    대부분 생명주기 동안 변경되므로 간단한 작업으로도 변경 가능해야 함, 변경하기 어려운 모듈은 제대로 동작하더라도 개선해야 함!
  3. 코드를 읽는 사람과 의사소통하는 것
    특별한 훈련없이도 코드를 쉽게 읽고 이해할 수 있어야 함, 의사소통 가능해지도록 모듈을 개선해야 함

앞서 구현한 프로그램의 경우, 첫번째 모듈의 목적을 달성했으나 변경 용이성과 코드 가독성을 만족시키지 못함

예상을 빗나가는 코드

Theater 클래스의 enter 메서드가 하는 일

  • 소극장은 관람객의 가방을 열어 그 안에 초대장이 있는지 확인
    있다면 매표소에 있는 티켓을 가방 안으로 이동
    없다면 금액만큼 현금을 꺼내 매표소에 적립후 티켓을 가방 안으로 이동

문제는 관람객과 판매원이 소극장의 통제를 받는 수동적인 존재라는 점

이해 가능한 코드: 그 동작이 우리의 예상에서 크게 벗어나지 않는 코드

이 코드는 우리의 예상에서 벗어나는 코드이기 때문에 코드를 읽는 사람과 의사소통을 할 수 없음

  • 관람객의 가방을 소극장이 마음대로 확인하고 돈을 가져가는 점
    -> 현실에서는 관람객이 직접 돈을 꺼내 판매원에게 지불
  • 소극장이 판매원 허락없이 매표소에 보관중인 티켓과 돈을 마음대로 접근할 수 있는 점
    -> 판매원은 매표소에 있는 티켓을 직접 꺼내 관람객에게 건내고 관람객의 돈을 직접 받아 매표소에 보관

또한, 이 코드를 이해하기 위해 여러가지 세부적인 내용들을 한꺼번에 기억하고 있어야 한다는 문제도 갖고 있음

  • Theater의 enter 메서드를 이해하기 위해 Audience가 Bag을 갖고 있고 Bag 안에는 현금과 티켓이 들어 있으며
    TicketSeller는 TicketOffice에서 티켓을 판매하고 TicketOffice 돈과 티켓이 보관되어 있다는 모든 사실을 다 알고 있어야 함

즉, 하나의 클래스나 메서드에서 너무 많은 세부사항을 다루기 때문에 코드를 작성하는 사람뿐만 아니라 코드를 읽고 이해하는 사람에게 큰 부담을 주게 됨

가장 심각한 문제는 Audience, TicketSeller를 변경할 경우 Theater도 함께 변경해야 하는 문제

변경에 취약한 코드

관람객이 현금과 초대장을 보관하기 위해 항상 가방을 들고다닌다고 가정
Audience 클래스에서 Bag을 제거하고 Audience의 Bag에 직접 접근하는 Theater의 enter 메서드도 수정해야 함

  • Theater는 관람객이 가방을 들고 있고 판매원이 매표소에서만 티켓 판매한다는 세부적인 사실에 의존해 있음

이처럼, 세부적인 사실에 의존해 있는 구조라면 세부적인 사실 중 하나만 변경이 되더라도 해당 클래스 뿐만아니라 의존하는 다른 클래스들까지 변경해야 하는 번거로움이 발생
(다른 클래스가 Audience의 내부에 대해 더 많이 알면 알수록 Audience를 변경하기 까다로워짐)

객체 사이의 의존성(Dependency)와 관련된 문제
의존성이 변경에 대한 영향을 암시함
즉, 의존성은 어떤 객체가 변경될 때 그 객체에게 의존하는 다른 객체도 함께 변경될 수 있다는 사실이 포함되어 있음

애플리케이션 기능을 구현하는데 필요한 최소한의 의존성만 유지하고 불필요한 의존성을 제거해가는 것이 목표!

객체 사이의 의존성이 과한 경우를 가리켜 결합도(coupling)이 높다고 말함
반대로, 객체들이 합리적인 수준으로 의존할 경우 결합도가 낮다고 말할 수 있음

설계의 목표 - 객체 사이의 결합도를 낮춰 변경 용이한 설계를 만드는 것

개선

로버트 마틴이 이야기한 세가지 목적중 두가지 조건을 만족시키기 위해 개선해야 함

우리의 예상을 벗어나는 코드

  • Theater가 Audience와 TicketSeller에 관해 너무 세세한 부분까지 알지 못하도록 정보를 차단
  • 관람객이 가방을 가진 사실과 판매원이 매표소에서 티켓을 판매한다는 사실을 Theater가 알 필요가 없음 -> Theater는 관람객이 소극장에 입장하는 것 뿐

관람객이 스스로 가방안의 현금과 초대장을 처리하고 판매원이 스스로 매표소의 티켓과 판매 요금을 다루게 한다면 문제 해결 가능 (즉, 판매원과 관람객을 자율적인 존재로 만들자)

자율성을 높이자

설계 변경의 어려움: Theater에서 Audience, TicketSeller이외에도 Audience 내의 Bag과 TicketSeller가 근무하는 TicketOffice까지 마음대로 접근하기 때문

해결 방법: Audience와 TicketSeller가 직접 Bag, TicketOffice를 처리하는 자율적인 존재가 되도록 설계를 변경하는 것

Theater의 enter() -> TicketSeller의 sellTo()로 이동
TicketSeller에서 getTicketOffice() 메서드가 제거되어 더 이상 외부에서 ticketOffice 필드에 접근할 수 없게 됨
따라서 TicketSeller는 ticketOffice에서 티켓, 요금 관리를 스스로 수행하게 됨

이처럼 개념적이나 물리적으로 객체 내부의 세부적인 사항을 감추는 것을 캡슐화(encapsulation)이라고 함
캡슐화는 변경하기 쉬운 객체를 만드는 것이 목적
캡슐화를 통해 객체 내부로의 접근을 제한하면 객체 간의 결합도를 낮출 수 있으므로 설계를 쉽게 변경하게 됨

  • 변경 후 TicketSeller와 Audience 사이의 결합도가 낮아짐

Audience와 TicketSeller는 자신이 갖고 있는 소지품을 스스로 관리하게 변경됨으로써 코드를 읽는 사람과의 의사소통이 개선되었음
더 중요한 것은 두 클래스의 내부를 개선하더라도 Theater를 함께 변경할 필요가 없어짐

캡슐화와 응집도

객체 내부 상태를 캡슐화하고 객체 간에 오직 메시지를 통해서만 상호작용할 수 있도록 만드는 것

  • Theater는 TicketSeller 내부에 대해 알지 못함, TicketSeller sellTo 메시지만 이해하고 응답할 수 있는 사실만 앎
  • TicketSeller는 Audience의 내부에 대해 알지 못하며 Audience가 buy 메시지에 이해하고 응답할 사실만 앎

밀접하게 연관된 작업만 수행하고 연관성 없는 작업은 다른 객체에게 위임하는 객체를 가리켜 응집도(cohesion)이 높다고 말함
자신의 데이터를 스스로 처리하는 자율적인 객체를 만들면 결합도를 낮출 수 있으며 응집도도 높일 수 있음

0개의 댓글