首页 > 代码库 > 观察者模式

观察者模式

1.  .Net可以很好地支持委托,事件,用事件来实现观察者模式很简洁,最大程度地减少了观察者与Subject之间的耦合。

    class Subject    {        public delegate void ChangedEventHandler(object sender, EventArgs args);        public event ChangedEventHandler Changed;        public void FireTest()        {            if (this.Changed != null)            {                this.Changed(this, null);            }        }    }    class Observer    {        public void subject_Changed(object sender, EventArgs args)        {            // do something            //.....            this.Render();        }        private void Render()        {            Console.WriteLine("start to reder by the model changes.");        }    }    class Program    {        static void Main(string[] args)        {            Subject subject = new Subject();            Observer observer = new Observer();            subject.Changed += observer.subject_Changed;            subject.FireTest();        }    }

 

 

2. 下面的例子是一个同事用模板实现的观察者模式:

ISubject

    public interface IObserver<in TChange>    {        void Update(TChange changes);    }

 

subject

 public class Subject<TChange> : ISubject<TChange>    {        protected ICollection<IObserver<TChange>> Observers = new HashSet<IObserver<TChange>>();        public void Attach(IObserver<TChange> observer)        {            Observers.Add(observer);        }        public void Dettach(IObserver<TChange> observer)        {            Observers.Remove(observer);        }        public void NotifyObservers(TChange changes)        {            foreach (IObserver<TChange> observer in Observers)            {                observer.Update(changes);            }        }    }

 

IObserver

    public interface IObserver<in TChange>    {        void Update(TChange changes);    }

 

Client program

 public class WeatherData : Subject<Tuple<string, float>>    {        private float temperature;        public float Temperature        {            get { return temperature; }            set            {                if (value != temperature)                {                    temperature = value;                    this.NotifyObservers(Tuple.Create("Temperature", value));                }            }        }        private float pressure;        public float Pressure        {            get { return pressure; }            set            {                if (value != pressure)                {                    pressure = value;                    this.NotifyObservers(Tuple.Create("Pressure", value));                }            }        }        private float humidity;        public float Humidity        {            get { return humidity; }            set            {                if (value != humidity)                {                    humidity = value;                    this.NotifyObservers(Tuple.Create("Humidity", value));                }            }        }    }    public class WeatherDisplay : Label, QiHe.CodeLib.DesignPatterns.IObserver<Tuple<string, float>>    {        public void Update(Tuple<string, float> changes)        {            if (this.InvokeRequired)            {                this.Invoke(new Action(() => Display(changes)));            }            else            {                Display(changes);            }        }        private void Display(Tuple<string, float> data)        {            this.Text = string.Format("{0}: {1:F2}", data.Item1, data.Item2);        }    }    public class Test    {        [STAThread]        static void Main()        {            WeatherData weatherData = new WeatherData();            WeatherDisplay dispalay = new WeatherDisplay();            WeatherDisplay dispalay2 = new WeatherDisplay();            weatherData.Attach(dispalay);            weatherData.Attach(dispalay2);            dispalay2.Top = 50;            Form form = new Form();            dispalay.AutoSize = true;            form.Controls.Add(dispalay);            form.Controls.Add(dispalay2);            //new Thread(() => form.ShowDialog()).Start();            form.Show();            weatherData.Temperature = 20;            Console.ReadLine();            weatherData.Pressure = 80;            Console.ReadLine();            weatherData.Humidity = 0.4f;            Console.ReadLine();        }    }

 

观察者模式