using System; using System.Collections; namespace test { public interface ICatCatcher { void DoSth(); } public interface ICatSubject { void RegesiterCatCatcher(ICatCatcher catCatcher); void Miao(); } public interface IRatSubject { void RegesiterRatCatcher(IRatCatcher ratCatcher); void Run(); } public interface IRatCatcher { void Wake(); } public class Cat : ICatSubject { public Cat() { } private ArrayList catcherList = new ArrayList(); public void RegesiterCatCatcher(ICatCatcher catcher) { catcherList.Add(catcher); } public void Miao() { Console.WriteLine("Miao"); for (int i = 0; i < catcherList.Count; i++) { ICatCatcher catCatcher = (ICatCatcher)catcherList[i]; catCatcher.DoSth(); } } [STAThread] public static void Main() { Cat cat = new Cat(); Rat[] rat = new Rat[10]; for (int i = 0; i < 10; i++) { rat[i] = new Rat(cat); } Man man = new Man(rat, cat); cat.Miao(); } } public class Rat : ICatCatcher, IRatSubject { public Rat(ICatSubject catSub) { catSub.RegesiterCatCatcher(this); } public void DoSth() { Run(); } private ArrayList ratcherList = new ArrayList(); public void RegesiterRatCatcher(IRatCatcher catcher) { ratcherList.Add(catcher); } public void Run() { Console.WriteLine("Rat Run"); for (int i = 0; i < ratcherList.Count; i++) { IRatCatcher ratCatcher = (IRatCatcher)ratcherList[i]; ratCatcher.Wake(); } } } public class Man : ICatCatcher, IRatCatcher { public Man(IRatSubject[] ratSub, ICatSubject catSub) { for (int i = 0; i < ratSub.Length; i++) { ratSub[i].RegesiterRatCatcher(this); } catSub.RegesiterCatCatcher(this); } public void DoSth() { Console.WriteLine("Cat bring on Wake"); } public void Wake() { Console.WriteLine("Rats bring on Wake"); } } } 或者 http://hi.baidu.com/xiao_5_zi/blog/item/fe42f522db5073589922edff.html
不玩设计模式。对于c#来说(也包括所有.net平台开发语言以及早期的vb版本都是基于事件驱动方式),就是:using System;namespace ConsoleApplication1 { class Program { static void Main(string[] args) { 老鼠 m = new 老鼠(); 人 p = new 人(); 猫 c = new 猫(); m.跑了 += c.叫; m.跑了 += p.醒了; Console.WriteLine("测试开始............"); m.开跑(); Console.WriteLine("..................测试结束!"); Console.ReadKey(); } } public class 老鼠 { public event Action 跑了; public void 开跑() { Console.WriteLine("老鼠跑"); if (跑了 != null) 跑了(); } } public class 猫 { public void 叫() { Console.WriteLine("猫叫"); } } public class 人 { public void 醒了() { Console.WriteLine("人醒了"); } } } 这里最关键的就是让两个完全不同class的对象实例去监听老鼠跑的动作,如果写出这两句就可以100分了。
或者修改一下需求描述:using System;namespace ConsoleApplication1 { class Program { static void Main(string[] args) { 老鼠 m = new 老鼠(); 人 p = new 人(); 猫 c = new 猫(); c.叫了 += p.醒了; m.跑了 += c.叫; Console.WriteLine("测试开始............"); m.开跑(); Console.WriteLine("..................测试结束!"); Console.ReadKey(); } } public class 老鼠 { public event Action 跑了; public void 开跑() { Console.WriteLine("老鼠跑"); if (跑了 != null) 跑了(); } } public class 猫 { public event Action 叫了; public void 叫() { Console.WriteLine("猫叫"); if (this.叫了 != null) this.叫了(); } } public class 人 { public void 醒了() { Console.WriteLine("人醒了"); } } }
嗯,让我们看看怎样让mobile手机界面像iPhone界面一样上下滑动。其实很简单,假设要让一个用户控件相对于它的父控件上下滑动(当它的界面大小大于父控件所留出的大小时),我们可以使用扩展方法来为任意用户控件增加新的共嫩:using System.Drawing; using System.Windows.Forms;namespace MyNameSpace { public static class Extensions { public static void SetDragEvents(this UserControl ctrl) { bool DragFlag = false; Point PreviousPoint = Point.Empty; ctrl.MouseDown += (s, e) => { DragFlag = true; PreviousPoint = new Point(e.X, e.Y); ctrl.SuspendLayout(); }; ctrl.MouseUp += (s, e) => DragFlag = false; { DragFlag = false; ctrl.ResumeLayout(); }; ctrl.MouseMove += (s, e) => { if (DragFlag) { var t = ctrl.Top + e.Y - PreviousPoint.Y; if (t <= 0 && t + ctrl.Height >= ctrl.Parent.Height) ctrl.Top = t; } }; } } }好了,这就可以用手指拖动控件的留白处上下移动界面了。这样我们就可以设计一个比窗体高很多的用户控件,例如用户需要5、6个步骤才能操作完的、但是功能极其浓缩的界面。我想强调的是,从代码中你就能看出,这里我们为任意ctrl增加了3个事件处理程序(也许它早就有别的程序已经对相同的事件注册过处理程序,但是我们的程序根本不管它),并且这些事件程序还能使用在时间处理程序之外定义的记忆状态的变量值,所有这一切我们都是在一个方法里搞定!因此可以看到这种开发理念,我们需要ctrl搞什么很特殊模式吗?我们也没有去声明和创建什么单独的观察者对象实例,我们就是在这样一个方法中写几行简单的代码而已嘛!学.net设计,不一定照抄10几年前的java早期的书本知识,你当作猎奇去看看设计模式就足够了!
为任意用户控件增加新的共嫩 --> 为任意用户控件增加新的手指拖动的功能我们只要写一句话:public partial class Form1 : Form { public Form1() { InitializeComponent(); this.setUserAvatar1.SetDragEvents(); } } 这就为控件 setUserAvatar1 (其实任何用户控件都可以)添加了这个功能。多么简单!我们还可以更好地处理手指滑动行为,例如支持左右移动、为控件的移动增加速度感觉等等。而我要用这个程序强调的是,事件使用起来是多么轻松的东西啊,可不要太繁文缛节又是这么设计又是那么模式化地。
这个面试题是用委托和事件描述猫叫,主人醒,老鼠跑 class Program { static void Main(string[] args) { 主人 主人 = new 主人(); 猫 猫 = new 猫(); 老鼠 老鼠 = new 老鼠(); 猫.事件_叫 += new 猫.委托_叫(主人.主人醒); 猫.事件_叫 += new 猫.委托_叫(老鼠.跑); 猫.猫叫(); } } public class 猫 { public delegate void 委托_叫(); public event 委托_叫 事件_叫; public void 猫叫() { Console.WriteLine("喵...."); 事件_叫(); } } public class 主人 { public void 主人醒() { Console.WriteLine("谁?"); } } public class 老鼠 { public void 跑() { Console.WriteLine("我跑了!"); } }
using System;
using System.Collections;
namespace test
{
public interface ICatCatcher
{
void DoSth();
} public interface ICatSubject
{
void RegesiterCatCatcher(ICatCatcher catCatcher);
void Miao();
} public interface IRatSubject
{
void RegesiterRatCatcher(IRatCatcher ratCatcher);
void Run();
} public interface IRatCatcher
{
void Wake();
} public class Cat : ICatSubject
{
public Cat()
{
} private ArrayList catcherList = new ArrayList();
public void RegesiterCatCatcher(ICatCatcher catcher)
{
catcherList.Add(catcher);
} public void Miao()
{
Console.WriteLine("Miao");
for (int i = 0; i < catcherList.Count; i++)
{
ICatCatcher catCatcher = (ICatCatcher)catcherList[i];
catCatcher.DoSth();
}
} [STAThread]
public static void Main()
{
Cat cat = new Cat();
Rat[] rat = new Rat[10]; for (int i = 0; i < 10; i++)
{
rat[i] = new Rat(cat);
} Man man = new Man(rat, cat);
cat.Miao();
}
} public class Rat : ICatCatcher, IRatSubject
{
public Rat(ICatSubject catSub)
{
catSub.RegesiterCatCatcher(this);
} public void DoSth()
{
Run();
} private ArrayList ratcherList = new ArrayList();
public void RegesiterRatCatcher(IRatCatcher catcher)
{
ratcherList.Add(catcher); } public void Run()
{
Console.WriteLine("Rat Run");
for (int i = 0; i < ratcherList.Count; i++)
{
IRatCatcher ratCatcher = (IRatCatcher)ratcherList[i];
ratCatcher.Wake();
}
}
} public class Man : ICatCatcher, IRatCatcher
{
public Man(IRatSubject[] ratSub, ICatSubject catSub)
{
for (int i = 0; i < ratSub.Length; i++)
{
ratSub[i].RegesiterRatCatcher(this);
}
catSub.RegesiterCatCatcher(this);
} public void DoSth()
{
Console.WriteLine("Cat bring on Wake");
} public void Wake()
{
Console.WriteLine("Rats bring on Wake");
}
}
}
或者
http://hi.baidu.com/xiao_5_zi/blog/item/fe42f522db5073589922edff.html
{
class Program
{
static void Main(string[] args)
{
老鼠 m = new 老鼠();
人 p = new 人();
猫 c = new 猫();
m.跑了 += c.叫;
m.跑了 += p.醒了;
Console.WriteLine("测试开始............");
m.开跑();
Console.WriteLine("..................测试结束!");
Console.ReadKey();
}
} public class 老鼠
{
public event Action 跑了; public void 开跑()
{
Console.WriteLine("老鼠跑");
if (跑了 != null)
跑了();
}
} public class 猫
{
public void 叫()
{
Console.WriteLine("猫叫");
}
} public class 人
{
public void 醒了()
{
Console.WriteLine("人醒了");
}
}
}
这里最关键的就是让两个完全不同class的对象实例去监听老鼠跑的动作,如果写出这两句就可以100分了。
设计模式如果成为八股文就会让人错误地滥用起来,设计模式只有观摩意义而对于许多开发者其实是一种坏味道。
{
class Program
{
static void Main(string[] args)
{
老鼠 m = new 老鼠();
人 p = new 人();
猫 c = new 猫();
c.叫了 += p.醒了;
m.跑了 += c.叫;
Console.WriteLine("测试开始............");
m.开跑();
Console.WriteLine("..................测试结束!");
Console.ReadKey();
}
} public class 老鼠
{
public event Action 跑了; public void 开跑()
{
Console.WriteLine("老鼠跑");
if (跑了 != null)
跑了();
}
} public class 猫
{
public event Action 叫了; public void 叫()
{
Console.WriteLine("猫叫");
if (this.叫了 != null)
this.叫了();
}
} public class 人
{
public void 醒了()
{
Console.WriteLine("人醒了");
}
}
}
using System.Windows.Forms;namespace MyNameSpace
{
public static class Extensions
{
public static void SetDragEvents(this UserControl ctrl)
{
bool DragFlag = false;
Point PreviousPoint = Point.Empty;
ctrl.MouseDown += (s, e) =>
{
DragFlag = true;
PreviousPoint = new Point(e.X, e.Y);
ctrl.SuspendLayout();
};
ctrl.MouseUp += (s, e) =>
DragFlag = false;
{
DragFlag = false;
ctrl.ResumeLayout();
};
ctrl.MouseMove += (s, e) =>
{
if (DragFlag)
{
var t = ctrl.Top + e.Y - PreviousPoint.Y;
if (t <= 0 && t + ctrl.Height >= ctrl.Parent.Height)
ctrl.Top = t;
}
};
}
}
}好了,这就可以用手指拖动控件的留白处上下移动界面了。这样我们就可以设计一个比窗体高很多的用户控件,例如用户需要5、6个步骤才能操作完的、但是功能极其浓缩的界面。我想强调的是,从代码中你就能看出,这里我们为任意ctrl增加了3个事件处理程序(也许它早就有别的程序已经对相同的事件注册过处理程序,但是我们的程序根本不管它),并且这些事件程序还能使用在时间处理程序之外定义的记忆状态的变量值,所有这一切我们都是在一个方法里搞定!因此可以看到这种开发理念,我们需要ctrl搞什么很特殊模式吗?我们也没有去声明和创建什么单独的观察者对象实例,我们就是在这样一个方法中写几行简单的代码而已嘛!学.net设计,不一定照抄10几年前的java早期的书本知识,你当作猎奇去看看设计模式就足够了!
{
public Form1()
{
InitializeComponent();
this.setUserAvatar1.SetDragEvents();
}
}
这就为控件 setUserAvatar1 (其实任何用户控件都可以)添加了这个功能。多么简单!我们还可以更好地处理手指滑动行为,例如支持左右移动、为控件的移动增加速度感觉等等。而我要用这个程序强调的是,事件使用起来是多么轻松的东西啊,可不要太繁文缛节又是这么设计又是那么模式化地。
{
static void Main(string[] args)
{
主人 主人 = new 主人();
猫 猫 = new 猫();
老鼠 老鼠 = new 老鼠();
猫.事件_叫 += new 猫.委托_叫(主人.主人醒);
猫.事件_叫 += new 猫.委托_叫(老鼠.跑);
猫.猫叫();
}
}
public class 猫
{
public delegate void 委托_叫();
public event 委托_叫 事件_叫;
public void 猫叫()
{
Console.WriteLine("喵....");
事件_叫();
}
}
public class 主人
{
public void 主人醒()
{
Console.WriteLine("谁?");
}
}
public class 老鼠
{
public void 跑()
{
Console.WriteLine("我跑了!");
}
}