慢慢的作记录,作最强大的本身面试
看了大话设计模式以后感触很深,发现本身还有不少学习的东西,设计软件并非一两句代码把功能写完了就行,须要思考的内容有不少设计模式
代码来源参考大话设计模式这本书,这里在博客里记录一下,不可能每次都去翻书,可是在博客里面是很是好找的。学习
观察者模式(Observer)算是设计模式里面最经典的一个模式了,这个模式能够应用在业务逻辑处理与界面交互的过程当中,官方解释就是在此种模式中,this
一个目标物件管理全部相依于它的观察者物件,而且在它自己的状态改变时主动发出通知。这一般透过呼叫各观察者所提供的方法来实现。此种模式一般被用来实现事件处理系统。spa
举一个简单的例子,以前看到的面试题:设计
猫看见不少老鼠在偷米吃,大叫了一声,主人醒了,这就是一个经典的观察者模式,老鼠跟主人都是观察者(Observer),而猫是一个被观察者(Subject)code
以前我同事还给我举了一个例子:项目经理,前台妹纸,还有科室成员,怎么防止项目经理忽然间在同事都在作非工做上的事情时,提早预知,那么就须要前台妹纸去观察了。server
那么怎么去实现观察者模式呢,那就是把观察者当一个总体给抽象出来。对象
就以猫碰见老鼠叫主人被惊醒这个为例子:blog
首先,理解一下观察者是谁,这里面谁跟谁是什么关系,老鼠碰见猫又是什么反应,猫叫声对主人又产生了什么影响
public interface Observer { void Response(); //观察者的响应,如是老鼠见到猫的反映 } public interface Subject { void AimAt(Observer obs); //针对哪些观察者,这里指猫的要扑捉的对象---老鼠,还有猫惊醒的主人 }
老鼠见到猫的反应用一个类写出来
public class Mouse : Observer { private string name; public Mouse(string name, Subject subj) { this.name = name; subj.AimAt(this); } public void Response() { Console.WriteLine(name + " 开始逃窜!"); } }
而后主人被猫叫声吵醒,也是一个反应,这里继承观察者
public class Master : Observer { public Master(Subject subj) { subj.AimAt(this); } public void Response() { Console.WriteLine("吵死了!"); } }
猫是被观察者,主要产生的行为就是大叫一声
public class Cat : Subject { private ArrayList observers; public Cat() { this.observers = new ArrayList(); } public void AimAt(Observer obs) { this.observers.Add(obs); } public void Cry() { Console.WriteLine("猫大叫一声!"); foreach (Observer obs in this.observers) { obs.Response(); } } }
整个过程在客户端的代码就是这样的
class MainClass { static void Main(string[] args) { Cat cat = new Cat(); Mouse mouse1 = new Mouse("mouse1", cat); Mouse mouse2 = new Mouse("mouse2", cat); Master master = new Master(cat); cat.Cry(); } }
固然这里耦合程度仍是很高,主人跟老鼠的行为都是高度依赖猫这个抽象的观察者,怎么改才能解耦,那么就须要用到另一种方式:事件委托
这里声明了一个委托事件
public delegate void SubEventHandler(); public abstract class Subject { public event SubEventHandler SubEvent; protected void FireAway() { if (this.SubEvent != null) this.SubEvent(); } }
猫对被观察者的影响
class Cat : Subject { public new event SubEventHandler SubEvent; public void Cry() { SubEvent(); Console.WriteLine("猫大叫!"); } }
而后老鼠跟主人都被猫影响,观察者被被观察者影响,产生不一样的反应
interface Observer { void Response(); //观察者的响应,如是老鼠见到猫的反映 }
老鼠观察者的响应,产生逃跑反应
class MouseObserver { private string name; public MouseObserver(string name, Subject subj) { this.name = name; } public void Response() { Console.WriteLine(name + " 赶忙逃离!"); } }
主人观察者的反应,吵死了
class MasterObserver { private string name; public MasterObserver(string name, Subject subj) { this.name = name; } public void Response() { Console.WriteLine(name + ":吵死了!"); } }
而后在交互端反馈出来是这样的:
static void Main(string[] args) { Cat cat = new Cat(); MouseObserver mouse1 = new MouseObserver("mouse1", cat); MouseObserver mouse2 = new MouseObserver("mouse2", cat); MasterObserver Master = new MasterObserver("主人", cat); cat.SubEvent += new SubEventHandler(mouse1.Response); cat.SubEvent += new SubEventHandler(mouse2.Response); cat.SubEvent += new SubEventHandler(Master.Response); cat.Cry(); Console.ReadLine(); }
查看运行结果以下:
这样处理过程就在客户端进行,就不须要依赖抽象观察者了