惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
T
Threatpost
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Tailwind CSS Blog
IT之家
IT之家
H
Hackread – Cybersecurity News, Data Breaches, AI and More
WordPress大学
WordPress大学
博客园 - 司徒正美
Microsoft Azure Blog
Microsoft Azure Blog
Hugging Face - Blog
Hugging Face - Blog
Google DeepMind News
Google DeepMind News
阮一峰的网络日志
阮一峰的网络日志
博客园 - 三生石上(FineUI控件)
Google Online Security Blog
Google Online Security Blog
The GitHub Blog
The GitHub Blog
Martin Fowler
Martin Fowler
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
有赞技术团队
有赞技术团队
S
SegmentFault 最新的问题
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Microsoft Security Blog
Microsoft Security Blog
Jina AI
Jina AI
G
GRAHAM CLULEY
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
Cyber Attacks, Cyber Crime and Cyber Security
A
About on SuperTechFans
Vercel News
Vercel News
The Cloudflare Blog
Cisco Talos Blog
Cisco Talos Blog
小众软件
小众软件
MyScale Blog
MyScale Blog
I
InfoQ
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
人人都是产品经理
人人都是产品经理
The Hacker News
The Hacker News
S
Security Affairs
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
MongoDB | Blog
MongoDB | Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
F
Fortinet All Blogs
Latest news
Latest news
Last Week in AI
Last Week in AI
博客园 - 叶小钗
H
Heimdal Security Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
V
Vulnerabilities – Threatpost
Project Zero
Project Zero

博客园 - 许明会

异步编程,采用WorkgroupWorker,async和await关键字 OCR图像识别技术-Asprise OCR JavaScript能干什么? C#泛型代理、泛型接口、泛型类型、泛型方法 Delegate, Method as Parameter. DES对称性加密 利用委托实现异步调用 通过Windows组策略限制证书组织流氓软件的安装运行 枚举\位域\结构综合实验 - 许明会 - 博客园 public static void Invoke (Action action) C#编写WIN32系统托盘程序 C#的互操作性:缓冲区、结构、指针 SQLServer异步调用,批量复制 Python体验(10)-图形界面之计算器 Python体验(09)-图形界面之Pannel和Sizer Python体验(08)-图形界面之工具栏和状态栏 Python体验(07)-图形界面之菜单 C#利用WIN32实现按键注册 Javascript猜数字游戏
关于委托,事件和类的设计准则
许明会 · 2016-04-14 · via 博客园 - 许明会

我们必须保持类型设计满足“高内聚,低耦合”,如此才能做到更好的代码重用。将应用拆解成组件类型可以实现高可维护性,并利于编码调试。

按钮点击、鼠标移动、键盘按键通常都是观察者模式的典型应用。封闭的类型对外发布事件,外部用用订阅类型的事件并编码实现在事件触发通知到系统后的操作,想想按钮Button类型来源于Windows.Forms名称空间,通过Dll提供,你没有Button类型的源代码不是一样注册Button的Click事件,从而让Button唤起你的Method,这个Dll就是一个有效封装。

委托必须实例化,或者指向一个实例化的方法才能被调用,我们无法直接用委托的名字加委托的参数定义一次函数Invoke,而事件充当此角色。事件的作用就是像委托的“样式”那样Invoke满足“样式”的方法,将任意多个满足“样式”的方法注册到事件上。“样式”本质是类型约束,所以委托就是C++的指针,但比C++多了类型检查,所以可以人为是强类型的指针,是在C++指针基础上的扩展类!

热水器带加热组件用于加热Heat(),热水器含有温度报警器设置预加热温度和报警温度,好的温度传感器甚至能够输出控制热水器的加热组件从而保持恒温。以热水器WaterHeater和温度传感报警器TemperatureAlarmer为例,下面展示其应用。可以直接拷贝代码到Vistual Studio,逐行调试并观察“即时窗口”的变量的变化情况,以深入理解。

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

namespace Demo
{
    /// <summary>
    /// 报警处理器:用于热水器及其关联的报警器
    /// </summary>
    /// <param name="heater">热水器</param>
    /// <param name="alarmer">报警器</param>
    public delegate void AlarmHandler(WaterHeater heater, TemperatureAlarmer alarmer);

    /// <summary>
    /// 温度报警器:设定当前温度和报警温度;
    /// 在超过报警温度后会触发事件 TemperatureOverflow,交给挂接报警器的设备处理
    /// </summary>
    public class TemperatureAlarmer
    {
        private float temperature_current, temperature_alarm;
        /// <summary>
        /// 在超过报警温度后会触发事件 TemperatureOverflow,交给挂接报警器的设备处理,如热水器
        /// </summary>
        public event Action TemperatureOverflow;

        //温度检查:超过报警温度后启动报警引擎
        private void TemperatureCheck()
        {
            if (temperature_current > temperature_alarm)
                TemperatureOverflow();
        }
        
        public TemperatureAlarmer()
        {
            temperature_current = 0f;
            temperature_alarm = 95f;
        }
        /// <summary>
        /// 属性:加热温度,范围35~100
        /// </summary>
        public float TemperaturCurrent
        {
            get { return temperature_current; }
            set
            {
                temperature_current = value > 100 ? 100 : value;
                temperature_current = value < 35 ? 35 : value;
                TemperatureCheck();
            }
        }
        /// <summary>
        /// 属性:报警温度,范围35~100
        /// </summary>
        public float TemperaturAlarm
        {
            get
            { return temperature_alarm; }
            set
            {
                temperature_alarm = value > 100 ? 100 : value;
                temperature_alarm = value < 35 ? 35 : value;
                TemperatureCheck();
            }
        }

    }

    /// <summary>
    /// 热水器,属于加热器,需要温度报警器
    /// </summary>
    public class WaterHeater
    {
        public string TradeMark { get; set; }
        public string Company { get; set; }
        public TemperatureAlarmer heaterAlarmer;
        /// 热水器报警事件,将处理权交给用户处理
        public event AlarmHandler TemperatureOverflow;
        /// 可以绑定更换掉默认的温度报警器
        public void BindAlarmer(TemperatureAlarmer alarmer)
        {
            this.heaterAlarmer = alarmer;
        }
        public WaterHeater()
        {
            heaterAlarmer = new TemperatureAlarmer();
            heaterAlarmer.TemperatureOverflow += () =>
            {
                TemperatureOverflow(this, heaterAlarmer);
            };
        }

        /// 对加热器进行加热,最高到100度,将温度增加到指定值
        public void Heat(float temperature)
        {
            heaterAlarmer.TemperaturCurrent = temperature;
        }

        public override string ToString()
        {
            return $"{this.Company},{this.TradeMark},{heaterAlarmer.TemperaturCurrent}/{heaterAlarmer.TemperaturAlarm}";
        }
    }

    /*
海信,?新婚之夜,0/95
Overflow:海信,?新婚之夜,88/80
海信,?新婚之夜,88/80
海信,?新婚之夜,95/95
海信,?新婚之夜,95/95
海信,?新婚之夜,90/95
    */
    public class RunMyApp
    {
        static void Main(string[] args)
        {
            WaterHeater HisenseWarmer = new WaterHeater();
            HisenseWarmer.Company = "海信";
            HisenseWarmer.TradeMark = "©新婚之夜";
            HisenseWarmer.TemperatureOverflow += (heater, e) => Console.WriteLine("Overflow:" + HisenseWarmer);
            Console.WriteLine(HisenseWarmer);//

            HisenseWarmer.Heat(88);//
            HisenseWarmer.heaterAlarmer.TemperaturAlarm = 80;//
            Console.WriteLine(HisenseWarmer);

            //更换第三方温度报警器,具有更高级的自我调节温度功能,也就是保证不超过报警温度
            TemperatureAlarmer OmronAlarmer = new TemperatureAlarmer();
            OmronAlarmer.TemperatureOverflow += () =>
            {
                OmronAlarmer.TemperaturCurrent = OmronAlarmer.TemperaturAlarm;
            };
            HisenseWarmer.BindAlarmer(OmronAlarmer);
            HisenseWarmer.Heat(96);
            Console.WriteLine(HisenseWarmer);

            OmronAlarmer.TemperaturCurrent = 100;
            Console.WriteLine(HisenseWarmer);

            HisenseWarmer.Heat(90);
            Console.WriteLine(HisenseWarmer);

            Console.ReadKey();
        }
    }
}