zoukankan      html  css  js  c++  java
  • 再看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都会被运行,达到观察者模式的效果。

      如今我们能够发现:抽象通知者不再依赖于抽象观察者,由于抽象通知者通过托付通知详细观察者;详细观察者中被调用的方法也不是必需一致。由于仅仅需把想要运行的方法绑定到事件上即可。详细通知者也不必存在共性,不必牵强的对这三个类进行抽象。托付+事件完美解决上述问题。  

  • 相关阅读:
    [LeetCode] 827. Making A Large Island 建造一个巨大岛屿
    [LeetCode] 916. Word Subsets 单词子集合
    [LeetCode] 828. Count Unique Characters of All Substrings of a Given String 统计给定字符串的所有子串的独特字符
    [LeetCode] 915. Partition Array into Disjoint Intervals 分割数组为不相交的区间
    [LeetCode] 829. Consecutive Numbers Sum 连续数字之和
    背水一战 Windows 10 (122)
    背水一战 Windows 10 (121)
    背水一战 Windows 10 (120)
    背水一战 Windows 10 (119)
    背水一战 Windows 10 (118)
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/6708195.html
Copyright © 2011-2022 走看看