使用EventBus对模块解耦(附实例)
用于模块间解耦,通过发布订阅的方式调用,每个人只负责自己的那部分。
写个小例子,比如现在有三个模块,订单、购物车、优惠券,由不同的人负责开发。
负责订单模块的人现在需要写个生成订单的方法,生成订单的逻辑包括删除购物车项、标记优惠券已使用。
如果直接调用购物车、优惠券两个模块中的方法,耦合性高。
此时可以使用EventBus进行解耦。
public class EventBus
{
private EventBus() { }
private static Object syncObj = new object();
private static EventBus _instance = null;
public static EventBus Instance
{
get
{
if (_instance == null)
{
lock (syncObj)
{
if (_instance == null)
{
_instance = new EventBus();
}
}
}
return _instance;
}
}
private ConcurrentDictionary<string, List<Action<object[]>>> _dict = new ConcurrentDictionary<string, List<Action<object[]>>>();
private bool ExistEvent(string eventName)
{
if (_dict.ContainsKey(eventName))
{
return true;
}
return false;
}
public void InvokeEvent(string eventName,object[] args)
{
if (!this.ExistEvent(eventName))
{
return;
}
foreach (var eventHandler in this._dict[eventName])
{
eventHandler.Invoke(args);
}
}
public void AddEvent(string eventName, Action<object[]> eventHandler)
{
if (this.ExistEvent(eventName))
{
this._dict[eventName].Add(eventHandler);
}
else {
this._dict[eventName] = new List<Action<object[]>> { eventHandler };
}
}
public void AddEvent(string eventName, List<Action<object[]>> eventHandlerList)
{
if (this.ExistEvent(eventName))
{
this._dict[eventName].AddRange(eventHandlerList);
}
else
{
this._dict[eventName] = eventHandlerList;
}
}
public void RemoveEvent(string eventName)
{
if (this.ExistEvent(eventName))
{
this._dict.TryRemove(eventName,out var value);
}
}
public void RemoveEvent(string eventName, Action<object[]> eventHandler)
{
if (this.ExistEvent(eventName))
{
this._dict[eventName].Remove(eventHandler);
}
}
}
public class ShopCartService
{
/// <summary>
/// 删除购物车
/// </summary>
/// <param name="shopCartID"></param>
public void RemoveShopCart(int orderID)
{
Console.WriteLine($"已删除订单{orderID}的购物车项");
}
}
public class CouponService
{
/// <summary>
/// 标记优惠券已使用
/// </summary>
public void RecordUsedCoupon(int orderID)
{
Console.WriteLine($"已将订单{orderID}标记已使用优惠券");
}
}
public class OrderService
{
/// <summary>
/// 创建订单
/// </summary>
public void CreateOrder()
{
;
Console.WriteLine($"生成订单");
EventBus.Instance.InvokeEvent(EventNames.CREATEORDER_EVENT, new object[] { orderID });
}
}
public static class EventNames
{
public static string CREATEORDER_EVENT = "CreateOrder";
}
---------------------------------------------------------------------------
订阅、发布
static void Main(string[] args)
{
//订阅
EventBus.Instance.AddEvent(EventNames.CREATEORDER_EVENT, new List<Action<object[]>>
{
(args)=>{ ].ToString())); },
(args)=>{ ].ToString())); }
});
var orderService = new OrderService();
orderService.CreateOrder();
}
使用EventBus对模块解耦(附实例)的更多相关文章
- Java经典设计模式之十一种行为型模式(附实例和详解)
Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:Java经典设计模式之 ...
- Java设计模式之十一种行为型模式(附实例和详解)
Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:J设计模式之五大创建型 ...
- (转)Java经典设计模式(3):十一种行为型模式(附实例和详解)
原文出处: 小宝鸽 Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:J ...
- Linux chmod命令修改文件与文件夹权限的命令附实例
Linux chmod命令修改文件与文件夹权限的命令附实例 作者:佚名 字体:[增加 减小] 来源:互联网 时间:05-01 20:46:07我要评论 在linux中要修改一个文件夹或文件的权限我们需 ...
- Java经典设计模式之七大结构型模式(附实例和详解)
博主在大三的时候有上过设计模式这一门课,但是当时很多都基本没有听懂,重点是也没有细听,因为觉得没什么卵用,硬是要搞那么复杂干嘛.因此设计模式建议工作半年以上的猿友阅读起来才会理解的比较深刻.当然,你没 ...
- Java设计模式之七大结构型模式(附实例和详解)
博主在大三的时候有上过设计模式这一门课,但是当时很多都基本没有听懂,重点是也没有细听,因为觉得没什么卵用,硬是要搞那么复杂干嘛.因此设计模式建议工作半年以上的猿友阅读起来才会理解的比较深刻.当然,你没 ...
- (转)Java经典设计模式(2):七大结构型模式(附实例和详解)
原文出处: 小宝鸽 总体来说设计模式分为三大类:创建型模式.结构型模式和行为型模式. 博主的上一篇文章已经提到过创建型模式,此外该文章还有设计模式概况和设计模式的六大原则.设计模式的六大原则是设计模式 ...
- web自动化测试-模块驱动测试实例和数据驱动测试实例
一.模块驱动测试实例 把登录和退出统一封装在login类中,若把login类单独放在一个文件中,就可以给任一测试脚本调用,这里就跟测试脚本放一起 from selenium import webdri ...
- Python命令行参数解析模块getopt使用实例
Python命令行参数解析模块getopt使用实例 这篇文章主要介绍了Python命令行参数解析模块getopt使用实例,本文讲解了使用语法格式.短选项参数实例.长选项参数实例等内容,需要的朋友可以参 ...
随机推荐
- 【操作系统之十五】iptables黑白名单、自定义链、网络防火墙、常用动作
1.黑白名单当链的默认策略为ACCEPT时,链中的规则对应的动作应该为DROP或者REJECT,表示只有匹配到规则的报文才会被拒绝,没有被规则匹配到的报文都会被默认接受,这就是"黑名单&qu ...
- GC分析工具使用-gceacy分析堆栈
gceasy是一款在线的gc分析工具.试用一下分析jstack的日志 1.jstack -l 3539 > 3539.stack 2.打包成zip文件 3.上传https://gceasy.io ...
- # Leetcode 67:Add Binary(二进制求和)
Leetcode 67:Add Binary(二进制求和) (python.java) Given two binary strings, return their sum (also a binar ...
- 利用mysql的LOAD DATA INFILE的功能读取客户端文件
前言:今天在浏览某知论坛时,看到某大佬在渗透过程中使用伪造的MySQL服务端读取客户端文件,此大佬在利用过程中描述得不是很详细,作为小白的我看不懂啊,由此产生了此篇文章. 某大佬文章:https:// ...
- JS修改URL参数,并修改前页面的地址
function changeURLArg(url,arg,arg_val){ var pattern=arg+'=([^&]*)'; var replaceText=arg+'='+arg_ ...
- json工具类(三)——net包
package com.ruoyi.common.utils.json; import java.util.List; import java.util.Map; import net.sf.json ...
- 《 .NET并发编程实战》阅读指南 - 第3章
先发表生成URL以印在书里面.等书籍正式出版销售后会公开内容.
- com.fasterxml.jackson.core.JsonGenerationException: Can not write a field name, expecting a value异常
springboot对象返回,一直报生成json异常,经过检查,发现是自己在做xss防护时对出参进行了json的处理(copy代码不可取,囧) 异常信息 这里进行了出参处理了,但实际上只要对入参处理就 ...
- SpringBoot 通过jjwt快速实现token授权
A 10分钟了解JSON Web令牌(JWT)https://baijiahao.baidu.com/s?id=1608021814182894637&wfr=spider&for=p ...
- MVC+Ninject+三层架构+代码生成 -- 总结(七、顯示層 一)
1.顯示層 在網上找的 Bootstrap 模板.