Design Pattern 设计模式【观察者】

  观察者设计模式中存在两种角色: 观察者被观察者

  最经典的例子就是“猫叫了,老鼠跑了,惊醒了主人。”,这个例子也是我以前去微软面试的时候碰到的一个面试题,当时就是让我设计一下这个过程的实现框架。

  在这个例子中,老鼠和主人其实就是观察者,而猫属于被观察者,老鼠和主人观察猫的变化,猫有了动作,老鼠和主人就要做出响应。被观察者,就是这个过程,也可以叫做整个事件的根本原因,亦可以叫直接导火索。 

  从上面这个例子不难看出,观察者和被观察者的关系通常是n:1,也就是多个多个观察者观察一个被观察者。 

  这样就给我们一个小小的提示,通过这个提示就可以很容易的找出被观察者。猫,也就是观察的内容,或者观察的被动者,猫所在的角色就是被观察者;老鼠和主人,也就是观察的主体,动作的出发者,他们的角色就是观察者。

  当然了,实际的项目中,这个过程肯定没有这么简单,这时候需要我们把大过程,分解成很多的小过程,分层级的找出观察者和被观察者,分层级的使用观察者模式。

  下面给出我写的一个完整代码,欢迎大家一起讨论。

      完整代码:/Files/virusswb/BeautyCode.DesignPattern.Observer.rar

  代码包括两个部分,首先是普通的观察者模式,也就是在被观察者中注册观察者,多个观察者通过一个荣起来管理,然后向观察者发送通知。

   

ContractedBlock.gif ExpandedBlockStart.gif 普通的观察者模式
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApp
{
    
/// <summary>
    
/// 观察者接口
    
/// </summary>
    public interface IObserver
    {
        
void Notify(object obj);
    }
    
/// <summary>
    
/// 被观察者接口
    
/// </summary>
    public interface IObservable
    {
        
void Register(IObserver observer);
        
void UnRegister(IObserver observer);
        
void Notify(object obj);
    }
    
class Mouse:IObserver 
    {
        
public void Run()
        {
           
        }

        
#region IObserver 成员

        
public void Notify(object obj)
        {
            Console.WriteLine(
string.Format("{0},老鼠跑了",obj.ToString()));
        }

        
#endregion
    }
    
class Master:IObserver 
    {
        
public void Wake()
        {
          
        }

        
#region IObserver 成员

        
public void Notify(object obj)
        {
            Console.WriteLine(
string.Format("{0},主人被惊醒",obj.ToString())); 
        }

        
#endregion
    }
    
class Dog : IObserver
    {
        
#region IObserver 成员

        
public void Notify(object obj)
        {
            Console.WriteLine(
string.Format("{0},狗拿耗子,多管闲事", obj.ToString())); 
        }

        
#endregion
    }
    
class Cat:IObservable 
    {
        
private Dictionary<IObserver, IObserver> _observerContainer = new Dictionary<IObserver, IObserver>();
        
public void Cry()
        {
            Console.WriteLine(
"猫叫了");
        }

        
#region IObservable 成员

        
public void Register(IObserver observer)
        {
            
if (_observerContainer.ContainsKey(observer))
                _observerContainer.Remove(observer);
            _observerContainer.Add(observer,observer );
        }

        
public void UnRegister(IObserver observer)
        {
            
if (_observerContainer.ContainsKey(observer))
                _observerContainer.Remove(observer);
        }

        
public void Notify(object obj)
        {
            
foreach (IObserver o in _observerContainer.Keys)
            {
                _observerContainer[o].Notify(obj);
            }
        }

        
#endregion
    }
  
}

 

  第二种是在.NET 框架的基础之上的观察者,也就是事件委托类型的观察者,不需要在被观察者中注册观察者,降低了观察者和被观察者的耦合度。

 

ContractedBlock.gif ExpandedBlockStart.gif 以事件委托为基础的观察者模式
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApp

    
public delegate void ObserverEventHandler(object sender, EventObjectArgs e);
    
/// <summary>
    
/// 被观察者
    
/// </summary>
    public interface IEventObserable
    {

         
event ObserverEventHandler ObserverEvent;
         
void OnObserverEvent(EventObjectArgs e);
         
void RaiseObserverMethod();
    }
    
/// <summary>
    
/// 观察者
    
/// </summary>
    public interface IEventObserver
    {
        
    }
    
    
public class EventObjectArgs : EventArgs
    {
        
private string _message;
        
public string Message
        {
            
get { return _message; }
        }
        
public EventObjectArgs()
        {
        }
        
public EventObjectArgs(string message)
        {
            
this._message = message;
        }
    }
    
class EventCat : IEventObserable
    {
        
#region IEventObserable 成员

        
public event ObserverEventHandler ObserverEvent;

        
public  void OnObserverEvent(EventObjectArgs e)
        {
            
if (null != ObserverEvent)
            {

                ObserverEvent(
this, e);
            }
        }

        
public void RaiseObserverMethod()
        {
            Console.WriteLine(
"猫叫了");
            OnObserverEvent(
new EventObjectArgs("猫叫了"));
        }

        
#endregion
    }
    
class EventMouse : IEventObserver
    {
        
public EventMouse() { }
        
public EventMouse(IEventObserable  observable)
        {
            observable.ObserverEvent 
+= new ObserverEventHandler(observable_ObserverEvent);
        }

       
public  void observable_ObserverEvent(object sender, EventObjectArgs e)
        {
            Console.WriteLine(
string.Format("{0},所有老鼠被吓跑了", e.Message));
        }
    }
    
class EventDog : IEventObserver
    {
        
public EventDog(IEventObserable observable)
        {
            observable.ObserverEvent 
+= new ObserverEventHandler(observable_ObserverEvent);
        }

        
public void observable_ObserverEvent(object sender, EventObjectArgs e)
        {
            Console.WriteLine(
string.Format("{0},所有老鼠被吓跑了,但是狗拿耗子多管闲事", e.Message));
        }
    }
    
class EventMaster : IEventObserver
    {
        
public EventMaster(IEventObserable observable)
        {
            observable.ObserverEvent 
+= new ObserverEventHandler(observable_ObserverEvent);
        }

       
public  void observable_ObserverEvent(object sender, EventObjectArgs e)
        {
            Console.WriteLine(
string.Format("{0},所有老鼠被吓跑了,但是狗拿耗子多管闲事,主人生气了,要打死这些动物", e.Message));
        }
    }
}

 

 

  下面是他们的调用代码,是一个Console应用程序

 

ContractedBlock.gif ExpandedBlockStart.gif Observer 代码调用
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApp
{
    
public class Model
    {
        
public object ModelState { getset; }
    }
    
public class Command
    {
        
public void DoCommand()
        { }
    }
    
public class Selection : EventArgs
    {
        
public object State { getset; }
    }
    
public class Interactor
    {
        
public delegate void AddItemEventHandler(object sender, Selection e);
        
public event AddItemEventHandler ItemAdded;
        
protected virtual void OnItemAdded(Selection e)
        {
            
if (ItemAdded != null)
                ItemAdded(
this, e);
        }
        
public void AddItem(object value)
        {
            Selection selection 
= new Selection() { State = value };
            OnItemAdded(selection);
        }
    }
    
public class Presenter
    {
        
private readonly Command command;
        
private readonly Interactor interactor;
        
private readonly Model model;
        
private readonly View view;
        
public Presenter(Interactor interactor)
        {
            
this.command = new Command();
            
this.model = new Model();
            
this.view = new View();
            
this.interactor = interactor;
            
this.interactor.ItemAdded += new Interactor.AddItemEventHandler(interactor_ItemAdded);
        }

        
void interactor_ItemAdded(object sender, Selection e)
        {
            
this.command.DoCommand();
            
this.model.ModelState = e.State;
            
this.view.Update ("Processed " + e.State);
        }
    }
    
public class View
    {
        
private object ViewState;
        
static void Main(string[] args)
        {
            
#region Model View Presenter Design Pattern

            Interactor interactor 
= new Interactor();
            Presenter presenter 
= new Presenter(interactor);
            interactor.AddItem(
"Message from the UI");

            
#endregion

            
#region 普通观察着模式

            Mouse mouse 
= new Mouse();
            Master master 
= new Master();
            Dog dog 
= new Dog();

            Cat cat 
= new Cat();
            cat.Register(mouse);
            cat.Register(master);
            cat.Register(dog);
            cat.Cry();
            cat.Notify(
"猫叫了");

            cat.UnRegister(mouse);
            cat.UnRegister(master);
            cat.UnRegister(dog );

            
#endregion

            
#region 基于事件和委托的观察者模式

            EventCat eventCat 
= new EventCat();
            EventMouse eventMouse 
= new EventMouse(eventCat);
            EventDog eventDog 
= new EventDog(eventCat);
            EventMaster eventMaster 
= new EventMaster(eventCat);

            eventCat.RaiseObserverMethod();
            
            
#endregion

            Console.ReadLine();
        }
        
public void Update(object state)
        {
            ViewState 
= state;
        }
    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值