본문 바로가기
컴퓨터 과학/디자인패턴

[디자인패턴] 행위 패턴(5) : 중재자(Mediator)

by webcodur 2024. 3. 25.
728x90

목차

     

     

    1. 중재자(Mediator)

    중재자(Mediator) 디자인 패턴은 행동 패턴의 하나로, 객체 간의 복잡한 통신을 캡슐화하여 간소화하는 데 목적을 둔다. 패턴의 어원은 '중재자' 또는 '조정자'라는 뜻의 'Mediator'에서 유래했다. 이 패턴의 핵심 아이디어는 여러 객체 간의 직접적인 참조와 통신을 줄이고, 대신 하나의 중재자 객체를 통해 모든 통신이 이루어지게 하는 것이다. 이로 인해 각 객체는 다른 객체들과의 결합도를 낮추며, 코드의 유지 보수와 확장성을 개선할 수 있다.

    중재자 패턴의 기본 구성 요소는 다음과 같다:

    • Mediator: 중재자 역할을 하는 인터페이스. 객체 간의 통신 규약을 정의한다.
    • ConcreteMediator: Mediator 인터페이스를 구현하는 구체적인 중재자 클래스. 실제 객체 간의 통신 방법을 코디네이트한다.
    • Colleague (또는 Component): 중재자를 통해 통신하는 객체들. 중재자에 대한 참조를 가지며, 통신이 필요할 때 이를 사용한다.

     

    패턴 미적용 예시

     

    게임 개발 상황을 가정해보자. 플레이어가 보스 몬스터를 처치했을 때, 점수를 업데이트하고, 인벤토리에 아이템을 추가하며, 업적 시스템에도 기록해야 한다고 하자. 이때 각 컴포넌트가 서로 직접 통신한다면, 코드는 다음과 같을 수 있다.

    class Player {
        public Inventory inventory;
        public Achievement achievement;
        public ScoreBoard scoreBoard;
    
        public void DefeatBossMonster() {
            // 보스 몬스터 처치 로직
            // 직접 다른 컴포넌트들과 통신
            inventory.AddItem("보스 몬스터의 아이템");
            achievement.AddRecord("보스 몬스터 처치");
            scoreBoard.UpdateScore(1000);
        }
    }
    
    class Inventory {
        public void AddItem(string item) {
            // 아이템 추가 로직
        }
    }
    
    class Achievement {
        public void AddRecord(string achievement) {
            // 업적 업데이트 로직
        }
    }
    
    class ScoreBoard {
        public void UpdateScore(int score) {
            // 점수 업데이트 로직
        }
    }
    

    이 방식의 문제점은 Player 클래스가 Inventory, AchievementSystem, **ScoreBoard**와 같은 여러 컴포넌트와 강하게 결합되어 있다는 것이다. 각 컴포넌트를 수정하거나 새로운 컴포넌트를 추가할 때마다 Player 클래스도 함께 수정해야 한다.

     

    패턴 적용 예시

    중재자 패턴을 적용한 전체 C# 코드 예시는 다음과 같다. 이 코드에서는 **Player**가 보스 몬스터를 처치할 때 발생하는 다양한 시스템 간의 상호작용을 **GameMediator**를 통해 관리한다. **GameMediator**는 게임의 다양한 컴포넌트 간의 통신을 조정하여, 각 컴포넌트가 서로 직접 참조하지 않고도 상호작용할 수 있게 해준다.

    // 중재자 인터페이스 정의
    interface IMediator {
        void Notify(object sender, string event_);
    }
    
    // 구체적인 중재자 클래스
    class GameMediator : IMediator {
        public Inventory inventory;
        public Achievement achievement;
        public ScoreBoard scoreBoard;
    
        // 중재자 생성자에서 각 컴포넌트를 초기화
        public GameMediator(Inventory inventory, Achievement achievement, ScoreBoard scoreBoard) {
            this.inventory = inventory;
            this.achievement = achievement;
            this.scoreBoard = scoreBoard;
        }
    
        // 이벤트에 따른 컴포넌트 간의 상호작용 조정
        public void Notify(object sender, string event_) {
            if (event_ == "보스 몬스터 처치") {
                inventory.AddItem("보스 몬스터의 아이템");
                achievement.AddRecord("보스 몬스터 처치");
                scoreBoard.UpdateScore(1000);
            }
            // 필요에 따라 다른 이벤트 처리도 추가 가능
        }
    }
    
    // Player 클래스
    class Player {
        private IMediator mediator;
        public Player(IMediator mediator) {
            this.mediator = mediator;
        }
        public void DefeatBossMonster() {
            // 보스 몬스터를 처치하는 로직
            mediator.Notify(this, "보스 몬스터 처치");
        }
    }
    
    // 인벤토리 관리 컴포넌트
    class Inventory {
        public void AddItem(string item) {
            Console.WriteLine($"Inventory: {item} 추가됨.");
        }
    }
    
    // 업적 시스템 컴포넌트
    class Achievement {
        public void AddRecord(string achievement) {
            Console.WriteLine($"Achievement: 업적 '{achievement}' 달성!");
        }
    }
    
    // 점수판 컴포넌트
    class ScoreBoard {
        public void UpdateScore(int score) {
            Console.WriteLine($"ScoreBoard: 점수 {score}점 업데이트!");
        }
    }
    
    // 애플리케이션 실행
    class Program {
        static void Main(string[] args) {
        
            Inventory inventory = new Inventory();
            Achievement achievement = new Achievement();
            ScoreBoard scoreBoard = new ScoreBoard();
            
            GameMediator mediator = new GameMediator(inventory, achievement, scoreBoard);
    
            Player player = new Player(mediator);
            player.DefeatBossMonster();
        }
    }
    

     

    이 코드 예시는 GameMediator 클래스를 통해 게임 내의 다양한 컴포넌트(Inventory, AchievementSystem, ScoreBoard) 간의 상호작용을 조정한다.

     

    Player 클래스는 DefeatBossMonster 메소드를 통해 보스 몬스터를 처치할 때 GameMediator에게 이를 알린다. 그러면 GameMediator는 해당 이벤트에 따라 필요한 컴포넌트에게 알맞은 작업을 지시한다. 이러한 구조 덕분에 각 컴포넌트는 서로 직접적으로 의존하지 않으며, 시스템의 유연성과 확장성이 크게 향상된다.