라즈베리파이반

라즈베리파이 등 컴퓨터계열 게시판입니다.

제목디자인 패턴(Design Pattern) : 중재자 / 옵저버2022-07-24 13:34
작성자user icon Level 4

88x31.png


1. 중재자 패턴(Mediator Pattern)


중재자 패턴은 객체들 간의 상호작용을 캡슐화하여 하나의 클래스에 위임하여 처리하는 패턴입니다. 객체 간의 직접적인 상호작용보다 중재자를 두어 간접적으로 상호작용 하도록 하는 것입니다. 이렇게 되면 컴포넌트 사이의 복잡한 M:N의 의존관계가 중재자와의 M:1의 의존관계가 되므로 결합도를 감소시킬 수 있게 됩니다.


5tAhdYJfQ1rEXENdxm586dTjehLHhMzikAAAAAjmL6CgAAAOAwknIAAADAYSTlAAAAgMNIygEAAACHkZQDAAAADiMpBwAAABxGUg4AAAA4jKQcAAAAcBhJOQAAAOAwknIAAADAYSTlAAAAgMP+H4JfnDzRfRfhAAAAAElFTkSuQmCC

Mediator는 BaseComponent와 상호작용하기 위한 인터페이스를 제공하며, ConcreteMediator는 이 인터페이스를 구현합니다. Component는 Mediator를 통해 다른 Component와 상호작용 할 수 있습니다.


예제 코드를 작성하겠습니다. 웹채팅을 하는 시나리오 입니다.


Mediator.java:

y3LbAghxJQkeRBCCCF0yRCTEEIIXdJBCCGE0BXyM4j4+PiJaIcQQogoI3cQQgghdIW91Mb4+Hgk2yGEECLKyB2EEEIIXdJBCCGE0CUdhBBCCF3SQQghhNAlHYQQQghd0kEIIYTQJR2EEEIIXdJBCCGE0CUdhBBCCF3SQQghhNAlHYQQQghd0kEIIYTQJR2EEEIIXf8PxjE7DJD6tPQAAAAASUVORK5CYII= 

중재자 인터페이스 입니다. 유저를 추가하거나 제거하고, 각 유저에게 메시지를 보냅니다.


ConcreteMediator.java:

qVfXY336n5AAAAAElFTkSuQmCC

중재자 인터페이스를 구현한 클래스 입니다. 유저들을 관리하며, 각 유저들에게 메시지를 전송합니다.


Colleague.java:

j8kezwD64K05wAAAABJRU5ErkJggg== 

유저를 추상화한 클래스 입니다. 중재자를 멤버변수로 가지며, 메시지를 전송하거나 수신받을 수 있습니다.


ConcreteColleague.java:

wFQZeoyoOvKFgAAAABJRU5ErkJggg== 

추상화된 유저 인터페이스를 구현한 클래스입니다.  메시지의 전송은 중재자에게 전송하는 것을 볼 수 있습니다.


Chat.java:

Cv9zG1IilxNRIREZGb3nW0YFwlNXk8H36g4EJEREQCaZCniIiIJJwCDBEREUk4BRgiIiKScNe3FknPPfy9XhMuIiIiQa5jLRIRERGR8NRFIiIiIgmnAENEREQSTgGGiIiIJJwCDBEREUk4BRgiIiKScAowREREJOEUYIiIiEjCKcAQERGRhFOAISIiIgmnAENEREQSTgGGiIiIJJwCDBEREUk4BRgiIiKScAowREREJOH+f1309AVDhnruAAAAAElFTkSuQmCC 

채팅을 하는 클래스입니다. 중재자와 각 유저들을 생성하고, user1 객체가 메시지를 전송하면 중재자를 통해 모든 유저들에게 메시지가 전송됨을 확인할 수 있습니다.


5X0+KZE3G9aAAAAAElFTkSuQmCC 

여기서는 로그를 통해서 모든 메시지가 출력되었지만, 실제로는 유저마다 메시지가 출력됩니다.


중재자 패턴은 하나의 중재자를 통해 M:1로 연결되어 있기 때문에 전체적인 연결 관계를 파악하기 쉬운 반면에 중재자가 특정 어플리케이션의 로직에 맞추어 만들어지기 때문에 재사용하기 어렵다는 단점이 있습니다.



2. 옵저버 패턴(Observer Pattern)


옵저버 패턴은 객체의 상태를 관찰하는 옵저버를 두어 변화가 있으면 종속된 객체들에게 통지하도록 하는 패턴입니다. 이전에 설명한 MQTT나 ROS의 통신 방식인 발행-구독 패턴(Publisher-Subscriber Pattern)과 유사합니다.


R+cJ+Kzm0w0BAAAAABJRU5ErkJggg==

Subject는 발행자(Publisher)의 인터페이스이며, Observer에 의해 관찰됩니다. ConcreteSubject는 발행자를 구현한 클래스 입니다. Observer는 발행자의 상태를 관찰하는 옵저버 객체의 인터페이스이며, ConcreteObserver에 의해 구현됩니다. ConcreteObserver는 ConcreteSubject 객체에 대한 참조자를 관리합니다.


다수의 옵저버가 하나의 객체와 상호작용한다는 점에서 중재자 패턴과 유사해 보이지만, 중재자 패턴은 M개의 발행자(Publisher)와 N개의 구독자(Subscriber)가 서로서로 상태를 관찰하는 반면에 옵저버 패턴은 1개의 발행자(Publisher)에 대하여 N개의 구독자(Subscriber)가 상태를 관찰합니다. 다시 말해서 중재자 패턴은 양방향 통신을, 옵저버 패턴은 단방향 통신을 합니다.


예제 코드를 작성해 보겠습니다. 새로운 글이 작성되면 알림 메시지가 오는 시나리오 입니다.


Subject.java:

DzOSNkOBOsqSAAAAAElFTkSuQmCC 

발행자 인터페이스 입니다.


ConcreteSubject.java:

dqGsAAAAASUVORK5CYII= 

발행자 인터페이스를 구현한 클래스 입니다. 옵저버들을 관리하며, 발행자의 상태를 알립니다.


Observer.java:

06Abk+EGfDCAAAAAElFTkSuQmCC 

옵저버의 인터페이스 입니다.


ConcreteObserver.java:

9g7lOxTRHhUAAAAASUVORK5CYII= 

옵저버 인터페이스를 구현한 클래스 입니다. 옵저버의 구분을 위해 name을 주었습니다.


Client.java:

QwqHTxKUWtAAAAABJRU5ErkJggg== 

클라이언트 클래스 입니다. 모델을 하나의 발행자로 생성하고, 다수의 뷰가 모델을 구독하는 형태입니다.


MAAAAASUVORK5CYII= 

중재자 패턴과 마찬가지로 여기서는 모든 로그가 출력되지만, 실제로는 뷰마다 새로운 글에 대한 알림이 뜰 것입니다. 출력된 로그를 보면 3번째 글이 등록되기 전에 view2 객체가 구독취소를 했기 때문에 view2 객체에게는 3번째 글 등록 알림이 가지 않는 것을 확인할 수 있습니다.


옵저버 패턴은 위의 예제와 같이 MVC 패턴(Model-View-Controller Pattern)에서 사용하는 패턴입니다. 하나의 모델 상태를 다수의 View가 관찰하고 있다가 모델의 상태에 따라 각각 반응하게 됩니다.


자바에서는 내부적으로 옵저버 패턴을 구현할 수 있도록 Observer 인터페이스와 Observable 클래스를 제공하고 있습니다.

#디자인 패턴# 중재자 패턴# 옵저버 패턴
댓글
자동등록방지
(자동등록방지 숫자를 입력해 주세요)