dotaeye

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

观察者模式的理解。

一、对象

1.观察者Observer

2.被观察者Subject

二、动作

观察者-------(action 观察)------>被观察者

被观察者自身发生改变

观察者得到被观察者改变之后的信息,

很多网上的列子,都是被观察者去注册观察者,这感觉有点本末倒置,

被观察者是被动的,它唯一主动的操作就是改变它自己的状态。

而主动的是观察者,应该由观察者去主动订阅被观察者。

三、从类的角度来理解

画图的类图应该是:

四、从类关系图来看

Observer和Subject是多对多的关系

Observer代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace observerPattern
{
    public abstract class Observer
    {
        public Observer()
        {
            this.SubjectCollection = new HashSet<Subject>();
        }
        public string Name
        {
            get;
            set;
        }
        public virtual void Display()
        {

        }
        public void Subscribe(Subject subject)
        {
            this.SubjectCollection.Add(subject);
            subject.Attach(this);
        }
        public void UnSubscribe(Subject subject)
        {
            this.SubjectCollection.Remove(subject);
            subject.Detach(this);
        }
        public ICollection<Subject> SubjectCollection { get; set; }
    }
}

Subject代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace observerPattern
{
    public abstract class Subject
    {
        public Subject()
        {
            this.ObserverCollecion = new HashSet<Observer>();
        }

        public string Name
        {
            get;
            set;
        }
        public string Message
        {
            get;
            set;
        }

        public void Attach(Observer observer)
        {
            this.ObserverCollecion.Add(observer);
        }

        public void Detach(Observer observer)
        {
            this.ObserverCollecion.Remove(observer);
        }

        public void Change()
        {
            throw new System.NotImplementedException();
        }

        public ICollection<Observer> ObserverCollecion { get; set; }
    }
}

然后拿经典的例子猫叫老鼠跑来分析

Cat代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace observerPattern
{
    public class Cat : Subject
    {
        public Cat(string name, string message)
        {
            this.Name = name;
            this.Message = message;
            Console.WriteLine(this.Name + "信息:" + this.Message);
        }

        public void Change()
        {
            this.Message = "饿了,醒来了";
            foreach (var o in this.ObserverCollecion)
            {
                o.Display();
            }
        }
    }
}

老鼠Mouse代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace observerPattern
{
    public class Mouse : Observer
    {
        public Mouse(string name)
        {
            this.Name = name;
        }

        public override void Display()
        {
            Console.WriteLine(this.Name + ":订阅详情");
            foreach (var s in this.SubjectCollection)
            {
                Console.WriteLine("订阅者:" + s.Name + ",订阅信息:" + s.Message);
            }
            SelfAction();
        }

        public void SelfAction()
        {
            Console.WriteLine("快跑!");
        }
    }
}

主进程代码:

    class Program
    {
        static void Main(string[] args)
        {
            Cat ct = new Cat("猫", "睡着的");
            Mouse mo = new Mouse("小老鼠");
            mo.Subscribe(ct);
            ct.Change();
            Console.ReadLine();
        }
    }

 事件驱动的observer pattern代码:

Observer代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace observerPatternEvent
{
    public abstract class Observer
    {

        public Observer()
        {
            this.SubjectCollection = new HashSet<Subject>();
        }


        public string Name
        {
            get;
            set;
        }

        public virtual void Display(Object sender, EventArgs e)
        {

        }

        public void Subscribe(Subject subject)
        {
            this.SubjectCollection.Add(subject);
            subject.MessageChanged += Display;
        }

        public void UnSubscribe(Subject subject)
        {
            this.SubjectCollection.Remove(subject);
            subject.MessageChanged -= Display;
        }

        public ICollection<Subject> SubjectCollection { get; set; }

    }
}

Subject代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace observerPatternEvent
{
    public abstract class Subject
    {

        public string Name
        {
            get;
            set;
        }
        public string Message
        {
            get;
            set;
        }

        public event EventHandler MessageChanged;

        public virtual void Change(string message)
        {
            this.Message = message;
            if (MessageChanged != null)
                MessageChanged(this, EventArgs.Empty);
        }
    }
}

Cat代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace observerPatternEvent
{
    public class Cat : Subject
    {
        public Cat(string name, string message)
        {
            this.Name = name;
            this.Message = message;
            Console.WriteLine(this.Name + "信息:" + this.Message);
        }

    }
}

Mouse代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace observerPatternEvent
{
    public class Mouse : Observer
    {
        public Mouse(string name)
        {
            this.Name = name;
        }

        public override void Display(object sender, EventArgs e)
        {
            Console.WriteLine(this.Name + ":订阅详情");
            foreach (var s in this.SubjectCollection)
            {
                Console.WriteLine("订阅者:" + s.Name + ",订阅信息:" + s.Message);
            }
            SelfAction();
        }

        public void SelfAction()
        {
            Console.WriteLine("快跑!");
        }
    }
}

主程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace observerPatternEvent
{
    class Program
    {
        static void Main(string[] args)
        {
            Cat ct = new Cat("猫", "睡着的");
            BlackCat ct1 = new BlackCat("黑猫", "睡着的");
            Mouse mo = new Mouse("小老鼠");
            mo.Subscribe(ct);
            mo.Subscribe(ct1);
            ct.Change("睡醒了,饿了");
            mo.UnSubscribe(ct);
            ct1.Change("继续睡");
            Console.ReadLine();
        }
    }
}

  

 

posted on 2013-02-21 15:02  dotaeye  阅读(220)  评论(0编辑  收藏  举报