再看C#中的委托和事件

一口一个设计模式--观察者模式中,我们已经知道如何应用观察者模式,但通过最近的深入学习,发现观察者模式存在以下缺陷:

1.抽象通知者依赖于抽象观察者;

2.每个具体观察者被调用的方法必须一致。

比如在机房收费系统中关于观察者模式的应用如下图所示:

这个设计存在以下问题:

1.抽象通知者需要把抽象观察者中的所有具体对象添加到集合中,以备向每个具体观察者发送通知消息;

2.在发送通知消息时,具体观察者中被通知的方法必须一致,否则具体通知者无法完成遍历;

3.更新卡内余额、更新学生上机状态和保存学生上机记录这三个类没什么相同的地方,抽象出来的抽象观察者有点牵强。

经过苦苦的思索,我发现用C#中的委托和事件机制解决上述问题,代码结构如下:

抽象通知者:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 观察者模式_委托
{
    public interface Informer
    {
        void Notify();
        string Action { get; set; }
    }
}

具体通知者--正常下机:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 观察者模式_委托
{
    public class Down : Informer
    {
        //声明一个委托
        public delegate void EventHandler();
        //为委托EventHandler添加事件Update
        public event EventHandler Update;

        public void Notify()
        {
            this.Update();
        }

        private string action;

        public string Action
        {
            get { return action; }
            set { action = value; }
        }
    }
}

具体通知者--强制下机:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 观察者模式_委托
{
    public class ForceDown : Informer
    {
        //声明一个委托
        public delegate void EventHandler();
        //为委托EventHandler添加事件Update
        public event EventHandler Update;

        public void Notify()
        {
            this.Update();
        }

        private string action;
        public string Action
        {
            get { return action; }
            set { action = value; }
        }
    }
}

这个我们不需要抽象观察者,直接具体观察者--更新卡内余额:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 观察者模式_委托
{
    public class UpdateBalance
    {
        protected Informer dn;
        public UpdateBalance(Informer dn)
        {
            this.dn = dn;
        }
        public void ModifyBalance()
        {
            Console.WriteLine("{0}!该卡要下机,更新余额!", dn.Action);
        }
    }
}

具体观察者--更新学生上机状态:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 观察者模式_委托
{
    public class OffLine
    {
        protected Informer dn;
        public OffLine(Informer dn)
        {
            this.dn = dn;
        }
        public void DelOnlineInfo()
        {
            Console.WriteLine("{0}!该卡要下机,删除正在上机表中的该卡信息!", dn.Action);
        }
    }
}

具体观察者--保存学生上机记录:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 观察者模式_委托
{
    public class SaveRec
    {
        protected Informer dn;
        public SaveRec(Informer dn)
        {
            this.dn = dn;
        }
        public void SaveLineRec()
        {
            Console.WriteLine("{0}!该卡要下机,保存上机记录信息!", dn.Action);
        }
    }
}

main方法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 观察者模式_委托
{
    class Program
    {
        static void Main(string[] args)
        {
            Down dn = new Down();

            OffLine ol = new OffLine(dn);
            UpdateBalance up = new UpdateBalance(dn);
            SaveRec sr = new SaveRec(dn);

           dn.Update+=new Down.EventHandler(ol.DelOnlineInfo);
           dn.Update += new Down.EventHandler(up.ModifyBalance);
           dn.Update += new Down.EventHandler(sr.SaveLineRec);

           dn.Action = "刷卡下机";
           dn.Notify();
        }
    }
}

程序执行结果如下所示:

通过执行结果,我们可以发现,在main方法中的正常下机事件dn.Update发生后,通过委托Down.EventHandler绑定到dn.Update事件上的三个方法ol.DelOnlineInfo、up.ModifyBalance、sr.SavelineRec都会被执行,达到观察者模式的效果。

现在我们可以发现:抽象通知者不再依赖于抽象观察者,因为抽象通知者通过委托通知具体观察者;具体观察者中被调用的方法也没必要一致,因为只需把想要执行的方法绑定到事件上就行;具体通知者也不必存在共性,不必牵强的对这三个类进行抽象。委托+事件完美解决上述问题。

再看C#中的委托和事件

时间: 2024-10-09 21:20:48

再看C#中的委托和事件的相关文章

C# 中的委托和事件

http://www.cnblogs.com/JimmyZhang/archive/2007/09/23/903360.html 文中代码在VS2005下通过,由于VS2003(.Net Framework 1.1)不支持隐式的委托变量,所以如果在一个接受委托类型的位置直接赋予方法名,在VS2003下会报错,解决办法是显式的创建一个委托类型的实例(委 托变量).例如:委托类型 委托实例 = new 委托类型(方法名); 欢迎浏览本文的后续文章: C#中的委托和事件(续) 引言 委托 和 事件在

C#中的委托和事件(续)

C#中的委托和事件(续) 引言 如果你看过了 C#中的委托和事件 一文,我想你对委托和事件已经有了一个基本的认识.但那些远不是委托和事件的全部内容,还有很多的地方没有涉及.本文将讨论委托和事件一些更为细节的问题,包括一些大家常问到的问题,以及事件访问器.异常处理.超时处理和异步方法调用等内容. 为什么要使用事件而不是委托变量? 在 C#中的委托和事件 中,我提出了两个为什么在类型中使用事件向外部提供方法注册,而不是直接使用委托变量的原因.主要是从封装性和易用性上去考虑,但是还漏掉了一点,事件应该

(转)C# 中的委托和事件

C# 中的委托和事件 引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里别(biè)得慌,混身不自在.本文中,我将通过两个范例由浅入深地讲述什么是委托.为什么要使用委托.事件的由来..Net Framework中的委托和事件.委托和事件对Observer设计模式的意义,对它们的中间代码也做了讨论. 将方法作为方法的参

C# 中的委托和事件详解

C# 中的委托和事件 文中代码在VS2005下通过,由于VS2003(.Net Framework 1.1)不支持隐式的委托变量,所以如果在一个接受委托类型的位置直接赋予方法名,在VS2003下会报错,解决办法是显式的创建一个委托类型的实例(委托变量).例如:委托类型 委托实例 = new 委托类型(方法名); 引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易

C# 中的委托和事件(1)

引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里别(biè)得慌,混身不自在.本文中,我将通过两个范例由浅入深地讲述什么是委托.为什么要使用委托.事件的由来..Net Framework中的委托和事件.委托和事件对Observer设计模式的意义,对它们的中间代码也做了讨论. 将方法作为方法的参数 我们先不管这个标题

.NET之美——C# 中的委托和事件

C# 中的委托和事件 文中代码在VS2005下通过,由于VS2003(.Net Framework 1.1)不支持隐式的委托变量,所以如果在一个接受委托类型的位置直接赋予方法名,在VS2003下会报错,解决办法是显式的创建一个委托类型的实例(委托变量).例如:委托类型 委托实例 = new 委托类型(方法名); 欢迎浏览本文的后续文章: C#中的委托和事件(续) 引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易

c#中的委托和事件(转)

引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里别(biè)得慌,混身不自在.本文中,我将通过两个范例由浅入深地讲述什么是委托.为什么要使用委托.事件的由来..Net Framework中的委托和事件.委托和事件对Observer设计模式的意义,对它们的中间代码也做了讨论. 将方法作为方法的参数 我们先不管这个标题

【转】c#中的委托和事件

引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里别(biè)得慌,混身不自在.本文中,我将通过两个范例由浅入深地讲述什么是委托.为什么要使用委托.事件的由来..Net Framework中的委托和事件.委托和事件对Observer设计模式的意义,对它们的中间代码也做了讨论. 将方法作为方法的参数 我们先不管这个标题

C# 中的委托和事件(转)

C# 中的委托和事件 文中代码在VS2005下通过,由于VS2003(.Net Framework 1.1)不支持隐式的委托变量,所以如果在一个接受委托类型的位置直接赋予方法名,在VS2003下会报错,解决办法是显式的创建一个委托类型的实例(委托变量).例如:委托类型 委托实例 = new 委托类型(方法名); 欢迎浏览本文的后续文章: C#中的委托和事件(续) 引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易