본문 바로가기

[객체지향의 사실과 오해] Chapter 1 - 협력하는 객체들의 공동체

by 꾸진 2022. 5. 24.

커피 공화국의 아침

  • 역할
    • 손님: 커피를 주문
    • 캐시어: 주문을 받음
    • 바리스타: 커피를 제조
  • 책임
    • 손님: 카페인을 채우기 위해 커피를 주문할 책임
    • 캐시어: 주문된 커피를 바리스타에게 제조하라고 전달하는 책임
    • 바리스타: 주문된 커피를 제조하는 책임
  • 협력
    • 커피 주문을 위해 손님, 캐시어, 바리스타가 협력한다.
class CofferOrderFactory{
    Customer customer = new Customer();
    Cashier cashier = new Cashier();
    Barista barista = new Barista();

    String selectedMenu = "ice americano";

    customer.orderCoffee(selectedMenu, cashier);

    cashier.commandCoffee(customer.selectedMenu, barista);

    barista.makeCoffee(cashier.menu);
}
class Customer {
    String selectedMenu; // 고객이 선택한 메뉴
    Cashier cashier; // 고객의 주문을 받은 캐시어

    void orderCoffee(String selectedMenu, Cashier cashier) {
        // 커피를 주문할 책임
        this.selectedMenu = selectedMenu;
        this.cashier = cashier;
        System.out.println("cashier에게" + this.menu + "를 주문했습니다.");
    }
}
class Cashier {
    String orderedMenu; // 고객이 주문한 메뉴
    Barista barista;// 커피를 제조할 바리스타

    void commandCoffee(String orderedMenu, Barista barista) {
        // 바리스타에게 커피를 제조하라고 명령하는 책임
        this.orderedMenu = orderedMenu;
        this.barista = barista;
        System.out.println("barista에게 주문된 메뉴인" + this.orderedMenu + "를 제조하라고 했습니다.");
    }
}
class Barista {
    String orderedMenu; //캐시어로부터 제조하라고 전달받은 메뉴

    void makeCoffee(String orderedMenu) {
        // 캐시어로부터 전달받은 메뉴를 제조할 책임
        this.ordereMenu = orderedMenu;
        System.out.println("cashier로부터 전달받은 메뉴인" + this.orderedMenu + "를 제조했습니다.");
    }
}

 

역할

  • 특정한 역할은 특정한 책임을 암시한다.
  • 여러 사람이 동일한 역할을 수행할 수 있다.
  • 역할은 대체 가능성을 의미한다.
    • 캐시어A와 캐시어B가 존재한다고 했을때, 고객은 둘 중 누가 역할을 수행하더라도 문제가 되지 않는다.
Customer customer = new Customer();
Cashier cashierAlice = new Cashier();
Cashier cashierBob = new Cashier();

customer.orderCoffee(selectedMenu, cashierAlice);
customer.orderCoffee(selectedMenu, cashierBob);
// cashierAlice, cashierBob 중 누구에게 주문해도 문제가 되지 않는다.
// Alice가 바쁘면 Bob에게 주문해도 되고, Bob이 바쁘면 Alice에게 주문하면 된다.

 

  • 책임을 수행하는 방법은 자율적이다.
    • 요청을 받은 사람들은 요청을 처리하는 방법을 자유롭게 선택할 수 있다.
    • 동일한 요청을 받더라도 역할을 수행하는 사람들마다 서로 다른 방식으로 요청을 처리할 수 있다. (다형성)
interface Barista {
    void commandCoffee(String orderedMenu);
}

class starbucksBarista implements Barista {
    public void makeCoffee(String orderedMenu) {
        makeStarbucksCoffee();
        ...
    }
}

class twoSomeBarista implements Barista {
    public void makeCoffee(String orderedMenu) {
        makeTwosomeCoffee();
        ...
    }
}
Barista baristaAlice = new starbucksBarista();
Barista baristaBob = new twoSomeBarista();
baristaAlice.makeCoffee();
baristaBob.makeCoffee();
//makeCoffee()라는 동일한 요청에 대해 서로 다른 방식으로 커피를 제조할 수 있다.

 

  • 하나의 객체가 여러 역할을 수행할 수 있다.
    • 만약 바리스타가 없을때 Cashier가 Barista 클래스를 extends 해서 사용한다면 된다.
    • 즉, 한 사람이 동시에 둘 이상의 역할을 수행하는 것도 가능하다.
class Cashier extends Barista{
    String orderedMenu;
    Barista barista;

    void commandCoffee(String orderedMenu, Barista barista) {
        ..doSomething
    }
}

 

만약 캐시어가 바리스타를 상속해서 사용한다면, 아래와 같이 캐시어가 바리스타의 역할을 수행할 수도 있다.

Cashier cashier = new Cashier();
cashier.makeCoffee(); // 캐시어가 커피를 만들 수 있다.