본문 바로가기
까망 동네/디자인 패턴

[디자인 패턴] 중재자 패턴 (Mediator Pattern)

by 까망 하르방 2023. 10. 22.
반응형

🎈 중재자 패턴 (Mediator Pattern) 

• 객체들이 직접 서로 참조하지 않도록 하여 객체들간 느슨한 결합 유지

• 객체들의 상호작용을 독립적으로 다양화 시킨다.

• 디자인 패턴에서 행위 패턴에 속한다.

 

💻 디자인 패턴(Design Pattern)이란?

👨‍💻 디자인 패턴(Design Pattern)이란? • SW 개발 방법 중에서도 구조적인 문제 해결에 목적을 둔다. • 알고리즘과 같이 특정 문제를 해결하는 Logic 형태보다는 특정 상황에 적용할 수 있는 방

zoosso.tistory.com


[예제 코드]

중재자 패턴이 적용되지 않은 예제

#include <iostream>
#include <string>

class User {
public:
    User(const std::string& name) : name(name) {}
    void sendMessage(const std::string& message, User* receiver) {
        puts("");
        std::cout << name << " sends message [To " << receiver->name << "]: " <<  message << std::endl;
        receiver->receiveMessage(message);
    }
    void receiveMessage(const std::string& message) {
        std::cout << name << " receives message: " << message << std::endl;
    }

private:
    std::string name;
};

void main() {
    User userA("User A");
    User userB("User B");

    userA.sendMessage("안녕 B!", &userB);
    userB.sendMessage("그래, 반가워 A", &userA);
}

 

두 User A, B가 직접적으로 통신하고 있다.

다른 User가 생기더라도 직접 메시지를 보낼 수 있다.

중재자 패턴 결과 예시

 

 

[예제 코드] - 중재자 패턴 적용

중재자와 통신하며, 중재자가 메시지 전달 역할을 수행한다.

사용자간 직접적인 결합이 느슨해지며

새로운 사용자나 단체방을 보다 쉽게 만들 수도 있다.

#include <iostream>
#include <string>
#include <vector>

class User;

class Mediator {
public:
    virtual void sendMessage(const std::string& message, User* sender, User* receiver)  = 0;
};

class User {
public:
    User(const std::string& name, Mediator* mediator) : name(name), mediator(mediator)  {}
    void sendMessage(const std::string& message, User* receiver) {
        mediator->sendMessage(message, this, receiver);
    }
    void receiveMessage(const std::string& message) {
        std::cout << name << " receives message: " << message << std::endl;
    }
    std::string getName() {
        return name;
    }

private:
    std::string name;
    Mediator* mediator;
};

class ChatMediator : public Mediator {
public:
    void sendMessage(const std::string& message, User* sender, User* receiver)  override {
        puts("");
        std::cout << sender->getName() << " sends message [To " \
            << receiver->getName() << "]: " << message << std::endl;
        receiver->receiveMessage(message);
    }
};

void main() {
    ChatMediator mediator;

    User userA("User A", &mediator);
    User userB("User B", &mediator);

    userA.sendMessage("안녕 B!", &userB);
    userB.sendMessage("그래, 반가워 A", &userA);
}

 

🎈 중재자 패턴 특징

+  단일 지점 관리: 중재자가 상호 작용을 관리하므로,

     시스템의 상태나 동작을 중앙에서 모니터링할 수 있다.

+  재사용성: 중재자를 여러 객체 그룹에 (재)사용할 수 있다.

+  복잡성 감소: 객체간의 느슨한 결합으로 시스템 복잡성을 낮출 수 있다.

    → 각 개별 객체는 자신의 주요 역할에 집중

- 설계 정도에 따라서는 중재자 객체의 복잡성이 증가할 수 있다.

- 중재자가 모든 통신을 관리하기에 성능 저하가 발생할 수 있다.

 

중재자 패턴은 채팅 App, 항공 트래픽 제어 시스템, 게임 엔진 등에 활용되는데

객체 간의 상호 작용을 효과적으로 관리하여

확장 가능한 소프트웨어를 개발하는데 유용하지만

중재자 객체 관리와 성능에 대한 고민이 필요하다.

 

 

[예제 코드] File 관리 시스템

#include <iostream>
#include <string>
#include <vector>

class FileSystemObject {
public:
    FileSystemObject(const std::string& name) : name(name) {}
    virtual void display() const = 0;
    virtual int size() const = 0;

protected:
    std::string name;
};

class File : public FileSystemObject {
public:
    File(const std::string& name, int fileSize) : FileSystemObject(name),  fileSize(fileSize) {}
    void display() const override {
        std::cout << "파일명: " << name << ", 크기: " << fileSize << " bytes" <<  std::endl;
    }
    int size() const override {
        return fileSize;
    }

private:
    int fileSize;
};

class Directory : public FileSystemObject {
public:
    Directory(const std::string& name) : FileSystemObject(name) {}
    void addFile(const File& file) {
        files.push_back(file);
    }
    void display() const override {
        std::cout << "폴더: " << name << std::endl;
        for (const auto& file : files) {
            file.display();
        }
    }
    int size() const override {
        int totalSize = 0;
        for (const auto& file : files) {
            totalSize += file.size();
        }
        return totalSize;
    }

private:
    std::vector<File> files;
};

void main() {
    File file1("file1.txt", 1024);
    File file2("file2.txt", 2048);
    Directory folder("Harbang");

    folder.addFile(file1);
    folder.addFile(file2);

    file1.display();
    file2.display();
    puts("");

    folder.display();

    std::cout << "\n폴더 용량: " << folder.size() << " bytes" << std::endl;
}

 

FileSystemObject 클래스를 상속받아 File과 Directory 클래스 구현

 • File 클래스는 파일명과 크기 저장

 • Directory 클래스는 폴더 내 파일 관리

→ 중재자 패턴으로 파일 관리 시스템을 효과적으로 표현할 수 있으며

  각 객체가 자신의 특성을 캡슐화하고 중복을 최소화 할 수 있다.

중재자 패턴 결과 예시
반응형

댓글