C# 观察者模式

介绍

这里是从网络上找到的案例,猫捉耗子,猫叫 耗子跑 同时大人醒来,小孩子哭。这里伴随的就是观察模式。
源代码 内部存在处理timer组件和Task异步锁处理

新建目标基类

/// <summary>
/// 目标基类
/// </summary>
namespace DelegateEvent
{

    /**//// <summary>

        ///     在Observer Pattern(观察者模式)中,此类作为所有Subject(目标)的抽象基类

        /// 所有要充当Subject的类(在此事例中为"猫")都继承于此类.

        ///     我们说此类作为模型,用于规划目标(即发布方)所产生的事件,及提供触发

        /// 事件的方法.

        ///     此抽象类无抽象方法,主要是为了不能实例化该类对象,确保模式完整性.

        ///     具体实施:

        ///     1.声明委托

        ///     2.声明委托类型事件

        ///     3.提供触发事件的方法

        /// </summary>

    public abstract class ModelBase

    {

        public ModelBase()

        {

        }

        /**//// <summary>

            /// 声明一个委托,用于代理一系列"无返回"及"不带参"的自定义方法

            /// </summary>

        public delegate void SubEventHandler();

        /**//// <summary>

            /// 声明一个绑定于上行所定义的委托的事件

            /// </summary>

        public event SubEventHandler SubEvent;



        /**//// <summary>

            /// 封装了触发事件的方法

            /// 主要为了规范化及安全性,除观察者基类外,其派生类不直接触发委托事件

            /// </summary>

        protected void Notify()

        {

            //提高执行效率及安全性

            if (this.SubEvent != null)

                this.SubEvent();



        }

    }

}

建立观察者基类

/// <summary>
/// 建立观察者基类(单行为,多行为)
/// </summary>
namespace DelegateEvent

{

    /**//// <summary>

        ///     在Observer Pattern(观察者模式)中,此类作为所有Observer(观察者)的抽象基类

        /// 所有要充当观察者的类(在此事例中为"老鼠"和"人")都继承于此类.

        ///     我们说此类作为观察者基类,用于规划所有观察者(即订阅方)订阅行为.

        ///     在此事例中,规划了针对目标基类(ModelBase)中声明的"无参无返回"委托的一个

        /// 方法(Response),并于构造该观察者时将其注册于具体目标(参数传递)的委托事件中.

        ///     具体实施过程:

        ///     1.指定观察者所观察的对象(即发布方).(通过构造器传递)

        ///     2.规划观察者自身需要作出响应方法列表

        ///     3.注册需要委托执行的方法.(通过构造器实现)

        /// </summary>

    public abstract class Observer

    {

        /**//// <summary>

            /// 构造时通过传入模型对象,把观察者与模型关联,并完成订阅.

            /// 在此确定需要观察的模型对象.

            /// </summary>

            /// <param name="childModel">需要观察的对象</param>

        public Observer(ModelBase childModel)
        {
            //订阅
            //把观察者行为(这里是Response)注册于委托事件
            childModel.SubEvent += new ModelBase.SubEventHandler(Response);
        }



        /**//// <summary>

            /// 规划了观察者的一种行为(方法),所有派生于该观察者基类的具体观察者都

            /// 通过覆盖该方法来实现作出响应的行为.

            /// </summary>

        public abstract void Response();

    }

}

再定义一个观察者基类

namespace DelegateEvent

{

    /**//// <summary>

        /// 定义了另一个观察者基类.该观察者类型拥有两个响应行为.

        /// 并在构造时将响应行为注册于委托事件.

        /// (具体描述请参照另一观察者基类Observer)

        /// </summary>

    public abstract class Observer2

    {

        /**//// <summary>

            /// 构造时通过传入模型对象,把观察者与模型关联,并完成订阅.

            /// 在此确定需要观察的模型对象.

            /// </summary>

            /// <param name="childModel">需要观察的对象</param>

        public Observer2(ModelBase childModel)

        {

            //订阅

            //把观察者行为(这里是Response和Response2)注册于委托事件

            childModel.SubEvent += new ModelBase.SubEventHandler(Response);

            childModel.SubEvent += new ModelBase.SubEventHandler(Response2);



        }

        /**//// <summary>

            /// 规划了观察者的二种行为(方法),所有派生于该观察者基类的具体观察者都

            /// 通过覆盖该方法来实现作出响应的行为.

            /// </summary>

        public abstract void Response();

        public abstract void Response2();

    }

}

大人

namespace DelegateEvent

{

    /**//// <summary>

        ///     此类为观察者模式中的具体观察者(即具体发布方),其继承于观察者基类.

        /// 其中覆盖了观察者基类规划好的方法,实现了响应的具体行为.

        /// </summary>

    public class Master : Observer

    {

        /**//// <summary>

            ///     构造时确定观察者所需要观察的对象(具体目标),并传递给观察者基类构造器,

            /// 实现响应行为(方法)的订阅.

            /// </summary>

        public Master(ModelBase childModel) : base(childModel)

        {

        }



        /**//// <summary>

            /// 覆盖了该类观察者需要作出的具体响应行为.

            /// 此行为已在观察者基类中注册于委托事件,由委托事件调度执行,不需要直接调用.

            /// </summary>

        public override void Response()

        {

            System.Console.WriteLine("主人醒来");

        }

    }

}

小孩

namespace DelegateEvent

{

    /**//// <summary>

        ///     此类为观察者模式中的具体观察者(即具体发布方),其继承了订阅了2个响应行为的

        /// 观察者基类.

        ///     其中覆盖了观察者基类规划好的二个方法,实现了响应的具体行为.

        /// </summary>

    public class Master2 : Observer2

    {

        /**//// <summary>

            ///     构造时确定观察者所需要观察的对象(具体目标),并传递给观察者基类构造器,

            /// 实现响应行为(方法)的订阅.

            /// </summary>

        public Master2(ModelBase childBase) : base(childBase)

        {

        }



        /**//// <summary>

            /// 覆盖了该类观察者需要作出的具体响应行为.

            /// 此行为已在观察者基类中注册于委托事件,由委托事件调度执行,不需要直接调用.

            /// </summary>

        public override void Response()

        {

            Console.WriteLine("baby醒来。。。。");



        }

        /**//// <summary>

            /// 覆盖了该类观察者需要作出的另一个响应行为.

            /// </summary>

        public override void Response2()

        {

            Console.WriteLine("开始哭闹。。。。。");

        }

    }

}

耗子

namespace DelegateEvent

{

    /**//// <summary>

        ///     此类为观察者模式中的具体观察者(即具体发布方),其继承于观察者基类.

        /// 其中覆盖了观察者基类规划好的方法,实现了响应的具体行为.

        /// </summary>

    public class Mouse : Observer

    {

        /**//// <summary>

            /// 观察者可以拥有自己的成员(字段或者方法).

            /// 在此事例中增加了"老鼠的名字"

            /// </summary>

        private string name;

        /**//// <summary>

            ///     构造时确定观察者所需要观察的对象(具体目标),并传递给观察者基类构造器,

            /// 实现响应行为(方法)的订阅.另外,为观察者实例初始化成员.

            /// </summary>

            /// <param name="name">老鼠的名字</param>

            /// <param name="childModel">

            ///需要观察的对象(发布方).

            ///此处用模型基类来传递,是为了兼容所有派生于此模型的观察者,从而提高扩展性.

            /// </param>

        public Mouse(string name, ModelBase childModel) : base(childModel)

        {

            //初始化字段(老鼠的名字)

            this.name = name;

        }

        /**//// <summary>

            /// 覆盖了该类观察者需要作出的具体响应行为.

            /// 此行为已在观察者基类中注册于委托事件,由委托事件调度执行,不需要直接调用.

            /// </summary>

        public override void Response()

        {

            //具体响应内容

            System.Console.WriteLine(this.name + "开始逃跑");

        }



    }

}

namespace DelegateEvent

{

    /**//// <summary>

        ///此类为观察者模式中的具体目标(即具体发布方),其继承于模型.
        ///其中包含(调用)了在模型中被封装好的触发委托事件的方法.
        /// </summary>

    public class Cat : ModelBase

    {

        public Cat()

        {

        }

        /**//// <summary>

            /// 定义了猫的一种行为----大叫

            /// </summary>

        public void Cry()

        {

            System.Console.WriteLine("Cat Cry..");

            //调用了触发委托事件的方法.

            //通知委托开始执行观察者已订阅的方法.

            this.Notify();

        }

    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个 C#观察者模式实例: ```csharp using System; using System.Collections.Generic; // 被观察者接口 interface ISubject { void Attach(IObserver observer); // 添加观察者 void Detach(IObserver observer); // 移除观察者 void Notify(); // 通知观察者 } // 观察者接口 interface IObserver { void Update(ISubject subject); // 接收通知并更新 } // 具体的被观察者类 class ConcreteSubject : ISubject { private List<IObserver> observers = new List<IObserver>(); private string state; // 被观察者状态 // 添加观察者 public void Attach(IObserver observer) { observers.Add(observer); } // 移除观察者 public void Detach(IObserver observer) { observers.Remove(observer); } // 通知观察者 public void Notify() { foreach (IObserver observer in observers) { observer.Update(this); } } // 修改状态并通知观察者 public void SetState(string state) { this.state = state; Notify(); } public string GetState() { return state; } } // 具体的观察者类 class ConcreteObserver : IObserver { private string name; // 观察者名称 public ConcreteObserver(string name) { this.name = name; } // 接收通知并更新 public void Update(ISubject subject) { Console.WriteLine("{0} 接收到了被观察者的通知,当前状态为 {1}", name, ((ConcreteSubject)subject).GetState()); } } // 测试代码 class Program { static void Main(string[] args) { ConcreteSubject subject = new ConcreteSubject(); // 添加观察者 subject.Attach(new ConcreteObserver("观察者 A")); subject.Attach(new ConcreteObserver("观察者 B")); subject.Attach(new ConcreteObserver("观察者 C")); // 修改状态并通知观察者 subject.SetState("状态 1"); // 移除观察者 subject.Detach(new ConcreteObserver("观察者 B")); // 修改状态并通知观察者 subject.SetState("状态 2"); Console.ReadKey(); } } ``` 以上代码实现了一个简单的观察者模式实例,其中 `ConcreteSubject` 是具体的被观察者类,实现了 `ISubject` 接口;`ConcreteObserver` 是具体的观察者类,实现了 `IObserver` 接口。在测试代码中,我们创建了一个 `ConcreteSubject` 对象,并添加了三个观察者,然后修改了状态并通知观察者,最后移除了一个观察者并再次修改状态并通知观察者。运行该程序,控制台输出如下: ``` 观察者 A 接收到了被观察者的通知,当前状态为 状态 1 观察者 B 接收到了被观察者的通知,当前状态为 状态 1 观察者 C 接收到了被观察者的通知,当前状态为 状态 1 观察者 A 接收到了被观察者的通知,当前状态为 状态 2 观察者 C 接收到了被观察者的通知,当前状态为 状态 2 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值