委托实现猫叫人醒老鼠逃
今天在看面试题的时候觉得有道题蛮有意思,原题如下:
程序设计: 猫大叫一声,所有的老鼠都开始逃跑,主人被惊醒。(C#语言)
要求: 1.要有联动性,老鼠和主人的行为是被动的。
2.考虑可扩展性,猫的叫声可能引起其他联动效应。
首先看到这道题的时候就蛮简单的,思路如下:
//定义猫类,具有叫的动作,考虑到联动效应,所以在叫的同时调用主人类的惊醒方法,老鼠类的逃跑方法
//定义主人类,具有惊醒方法
//定义老鼠类,具有逃跑方法
//定义主调函数,调用猫类的叫动作
--------------------------------
以上,便实现了猫叫人醒老鼠逃的功能;但
“要求2.考虑可扩展性,猫的叫声可能引起其他联动效应。”这个要求明显不能满足;那么
怎样的设计才具有可扩展性呢?
我们首先分析,主人类和老鼠类有没有什么共性,是否可以提取抽象方法,我们看到,猫叫之后,我们程序会打印出人醒、老鼠逃的提示语言,那我们能不能把这个输出打印动作抽象出来呢,那我们的程序需要稍作修改,如下:
//定义反应抽象类(人醒老鼠逃)--输出动作
//定义主人类,继承自反应抽象类 --实现输出动作(“主人醒”);
//定义老鼠类,继承自反应抽象类 --实现输出动作(“老鼠逃”);
程序写到这里,我们会想,猫叫的时候怎么把主人、老鼠联动到一起呢?
在猫类里面直接实例化主人类、老鼠类,然后直接调用,这种方法不是我们想要的,我们需要的是松耦合的方式;当然实现方式有很多,比如利用“中间组件”。
不知道有同学是否还记得委托能够把多个方法绑定到一个事件中;这样的话,先把主人醒、老鼠逃都绑定到事件中,然后直接在猫类里面激活这个事件即可触发“人醒”、“老鼠逃”等动作,即使把邻居吵醒也可以轻松实现,只需
//定义邻居类,继承自反应抽象类 --实现输出动作(“邻居醒”);
然后把邻居醒绑定到事件中即可;
也有同学要问了,怎么定义委托,以及怎么把主人醒、老鼠逃等动作都绑定到事件中呢?
我这里提供一个思路,你们也可以随意发挥,我是在“反应抽象类”的构造函数里把输出动作绑定到事件中,然后在子类(主人类)的构造函数继承父类,这样就能把子类的实现绑定到事件中,老鼠类、邻居类也是相同方式;
理论说了这么多,上代码(我是直接在网站后台写的,没办法定义格式,还请谅解):
//定义事件委托类
public delegate void SubEventHandler();
public abstract class Subject
{
//基于委托定义事件
public event SubEventHandler SubEvent;
//猫大叫一声
protected void FireWay()
{
if (this.SubEvent != null)
{
//激活事件,从而触发一系列动作,在反应抽象类里要实现的是将所有动作都绑定到委托
this.SubEvent();
}
}
}
//定义反应抽象类--构造函数将反应动作绑定到委托
public abstract class AbsObject
{
public AbsObject(Subject sub)
{
sub.SubEvent += new SubEventHandler(Response);
}
public abstract void Response();
}
//定义人类继承反应抽象类继承构造函数,将具体人类绑定到委托
public class people : AbsObject
{
public people(Subject sub) : base(sub) { }
public override void Response()
{
Console.WriteLine("host waken");
}
}
//定义老鼠继承反应抽象类继承构造函数,将具体老鼠绑定到委托
public class mouse : AbsObject
{
private string name = string.Empty;
public mouse(string name, Subject sub)
: base(sub)
{
this.name = name;
}
public override void Response()
{
Console.WriteLine(string.Format("this name :{0},mouse run",name));
}
}
//定义猫继承委托类--猫叫触发事件
public class cart:Subject
{
public void cary()
{
//猫叫
Console.WriteLine("cart cary");
//联动效应
this.FireWay();
}
}
//定义主调函数
public class mainclass
{
static void Main()
{
cart c=new cart();
people p = new people(c);
mouse m = new mouse("大米奇",c);
mouse m1 = new mouse("小米奇", c);
c.cary();
Console.ReadLine();
}
}
总结:
其实面向对象的程序设计中,提取抽象能力是很重要的,往往抽象函数和委托结合就能写出很优美的代码,松耦合,高聚合,是程序设计的追求。
ps:
别迷恋哥,哥只是个传说。