CS/디자인패턴

[디자인패턴] Mediator 패턴 (중개자 패턴)

mabb 2023. 6. 22. 22:25
반응형

▶디자인 패턴 ( Design Pattern)

:프로그램 개발 시 문제 해결을 위하여 빈번히 사용되는 개발자들의 경험, 내적인 축적에 대하여,
GoF(Gang of Four) 라 불리는 4인의 개발자들이 각각을 패턴으로 정의하고 이름을 붙였다.
이를 디자인 패턴 (Design Pattern)이라고 한다.
 23개의 디자인 패턴을
『Elements of Reusable Object-Oriented Software』
라는 책으로 발간하였다.

Gang of Four 분들은 모두 안경을 썼다.

 

▷디자인 패턴의 용어를 빌리면 서로의 아이디어를 보다 용이하게 비교, 논의할 수 있게 된다.
▷재사용과 기능확장이 쉬운 소프트웨어를 만들기 위한 유익한 기법이 바로 디자인 패턴이다.

 

---------------------------------------------------------
1. Iterator
2. Adapter
3. Template Method
4. Factory Method
5. Singleton
6. Prototype
7. Builder
8. Abstract Factory
9. Bridge
10. Strategy
11. Composite
12. Decorator
13. Visitor
14. Chain of Responsibility
15. Facade
16. Mediator
17. Observer
18. Memento
19. State
20. Flyweight
21. Proxy
22. Command
23. Interpreter
---------------------------------------------------------

▶Mediator 패턴

"중개자와 회원들"
"회원들은 중개자 하고만 통신"
"중개자는 모든 회원을 가지고 있다"
"회원들은 자신의 변화 및 동작 시 중개자에게 알린다"
"중개자는 회원들의 동작 및 상태를 확인하고 회원들을 컨트롤한다"


-왜 사용하는가
-클래스다이어그램
-각 클래스(인터페이스)의 역할
-Java소스

▶Mediator패턴에 대한 이해

-Mediator를 중개인, 중개가 필요한 각 회원을 Colleague라고 칭한다.

-여러 객체(회원)가 서로 통신을 주고받으며 서로의 상태에 대해 영향을 주고 특정 기능을 구현해야 할 때
기능은 객체 중 어디에 구현해야 할까?

-다수의 오브젝트가 서로 통신을 하지 않고 중개인하고만 통신을 하는 것이 중개자 패턴이다.

-다수의 오브젝트의 상호작용을 기반으로 동작하는 기능은 중개자가 구현한다.

-중개자는 모든 회원을 가지고 있다.

-각각의 회원은 중개자를 가지고 있다.

-중개자는 한 회원의 상태에 따라 다른 회원의 동작을 구현할 수 있다.

 

▶왜 사용하는가

여러 오브젝트 간 서로 통신을 하면서 서로 상태 및 동작을 확인해서 각각 특정 기능을 수행해야 한다고 할 때 굉장히 복잡해질 수가 있다. 이때 오브젝트 상호 간에 통신을 하지 않고 모든 오브젝트들이 중개자 하고만 통신하며, 중개자가 오브젝트들의 상태 및 동작을 파악하고 회원들을 다루는 로직을 수행한다면 편리할 것이다. 중개자가 오브젝트들의 상태를 파악하여 여러 오브젝트 간의 로직을 구현한다.

 

▶클래스다이어그램

Mediator패턴의 클래스다이어그램

 

▶각 클래스(인터페이스)의 역할

▷중개자 역할

중개자는 중개 대상이 되는 모든 회원들을 생성하고 회원들의 동작 및 상태 변화를 체크할 수 있어야 한다.

▷구체적인 중개자 역할

모든 회원들을 생성하고 각각 회원들의 상태를 파악하여 회원들을 컨트롤하는 등 기능을 구현한다.

▷회원 역할

회원들은 중개자를 가지고 있다. 중개자가 컨트롤할 수 있는 기능을 선언한다.

▷구체적인 회원 역할

동작이나 상태 변화 시 중개자에게 이 사실을 알린다. mediator.colleagueChanged();

 

▷Main역할

여기에서는 중개자를 생성하여 기능을 구현하는 역할을 한다.

 

▶Java 소스

*java1.8 이전 버전을 사용하는 교재를 참고하였습니다.
Java API 문서 등을 참조하여 제네릭을 적용하는 등 소스를 개선할 필요가 있습니다.
(https://docs.oracle.com/en/java/javase/20/docs/api/)

 

3명의 회원이 있고 1명의 회원이 이름을 바꾸면 다른 두 명의 회원이 이름을 변경한 회원을 부른다. 다른 회원이 이름을 변경한 사실을 회원 본인이 직접 파악하고 다른 회원의 이름을 부르는 기능을 수행하는 것이 아니라, 각 회원들이 이름을 변경한 경우 이를 중개자에게 알리고 중개자는 이름을 변경하지 않은 회원들이 해당 회원을 부를 수 있도록 중개하고 있다. 

 

▷중개자 역할 - Mediator.java

package main.java.designpattern.mediator2;

public interface Mediator {
    public abstract void createColleagues();
    public abstract void colleagueChanged(Colleagues c);
}

▷구체적인 중개자 역할 - ConcreteMediator.java

package main.java.designpattern.mediator2;

public class ConcreteMediator implements Mediator{
    Colleagues colleagues1;
    Colleagues colleagues2;
    Colleagues colleagues3;



    @Override
    public void createColleagues() {
        colleagues1 = new ColleagueA("철수");
        colleagues2 = new ColleagueB("민수");
        colleagues3 = new ColleagueC("동수");

        colleagues1.setMediator(this);
        colleagues2.setMediator(this);
        colleagues3.setMediator(this);

        colleagues1.changeName("은우");
        colleagues2.changeName("동원");


    }
    @Override
    public void colleagueChanged(Colleagues c) {
        System.out.println("Colleague들의 변화를 확인합니다.");

        if(c instanceof ColleagueA){
            colleagues2.controlColleague(c);
            colleagues3.controlColleague(c);
        }else if(c instanceof ColleagueB){
            colleagues1.controlColleague(c);
            colleagues3.controlColleague(c);

        }else if(c instanceof ColleagueC){
            colleagues1.controlColleague(c);
            colleagues2.controlColleague(c);
        }
    }
}

 

▷회원 역할 - Colleagues.java

package main.java.designpattern.mediator2;

public interface Colleagues {
    public abstract void setMediator(Mediator mediator);
    public abstract void controlColleague(Colleagues c);
    public abstract String getName();
    public abstract void changeName(String name);
}

 

▷구체적인 회원 역할 

ColleagueA

package main.java.designpattern.mediator2;

public class ColleagueA implements Colleagues{
    private Mediator mediator;
    private String name;

    public ColleagueA(String name){
        this.name = name;
    }

    @Override
    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }

    @Override
    public void controlColleague(Colleagues c) {
        System.out.println(this.name + " : " + c.getName() + "야 이름 바꿨구나?");

    }

    public String getName(){
        return name;
    }

    public void changeName(String name){
        System.out.println(this.aname + "의 이름을 변경합니다.");
        System.out.println("변경 사실을 중개자에게 알립니다.");
        this.name = name;
        mediator.colleagueChanged(this);
    }
}

 

ColleagueB

package main.java.designpattern.mediator2;

public class ColleagueB implements Colleagues{
    private Mediator mediator;
    private String name;

    public ColleagueB(String name){
        this.name = name;
    }

    @Override
    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }

    @Override
    public void controlColleague(Colleagues c) {
        System.out.println(this.name + " : " + c.getName() + "야 이름 바꿨어?");

    }

    public String getName(){
        return name;
    }
    public void changeName(String name){
        System.out.println(this.name + "의 이름을 변경합니다.");
        System.out.println("변경 사실을 중개자에게 알립니다.");
        this.name = name;
        mediator.colleagueChanged(this);
    }


}

 

ColleagueC

package main.java.designpattern.mediator2;

public class ColleagueC implements Colleagues {
    private Mediator mediator;
    private String name;

    public ColleagueC(String name){
        this.name = name;
    }

    @Override
    public void setMediator(Mediator mediator) {

    }

    @Override
    public void controlColleague(Colleagues c) {
        System.out.println(this.name + " : " + c.getName() + "야 이름 바꿨니!?");

    }

    public String getName(){
        return name;
    }
    public void changeName(String name){
        System.out.println(this.name + "의 이름을 변경합니다.");
        System.out.println("변경 사실을 중개자에게 알립니다.");
        this.name = name;
        mediator.colleagueChanged(this);
    }


}

 

▷Main역할

package main.java.designpattern.mediator2;

public class Main {
    public static void main(String[] args){

        Mediator m = new ConcreteMediator();
        m.createColleagues();

    }
}

 

 

 

---------------------------------------------------------
※참고자료
-Java언어로 배우는 디자인 패턴 입문
-Headfirst Design Pattern
-나무위키, 위키백과, 네이버백과
-리팩토링구루(https://refactoring.guru/ko)

반응형