heart 板


LINE

你的比喻很有趣,而且抓住了事件驱动的核心概念——**当某个事情发生(事件),感兴趣 的对象(订阅器)会执行相应的动作(处理程序)**。 你的比喻本身的方向是正确的,只是在具体对应到程式码中的「委托」和「事件」时,可能 需要稍微调整一下。让我们来分析你的情境,并进行修正和更清晰的对应: **情境 A:忍者与主公密函** * **发布器:主公 (Lord)** * **事件:密函送达 (SecretMessageArrived)** * 这个事件可以携带密函的内容(例如:目标、时间、地点等资讯)。 * 在程式码中,「密函送达」会是一个基於特定委托的 `event`。这个委托会定义 事件处理程序需要接收的参数,例如密函内容的字串或其他更复杂的物件。 * **订阅器:忍者 (Ninja)** * **处理程序:执行暗杀任务 (ExecuteAssassination)** * 不同的忍者可能有不同的暗杀方法。每个忍者会编写一个符合「密函送达」事件 委托签名的方法来处理密函。 * 例如,一个忍者可能专精於近身格斗,另一个擅长远程毒杀。他们都会订阅「密 函送达」事件,并在收到密函时执行他们各自的暗杀处理程序。 **程式码概念对应:** ```csharp // 委托:定义了处理密函的方法签名 public delegate void SecretMessageHandler(string target, DateTime deadline, stri ng location); // 发布器:主公 public class Lord { // 事件:密函送达 public event SecretMessageHandler SecretMessageArrived; // 发布密函的方法 public void SendSecretMessage(string target, DateTime deadline, string locat ion, string messageContent) { Console.WriteLine($"主公发出密函:目标 {target}, 时间 {deadline}, 地点 { location}"); // 触发事件,将密函内容传递给所有订阅的忍者 SecretMessageArrived?.Invoke(target, deadline, location); // 这里的 messageContent 可以是额外的资讯,或者直接包含在参数中 } } // 订阅器:忍者 public class Ninja { public string Name { get; set; } public Ninja(string name) { Name = name; } // 处理程序 1:近身暗杀 public void MeleeAssassination(string target, DateTime deadline, string loca tion) { Console.WriteLine($"{Name} 接到密函,将於 {deadline} 在 {location} 对 {t arget} 进行近身暗杀。"); // 具体的暗杀逻辑 } // 处理程序 2:远程毒杀 public void PoisonAssassination(string target, DateTime deadline, string loc ation) { Console.WriteLine($"{Name} 接到密函,将於 {deadline} 在 {location} 对 {t arget} 进行远程毒杀。"); // 具体的毒杀逻辑 } } public class ScenarioA { public static void Run() { Lord lord = new Lord(); Ninja ninjaA = new Ninja("风影"); Ninja ninjaB = new Ninja("月影"); // 忍者订阅主公的密函事件,并绑定自己的处理程序 lord.SecretMessageArrived += ninjaA.MeleeAssassination; lord.SecretMessageArrived += ninjaB.PoisonAssassination; // 主公发出密函 lord.SendSecretMessage("敌方首领", DateTime.Now.AddDays(3), "敌方城堡", "务必成功!"); } } ``` **情境 B:保险业车祸评估** * **发布器:车祸事件记录系统 (AccidentRecorder)** * **事件:车祸发生 (AccidentOccurred)** * 这个事件需要包含车祸的相关资讯,例如地点、时间、涉及车辆、人员伤亡情况 等。这会定义委托的参数。 * **订阅器:保险公司评估部门 (InsuranceAssessment)** * **处理程序:测量与评估损失 (MeasureAndEvaluateLoss)** * 不同的保险公司或不同的评估人员可能有不同的评估流程和标准。每个评估部门 会编写一个符合「车祸发生」事件委托签名的方法来处理车祸资讯。 * 例如,一个评估员可能负责初步现场勘查,另一个负责医疗费用评估,还有一个 负责车辆损失评估。他们都会订阅「车祸发生」事件,并执行他们各自的评估处理程序。 **程式码概念对应:** ```csharp // 委托:定义了处理车祸资讯的方法签名 public delegate void AccidentHandler(string location, DateTime time, string[] in volvedVehicles, string[] injuries); // 发布器:车祸事件记录系统 public class AccidentRecorder { // 事件:车祸发生 public event AccidentHandler AccidentOccurred; // 记录车祸并发布事件的方法 public void RecordAccident(string location, DateTime time, string[] vehicles , string[] injuries) { Console.WriteLine($"记录到一起车祸:地点 {location}, 时间 {time}"); // 触发事件,将车祸资讯传递给所有订阅的保险公司评估部门 AccidentOccurred?.Invoke(location, time, vehicles, injuries); } } // 订阅器:保险公司评估部门 public class InsuranceAssessment { public string DepartmentName { get; set; } public InsuranceAssessment(string name) { DepartmentName = name; } // 处理程序 1:现场初步勘查 public void InitialAssessment(string location, DateTime time, string[] vehic les, string[] injuries) { Console.WriteLine($"{DepartmentName} 进行现场初步勘查,地点:{location} ,时间:{time}。"); // 现场勘查逻辑 } // 处理程序 2:医疗费用评估 public void MedicalAssessment(string location, DateTime time, string[] vehic les, string[] injuries) { Console.WriteLine($"{DepartmentName} 评估伤亡人员的医疗费用。"); // 医疗费用评估逻辑 } // 处理程序 3:车辆损失评估 public void VehicleDamageAssessment(string location, DateTime time, string[] vehicles, string[] injuries) { Console.WriteLine($"{DepartmentName} 评估涉及车辆的损失情况:{string.Joi n(", ", vehicles)}。"); // 车辆损失评估逻辑 } } public class ScenarioB { public static void Run() { AccidentRecorder recorder = new AccidentRecorder(); InsuranceAssessment companyA = new InsuranceAssessment("快速理赔中心"); InsuranceAssessment companyB = new InsuranceAssessment("专业评估团队"); // 保险公司评估部门订阅车祸事件 recorder.AccidentOccurred += companyA.InitialAssessment; recorder.AccidentOccurred += companyB.VehicleDamageAssessment; recorder.AccidentOccurred += companyB.MedicalAssessment; // 记录并发布车祸事件 recorder.RecordAccident("市中心十字路口", DateTime.Now, new string[] { " 轿车A", "卡车B" }, new string[] { "驾驶员A轻伤", "乘客B重伤" }); } } ``` **你的比喻很棒,它们清晰地展现了事件驱动的模式:** * **事件是发布器发生的重要事情。** * **订阅器是对这些事件感兴趣的对象。** * **处理程序是订阅器在接收到事件通知後执行的具体动作。** 关键在於理解程式码中的 **委托 (Delegate)** 定义了事件发生时,发布器会传递给订阅 者的资料的「格式」和订阅者需要提供的「处理方法」的签名。而 **事件 (event)** 则是 发布器中让订阅者可以「注册」他们符合这个「格式」的处理程序的地方。 所以,`RecordHandler` 只是我们在之前例子中使用的委托名称,你可以根据不同的情境定 义不同的委托名称和签名,例如 `SecretMessageHandler` 和 `AccidentHandler`。事件的 名称 (`Record`、`SecretMessageArrived`、`AccidentOccurred`) 也可以根据情境来命名 。 你的比喻是完全可行的,并且有助於理解事件驱动架构的灵活性和不同组件之间的松耦合。 --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 223.138.162.107 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/heart/M.1745899696.A.892.html







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:BabyMother站内搜寻

TOP