You will be fine

<디자인패턴입문> 13. Mediator 패턴

by BFine
반응형

 

www.yes24.com/Product/Goods/2918928

 

Java 언어로 배우는 디자인 패턴 입문

이 책은 디자인 패턴의 입문서입니다. GoF가 정리한 23개의 디자인 패턴을 하나씩 다루면서 객체 지향을 잘 모르는 초보자도 이해하기 쉽도록 정리하고 있습니다. 단순한 이론이나 논리을 제시하

www.yes24.com

가. 무엇인가

 a. 중개인

  -  서로 같은 입장의 회원들이 공동작업을 하는데 정리가 안되어서 옥신각신하는 모임을 상상해보자

      => 공유도 안되고 정신사나우니 상황을 정리하기 위해 중개인을 고용하자

  -  이제 회원들은 중개인에게만 보고하고 중개인만이 회원에게 지시를 내릴수있게 만들었다.

      => 회원들끼리의 상황파악하거나 서로 지시를 내리는 일이 없어졌다.

  -  이렇게 중간에 중개자를 두어 역할을 정리하는 패턴이 Mediator(조정자,중개자) 패턴이다.

 

나. 만들어본 예제

중개인을 통해 경매하는 예제

 a. Mediator (중개자) 역할

  -  조정을 실행하기 위한 추상클래스, 참여하는 Colleague들을 가지고 있는다. 

  -  Colleague로부터 요청을 받는 부분과 결과(변경)을 알리는 부분의 인터페이스를 명세한다.  

public abstract class Mediator {
   List<Colleague> colleagueList = new ArrayList<>();

   public void addCollege(Colleague colleague){
      colleagueList.add(colleague);
   }

   protected abstract void mediate(Colleague colleague, int paid);
   //Colleague에서 요청하는 메서드 
   
   protected abstract void round(String product);
   protected abstract void result();
}

 b. ConcreteMediator (구체적인 중개자) 역할

  -  예제에서는 Colleage들로부터 입찰내역을 받고 결과를 Colleage로 알려주는 역할을 한다.

public class AuctionMediator extends Mediator{

    Map<Colleague,Integer> bidMap;
    String product;

    public AuctionMediator() {
        this.bidMap = new WeakHashMap<>();
    }

    @Override
    protected void round(String product) {
        this.product = product;
        this.bidMap = new WeakHashMap<>();
    }

    @Override
    protected void mediate(Colleague colleague, int paid) {
        bidMap.put(colleague,paid);
    }

    @Override
    protected void result() {

        List<Colleague> colleagues = new ArrayList<>(bidMap.keySet());
        colleagues.sort((o1,o2)->Integer.compare(bidMap.get(o2), 
        									     bidMap.get(o1)));
        boolean isWinner = true;
        for (Colleague colleague: colleagues) {
            if(isWinner){
                colleague.win(product);
                // 낙찰된 상품을 준다.
                isWinner = false;
            }else {
                colleague.lose(bidMap.get(colleague));
                // 유찰된 금액을 돌려준다.
            }
        }
    }

}

 c. Colleague(동료) 역할

  -  Mediator 역할과 통신할 인터페이스를 결정한다. 모든 처리를 Mediator로 위임한다.

public abstract class Colleague {
    Mediator mediator;

    public Colleague(Mediator mediator) {
        this.mediator = mediator;
    }

    protected abstract void bidding(int paid);
    protected abstract void win(String product);
    protected abstract void lose(int paid);

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        return Objects.equals(mediator, o);
    }

    @Override
    public int hashCode() {
        return Objects.hash(mediator);
    }
}

 d. ConcreteColleague(구체적인 동료) 역할

  -  예제에서는 경매에 참여하는 사람 역할을 한다.

public class KoreanColleague extends Colleague{

    private int balance;
    private List<String> collection;

    public KoreanColleague(Mediator mediator, int balance) {
        super(mediator);
        this.balance = balance;
        collection = new ArrayList<>();
    }


    @Override
    protected void bidding(int paid) {
        balance -=paid;
        mediator.mediate(this,paid);
    }

    @Override
    protected void win(String product) {
        collection.add(product);
    }

    @Override
    protected void lose(int paid) {
        balance +=paid;
    }

    public int getBalance() {
        return balance;
    }

    public String getCollection() {
        return String.join(",", collection);
    }
}

// JapaneseColleage, ChineseColleague 동일한 내용

 e. Main

public class Main {

    public static void main(String[] args) {

        Mediator mediator = new AuctionMediator();

        ChineseColleague ch = new ChineseColleague(mediator,10000);
        KoreanColleague ko = new KoreanColleague(mediator,30000);
        JapaneseColleage ja = new JapaneseColleage(mediator,20000);

        mediator.addCollege(ch);
        mediator.addCollege(ko);
        mediator.addCollege(ja);

        mediator.round("Tablet");
        ko.bidding(3000);
        ja.bidding(1000);
        ch.bidding(2000);
        mediator.result();

        mediator.round("Computer");
        ko.bidding(6000);
        ja.bidding(5500);
        ch.bidding(5000);
        mediator.result();

System.out.println("Korean  Collection["+ko.getCollection()+"]  
					잔액 : "+ko.getBalance());
System.out.println("Japanese Collection["+ja.getCollection()+"] 
					잔액 : "+ja.getBalance());
System.out.println("Chinese  Collection["+ch.getCollection()+"] 
					잔액 : "+ch.getBalance());
    }
}
/**
"C:\Program Files\Java\jdk1.8.0_251\bin\java.exe" 
Korean  Collection[Tablet,Computer]  잔액 : 21000
Japanese Collection[] 잔액 : 20000
Chinese  Collection[] 잔액 : 10000
*/

다. 정리

 a. 분산이 화를 부를때

  -  객체지향에서는 한곳에 집중되는 것을 피해서 처리를 분산시키는 경우가 많다.

  -  하지만 예제처럼 같은 입장에 있는 객체간에 sync를 서로 맞춰야하는 경우에 오히려 복잡해질 수 있다.

  -  무조건적인 분산이 아닌 집중시킬 필요가 있는 부분에 대해서는 집중시키는 것이 현명하다.

 

 b. 재이용할수 있는 것은 무엇인가

  -  ConcreateColleage 역할은 재이용하기 쉽지만 ConcreteMediator 역할은 재이용하기 어렵다.

     => ConcreteMediator는 Colleage로부터의 의존도가 크기때문이다.

Mediator은 복잡한 관계를 맺은 객체들 사이에 중개자를 추가해 처리, 통보를 중개자에게 일임하는 패턴이다.
반응형

블로그의 정보

57개월 BackEnd

BFine

활동하기