星星之火

燎原之势不可挡
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

关于猫叫、老鼠逃跑、人被惊醒的程序设计

Posted on 2012-11-12 11:06  星星之火116  阅读(10645)  评论(52编辑  收藏  举报

题目是这样的:猫大叫一声,所有的老鼠都开始逃跑,主人被惊醒。

要求:

1、要有联动性,老鼠和人的行为是被动的

2、考虑可扩展行,猫叫声可能会引起其他联动效应

看到这个程序设计题目,我的第一反应是用事件来解决,猫叫触发了事件,引起了老鼠的逃跑,老鼠逃跑又触发了事件导致主人被惊醒,或者是猫叫引起了老鼠逃跑、人醒。所以按照这个思路,我做出了如下的解答。

    第一种解决方案用事件来解决:是多级的联动:即:猫叫-》老鼠跑-》人醒

    第二种解决方案采用观察者模式:猫叫-》老鼠跑;猫叫-》人醒

首先,将猫、老鼠、和人分别抽象出来为三个类,分别为:CatMousePeople。在Cat类中我们做如下处理:

 

public class Cat
{
    public delegate void Crying(object sender,EventArgs e);//定义一个猫叫委托
    public event Crying cry;//定义猫叫事件
    public void OnCry(EventArgs e)
    {
       if(cry!=null)
       {
           cry(this,e);
       }
    }
   public void StartCrying()//猫叫、触发cry事件
   {
      MessageBox.Show("猫开始叫了......");
      EventArgs e=new EventArgs();
      OnCry(e);
   }
}

 

public class Mouse
{
   public delegate void Runing(Object sender,EventArgs e);
   public evnet Running run;
   public void OnRun(EventArgs e)
   {
        if(run!=null)
          {
             run(this,e); 
          }
   }
   public Mouse(Cat c)
   {
       c.cry+=new Cat.Crying(c_Cry);//注册了猫叫事件,老鼠听到猫叫则开始逃跑
   }
   void c_Cry(object sender,EvnetArgs e)//老鼠在逃跑时又触发了人被惊醒事件
   {
       MessageBox.Show("老鼠开始逃跑了........");
       EventArgs e=new EventArgs();
       OnRun(e);
   }
}
public class Person
{
     public Person(Mouse m)
     {
         m.run+=new Mouse.Runing(m_run);//人注册了老鼠逃跑事件,老鼠逃跑时人被 惊醒
     }
     void m_run(object sender,EventArgs e)
         {
         MessageBox.Show("人醒了,What's wrong?");
         }
}

 

BtnTest_Click(object sender, EventArgs e)
{
    Cat c=new Cat();
    Mouse m=new Mouse(c);
    Person p=new Person(m);
    c.StartCrying();
}

 

实验效果依次如下:

 

下面再通过另一个方式来解决这个问题。

Observer(观察者模式)

首先我们需要新建两个接口:

 

public interface Observer
{
     void Response();//对被观察对象的行为作出反应,这里是指猫叫
}
public interface Subject
{
     void AddObserver(Observer obj);//添加所有的观察者,在发生动作时对他们进行通知
}

 

public class Cat:Subject
{
    ArrayList arrlyList;
    public Cat()
    {
       arrlyList=new ArrayList();
    }
    void AddObserver(Observer obj)//实现添加观察着对象的方法
    {
       arrlyList.Add(obj);
    }
    void Cry()//猫叫了,并通知所有的观察者,作出相应的反应
    {
        MessageBox.Show("猫叫了......");
        foreach(Observer obj in arrlyList)
         {
              obj.Response();
         }
    }
}

 

public class Mouse:Observer
{
    public Mouse(Cat c)//将当前的观察着对象添加到观察者集合中
    {
        c.AddObserver(this);
    }
    public void Response()
    {
        MessageBox.show("老鼠开始逃跑了.....");
    }
}

 

public class People:Observer
{
   public People(Cat c)//将当前的观察着对象添加到观察者集合中
   {
      c.AddOberver(this);
   }
   public void Respone()
  {
       MessageBox.Show("人醒了,What's Wrong?");
   }
}

 

Btn_Click(Object sender,EventArgs e)
 {
Cat c=new Cat();
Mouse m=new Mouse(c);
People p=new People(c);
c.Cry();
 }

 

    结果跟上边所示的一样。

    好了,到这里这道程序设计题的解决方案也就是这些了,通过这两种不同的解决方案我们可以发现,在针对多个不同的观察者时,使用观察着实现联动性,比较方面,而且可扩展性也比较强,事实上观察者模式也就是主要用于对多个不同的观察者对象做出不同反应而设计的。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实作事件处理系统。

反观我们使用第一种方法事件订阅处理,可以实现多级的联动,猫叫引发老鼠跑,老鼠跑引发人醒,事件的存在是为了弥补委托的不足,事件是将事件发送者(触发事件的对象)与事件接受者(处理事件的方法)相关联的一种代理类,即事件机制是通过代理类来实现的。当一个事件被触发时,由该事件的代理来通知(调用)处理该事件的相应方法。事件多用于WinForm中的窗体的传递值,按钮的Click事件等。

这一节就到这里了,希望能给大家有所帮助,还请多多指导!