Skip to content

Chapter 01. 객체, 설계

Published: at 오후 02:46

Table of contents

Open Table of contents

티켓 판매 애플리케이션 구현하기

이벤트 요구사항

img_2.png

무엇이 문제인가

마틴에 따르면 모든 모듈은 실행돼야 하고, 변경이 용이해야 하며, 이해하기 쉬워야 한다. 앞에 프로그램은 변경 용이성과 읽는 사람과의 의사소통이라는 목적은 만족시키지 못한다.

예상을 빗나가는 코드

public class TicketSeller {
  private TicketOffice ticketOffice;

  public TicketSeller(TicketOffice ticketOffice) {
    this.ticketOffice = ticketOffice;
  }

  public void sellTo(Audience audience) {
    if (audience.getBag().hasInvitation()) {
      Ticket ticket = ticketOffice.getTicket();
      audience.getBag().setTicket(ticket);
    } else {
      Ticket ticket = ticketOffice.getTicket();
      audience.getBag().minusAmount(ticket.getFee());
      ticketOffice.plusAmount(ticket.getFee());
      audience.getBag().setTicket(ticket);
    }
  }
}

변경에 취약한 코드

설계 개선하기

자율성을 높이자

1. Theaterenter 메서드를 TicketSeller의 내부로 숨긴다. (캡슐화)

public class TicketSeller {
  private TicketOffice ticketOffice;

  public TicketSeller(TicketOffice ticketOffice) {
    this.ticketOffice = ticketOffice;
  }

  public void sellTo(Audience audience) {
    ticketOffice.plusAmount(audience.buy(ticketOffice.getTicket()));
  }
}
  1. Bag의 접근하는 모든 로직을 Audience 내부로 감춘다.
public class Audience {
  private Bag bag;

  public Audience(Long amount) {
    bag = new Bag(amount);
  }

  public Long buy(Ticket ticket) {
    if (bag.hasInvitation()) {
      bag.setTicket(ticket);
      return 0L;
    } else {
      bag.setTicket(ticket);
      bag.minusAmount(ticket.getFee());
      return ticket.getFee();
    }
  }
}

img.png

무엇이 개선됐는가

어떻게 한 것인가

판매자가 티켓을 판매하기 위해 TicketOffice를 사용하는 모든 부분을 TicketSeller 내부로 옮기고, 관람객이 티켓을 구매하기 위해 Bag을 사용하는 모든 부분을 Audience 내부로 옮겼다. => 자신의 문제를 스스로 해결하도록 코드를 변경한 것이다.

캡슐화와 응집도

절차지향과 객체지향

책임의 이동

더 개선할 수 있다

public class Bag {
  private Long amount;
  private Ticket ticket;

  public Bag(Long amount) {
    this.amount = amount;
  }

  public Long hold(Ticket ticket) {
    if (hasInvitation()) {
      setTicket(ticket);
      return 0L;
    } else {
      setTicket(ticket);
      minusAmount(ticket.getFee());
      return ticket.getFee();
    }
  }

  private boolean hasInvitation() {
    return false;
  }

  private void setTicket(Ticket ticket) {
    this.ticket = ticket;
  }

  private void minusAmount(Long amount) {
    this.amount -= amount;
  }
}

그래, 거짓말이다!

객체지향 설계

설계가 왜 필요한가

객체지향 설계