当前位置: 移动技术网 > IT编程>开发语言>.net > 设计模式——观察者模式

设计模式——观察者模式

2018年09月13日  | 移动技术网IT编程  | 我要评论

慢慢的做记录,做最强大的自己

看了大话设计模式之后感触很深,发现自己还有很多学习的东西,设计软件并不是一两句代码把功能写完了就行,需要思考的内容有很多

代码来源参考大话设计模式这本书,这里在博客里记录一下,不可能每次都去翻书,但是在博客里面是非常好找的。

        观察者模式(observer)算是设计模式里面最经典的一个模式了,这个模式可以应用在业务逻辑处理与界面交互的过程中,官方解释就是在此种模式中,

一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。

举一个简单的例子,之前看到的面试题:

猫看见很多老鼠在偷米吃,大叫了一声,主人醒了,这就是一个经典的观察者模式,老鼠跟主人都是观察者(observer),而猫是一个被观察者(subject)

之前我同事还给我举了一个例子:项目经理,前台妹纸,还有科室成员,怎么防止项目经理突然间在同事都在做非工作上的事情时,提前预知,那么就需要前台妹纸去观察了。

那么怎么去实现观察者模式呢,那就是把观察者当一个整体给抽象出来。

就以猫遇见老鼠叫主人被惊醒这个为例子:

    首先,理解一下观察者是谁,这里面谁跟谁是什么关系,老鼠遇见猫又是什么反应,猫叫声对主人又产生了什么影响

 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();
        }

查看运行结果如下:

这样处理过程就在客户端进行,就不需要依赖抽象观察者了

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网