프로그래밍 기술/Escort GoF의 디자인 패턴 C#

[C#] 감시자 패턴(Observer Pattern) - 구현

언제나휴일 2016. 4. 28. 16:09
반응형

21. 감시자 패턴(Observer Pattern)


감시자 패턴(Observer Pattern) 클래스 다이어그램

[그림] 감시자 패턴(Observer Pattern) 클래스 다이어그램

Observer.zip


21.4 구현

 

 감시자 패턴에 대한 예제 프로그램을 구현하는 순서는 Subject Picture, IUpdate와 각 뷰어, 데모 코드 순으로 하겠습니다.

 

21.4.1 Subject Picture

 

 Subject는 상태 변경이 있을 때 감시자에게 변경을 통보하는 역할을 담당합니다. 이를 위해 감시자를 등록하는 메서드와 해제하는 메서드를 구현해야 합니다. 그리고, 상태 변경이 있을 때 등록된 모든 감시자들에게 변경된 사실을 통보를 하는 메서드도 구현합시다.

 

Subject.cs

using System.Collections.Generic;

namespace Observer

{

    class Subject

    {

        List<IUpdate> observers = new List<IUpdate>();

        public void AddObserver(IUpdate observer)

        {

            observers.Add(observer);

        }

        public void RemoveObserver(IUpdate observer)

        {

            observers.Remove(observer);

        }

        public void Notify()

        {

            foreach (IUpdate observer in observers)

            {

                observer.Update();

            }

        }

    }

}

 

 

 그리고, Picture Subject를 기반으로 파생된 형식으로 정의합시다. 이를 통해 Picture에서는 자신이 상태가 변경되었을 때 누군한테 보내야 하는지에 대한 고민을 하지 않아도 됩니다. 단순히 기반 클래스의 상태 변경을 통보하는 Notify 메서드를 사용하면 됩니다. 이를 통해 Picutre는 자신의 상태가 변경되었을 때 영향을 받는 다른 형식들과의 의존 관계가 필요없게 되는 것입니다.

 

Picture.cs

using System;

namespace Observer

{

    class Picture:Subject

    {

        public string Name{    get;     private set;     }

        public int Tone {    get;     private set;    }

        public int Brightness{    get;    private set;     }

        public int Saturation{    get;    private set;    }

        public Picture(string name,int tone,int brightness,int saturation)

        {

            Name = name;

            Tone = tone;

            Brightness = brightness;

            Saturation = saturation;

        }

        public void Change(int tone,int brightness,int saturation)

        {

            Tone+=tone;

            Brightness += brightness;

            Saturation += saturation;

            Notify();

        }

        public void View()

        {

            Console.WriteLine("사진 파일명:{0}",Name);

            Console.WriteLine("    색조:{0} 명도:{1} 채도:",Tone,Brightness,Saturation);

        }

    }

}

 

  

21.4.2 IUpdate와 각 뷰어

 

 IUpdate에서는 상태 변경을 통보 받았을 때 처리할 메서드에 대한 약속을 하면 됩니다. 그리고, 각 뷰어에서는 IUpdate에서 약속한 메서드를 구체적으로 구현해야 겠지요. ToneViewer에서는 Picture 개체의 색조값을 얻어와 이를 보여주면 되고 다른 뷰어들도 자신이 보여줘야 할 정보를 얻어와서 보여주면 됩니다.

 

IUpdate.cs

namespace Observer

{

    interface IUpdate

    {

        void Update();

    }

}

 

 

ToneViewer.cs

using System;

namespace Observer

{

    class ToneViewer:IUpdate

    {

        Picture picture = null;

        public ToneViewer(Picture picture)

        {

            this.picture = picture;

        }

        public void Update()

        {

            Console.WriteLine("이름:{0} 색조:{1}", picture.Name, picture.Tone);

        }

    }

}

 

  

BrightnessViewer.cs

using System;

namespace Observer

{

    class BrightnessViewer:IUpdate

    {

        Picture picture;

        public BrightnessViewer(Picture picture)

        {

            this.picture = picture;

        }

        public void Update()

        {

            Console.WriteLine("이름:{0} 명도:{1}", picture.Name, picture.Brightness);

        }       

    }

}

 

 

SaturationViewer.cs

using System;

namespace Observer

{

    class SaturationViewer :IUpdate

    {

        Picture picture = null;

        public SaturationViewer(Picture picture)

        {

            this.picture = picture;

        }

        public void Update()

        {

            Console.WriteLine("이름:{0} 채도:{1}", picture.Name, picture.Saturation);

        }

    }

}

 

 

21.4.3 데모 코드

 

 데모 코드에서는 사진 개체와 각 뷰어 개체를 생성한 후에 사진 개체에 각 뷰어를 등록을 합니다. 그리고, 사진 개체의 정보를 변경하는 코드로 작성하겠습니다. 내부적으로 사진 개체의 기반 형식인 Subject Update 메서드에 의해 각 뷰어에게 변경된 사실이 통보될 것이며 각 뷰어에서는 필요한 정보를 요청하여 화면에 출력을 하겠죠.

 

Program.cs

namespace Observer

{

    class Program

    {

        static void Main(string[] args)

        {

            Picture picture = new Picture("제주도의 밤",100,100,100);

            IUpdate[] observers = new IUpdate[3];

            observers[0] = new ToneViewer(picture);

            observers[1] = new BrightnessViewer(picture);

            observers[2] = new SaturationViewer(picture);

            picture.AddObserver(observers[0]);

            picture.AddObserver(observers[1]);

            picture.AddObserver(observers[2]);

            picture.Change(3,10,5);

        }

    }

}

 



감시자 패턴 예제 실행 화면 

[그림 ] 감시자 패턴 예제 실행 화면


2016/04/28 - [프로그래밍 기술/Escort GoF의 디자인 패턴 C#] - [C#] 감시자 패턴(Observer Pattern) - 개요, 시나리오


2016/04/28 - [프로그래밍 기술/Escort GoF의 디자인 패턴 C#] - [C#] 감시자 패턴(Observer Pattern) - 설계(Design)


반응형