程序设计: 猫大叫一声,所有的老鼠都开始逃跑,主人被惊醒。(C#语言) 要求: 1.要有联动性,老鼠和主人的行为是被动的。 2.考虑可扩展性,猫的叫声可能引起其他联动效应。
应该是用委托吧。具体怎么做还不会。什么是联动性、可扩展性?
基础差,以前又没接触过这样的题目。
望高手给个实例,好回去理解一下。
应该是用委托吧。具体怎么做还不会。什么是联动性、可扩展性?
基础差,以前又没接触过这样的题目。
望高手给个实例,好回去理解一下。
protected void Page_Load(object sender, EventArgs e)
{
Dog dog = new Dog();
Host host = new Host(dog); DateTime now = new DateTime(2008, 12, 31, 23, 59, 50);
DateTime midnight = new DateTime(2009, 1, 1, 0, 0, 0); Response.Write("时间一秒一秒的流逝..." + "<br />");
while (now < midnight)
{
Response.Write("当前时间:" + now + "<br />");
System.Threading.Thread.Sleep(1000);
now = now.AddSeconds(1);
} Response.Write("<br /" + "月黑风高的午夜:" + now + "<br />");
Response.Write("小偷悄悄地摸进了主人的屋内...");
dog.OnAlarm();
}
class Dog
{
public delegate void AlarmEventHandler(object sender, EventArgs e); //1.声明关于事件的委托;
public event AlarmEventHandler Alarm; //2.声明事件;
public void OnAlarm() //3.编写引发事件的函数;
{
if (this.Alarm != null)
{
HttpContext.Current.Response.Write("<br />" + "狗报警:有小偷进来了,汪汪~~~~~" + "<br />");
this.Alarm(this, new EventArgs());
}
}
} class Host
{
void HostHandleAlarm(object sender, EventArgs e) //4.编写事件处理程序
{
HttpContext.Current.Response.Write("主人:抓住了小偷!");
} public Host(Dog dog) //5.注册事件处理程序
{
dog.Alarm += new Dog.AlarmEventHandler(HostHandleAlarm);
}
}
我也不想扯什么模式模式的,不过我也不知道怎么样表达.此题比直接问:你知道观察者模式难很多(我就是知道一个大概,一看此题,可能还真难一下就反应到他身上)
就算知道了观察者模式,如果不知道C#下的事件可以很简洁的实现它的思想,那么写的出来的代码,可能看上去会复杂点.(C#里的事件委托实际上就是一个委托链表,用事件委托就可以省去自己搞一个List去foreach了)
设计的大致思路在于,猫类型负责包含并维护一个猫叫的事件,主人和老鼠的对象需要订阅猫叫这一事件,这样能够保证猫叫发生时执行相应的动作。下面的代码展示了这一设计。
首先需要设计的是猫模拟猫的类型,该类型是猫叫事件的管理者。
-------------------------------------------------猫类型-------------------------------------------
public class Cat
{
private Sting _name;//猫名
public event EventHandler<CatCryEventArgs> CatCryEvent;//猫叫的事件
public Cat(String name)//构造方法
{
_name = name;
}
public void CatCry() //触发猫叫事件
{
CatCryEventArgs args = new CatCryEventArgs(_name);
Console.WriteLine(args);
CatCryEvent(this,args);
}
}public class CatCryEventArgs :EventArgs
{
private String _catname;//发出叫声的猫的名字
public CatCryEventArgs(String catname): base()
{
_catname = catname;
}
public override string ToString()
{
return _catname + "叫了";
}
}
---------------------------------主人类型----------------------
public class Master
{
private String _name;//主人名
public Master(String name,Cat cat)//构造方法,订阅事件
{
_name = name;
cat.CatCryEvent += catCryHandler;
}
private void CatCryHandler(object sender,CatCryEventArgs args)//猫叫事件处理方法
{
WakeUp();
}
private void WakeUP()//惊醒方法
{
Console.WriteLine(_name + "醒了");
}
}
-------------------------------老鼠类型------------------------------
public class Mouse
{
private string _name;
public Mouse(string name,Cat cat)
{
_name = name;
cat.CatCryEvent += CatCryHandler;
}
private void CatCryHandler(object sender,CatCryEventArgs args)
{
Run();
}
private void Run()
{
Console.WriteLine(_name + "逃走了");
}
}
------------------------入口方法--------------------------
class MainClass
{
static void Main(string[] args)
{
Console.WriteLine("开始模拟");
Cat cat = new Cat("功夫熊猫");
Mouse mouse1 = new Mouse("小拉登老鼠", cat);
Mouse mouse1 = new Mouse("大拉登老鼠", cat);
Master master = new Master("小布什",cat);
cat.CatCry();
Console.Read();
}
}在老鼠和主人类型初始化时,都订阅了猫叫的事件,这样猫叫发生时,猫类型的对象会负责通知所有的事件订阅者。本问题的关键就在于主人和老鼠的动作应该完全由猫叫来触发。
几点改进方案:
1.主人的惊醒和老鼠的逃跑应该是完全并行的,但是委托链表的调用却是串行的,可以考虑改进。
2.主人类型和猫类型可以考虑设计成静态的,这取决于实际业务逻辑。
3.主人、老鼠和猫类型的信息只有一个名字字符,可以考虑为每个类型设计一个信息结构,如主人信息结构、猫信息结构。也可以考虑设计一个信息基类,这样每个信息类都可以从中派生。
-------------编译执行结果:
开始模拟
功夫熊猫叫了
小拉登老鼠逃走了
大拉登老鼠逃走了
小布什醒了