[디자인 패턴] Mediator 패턴

이멀젼씨

·

2020. 3. 23. 10:52

- 정의

 

다대다 관계에서 일대다 관계로 만들어주는 패턴이다

 

- UML

1. Cook인터페이스는 배달원(중재자)을 설정하는 setMediator메소드와 음식을 만드는 makeFood메소드를 갖는다

2. Cook인터페이스를 구현한 ChineseChef, JapaneseChef, KoreanChef는 메소드를 오버라이딩하여 구현한다

3. Mediator클래스는 배달할 음식을 받는 deliveryFood메소드와 주문 고객을 추가하는 addCutomer메소드를 갖는다

4. Customer인터페이스는 음식을 받는 receiveFood메소드를 갖는다

5. Customer인터페이스를 구현하는 Apartment, Villa, Office클래스는 receiveFood메소드를 오버라이딩한다

 

- 코드

 

Cook interface

public interface Cook {
	public void setMediator(Mediator mediator);
	public void makeFood(String food);
}

ChineseChef class

public class ChineseChef implements Cook{
	private Mediator mediator;

	public void setMediator(Mediator mediator) {
		this.mediator = mediator;
	}
	
	public void makeFood(String food) {
		mediator.deliverFood("중식", food);
	}
	
}

JapaneseChef class

public class JapaneseChef implements Cook{
	private Mediator mediator;

	public void setMediator(Mediator mediator) {
		this.mediator = mediator;
	}
	
	public void makeFood(String food) {
		mediator.deliverFood("일식", food);
	}
	
}

KoeranChef class

public class KoreanChef implements Cook{
	private Mediator mediator;

	public void setMediator(Mediator mediator) {
		this.mediator = mediator;
	}
	
	public void makeFood(String food) {
		mediator.deliverFood("한식", food);
	}
	
}

Mediator class

import java.util.ArrayList;
import java.util.List;

public class Mediator {
	private List<Customer> customers = new ArrayList<>();
	
	public void addCustomer(Customer customer) {
		customers.add(customer);
	}
	
	public void deliverFood(String chef, String food) {
		for(Customer customer : customers) {
			customer.receiveFood(chef, food);
		}
	}
}

Customer interface

public interface Customer {
	public void receiveFood(String chef, String food);
}

Apartment class

public class Apartment implements Customer{
	@Override
	public void receiveFood(String chef, String food) {
		System.out.println("아파트 거주자가 "+chef+"요리사의 "+food+"을(를) 배달받았습니다");
	}
}

Villa class

public class Villa implements Customer{
	@Override
	public void receiveFood(String chef, String food) {
		System.out.println("빌라 거주자가 "+chef+"요리사의 "+food+"을(를) 배달받았습니다");
	}
}

Office class

public class Office implements Customer{
	@Override
	public void receiveFood(String chef, String food) {
		System.out.println("사무실 근무자가 "+chef+"요리사의 "+food+"을(를) 배달받았습니다");
	}
}

Main class

public class Main {
	public static void main(String[] args) {
		Mediator deliveryMan = new Mediator();
		
		JapaneseChef jChef = new JapaneseChef();
		ChineseChef cChef = new ChineseChef();
		KoreanChef kChef = new KoreanChef();
		
		jChef.setMediator(deliveryMan);
		cChef.setMediator(deliveryMan);
		kChef.setMediator(deliveryMan);
		
		deliveryMan.addCustomer(new Office());
		deliveryMan.addCustomer(new Apartment());
		deliveryMan.addCustomer(new Villa());
		
		jChef.makeFood("초밥");
		kChef.makeFood("꿔바로우");
		
		
	}
}

출력결과

사무실 근무자가 일식요리사의 초밥을(를) 배달받았습니다
아파트 거주자가 일식요리사의 초밥을(를) 배달받았습니다
빌라 거주자가 일식요리사의 초밥을(를) 배달받았습니다
사무실 근무자가 한식요리사의 꿔바로우을(를) 배달받았습니다
아파트 거주자가 한식요리사의 꿔바로우을(를) 배달받았습니다
빌라 거주자가 한식요리사의 꿔바로우을(를) 배달받았습니다

 

- 설명

 

중간에 배달원이 없다면 한식, 일식, 중식 요리사는 아파트와 빌라, 사무실을 직접 방문을 해야 한다

 

이렇게 되면 결합도가 높아지고 코드의 가독성이 떨어지게 된다

 

따라서 중간에 배달원을 두어 만든 요리는 배달원에게 전달하는 다대일 관계를 형성하고, 배달원은 주문을 한 고객들에게 전달하는 일대다 관계를 만들어 결합도와 코드의 복잡성을 낮출 수 있다

 

퍼사드 패턴과 옵저버 패턴이 이와 유사하다

 

장점

복잡한 관계를 단순화 시킴

효율적인 자원관리를 가능케 함

서로 간에 직접 참조할 필요를 없애줌

 

단점

객체 간의 통신 로직이 복잡해지거나 객체의 형태가 자주 변경되는 경우 유지보수, 관리가 어려움