大家好,现在有这么一个需求,请教一下有没有好的实现办法。
需求描述:
1、ClassA产生事件,可能有多种类型,例如:订单创建、订单付款、订单评价。。。等。
2、有许多类需要知道ClassA产生的事件中的一种或多种类型。例如:ClassB想知道ClassA产生的订单创建、订单评价这两个事件。
3、应该怎么实现?我现在的做法是:
1 Class A { 2 3 List<ClassAListener> listeners = new ArrayList<>(); 4 5 void produceEvent(String a){ 6 if(a == 订单创建){ 7 foreach(listeners as l){ 8 l.onCreated(); 9 }else if(a == 订单付款){ 10 foreach(listeners as l){ 11 l.onPay(); 12 } 13 } 14 } 15 } 16 }
然后让ClassB继续ClassAListener,重写onCreated、onPay等方法。
描述的可能不太清楚,大家都是高手应该可能看懂我的意思,有问题请留言。
谢谢大家了。
Class A中的 订单创建、订单付款、订单评价。。。等。这些行为是固定的?还是这些动作也是动态的。如果是固定的,用枚举,字符串数组等就行了,如果是动态的,是不是还要封装一下。或者楼主介绍一下最原始的需求,抛开代码实现来谈。另外:ClassAListener楼主你写了两个方法,并不是所有的订阅者都有这两个方法吧,为什么不是每个订阅者专门做一件事情,而是一个订阅者做两件事情。
Class A中的 订单创建、订单付款、订单评价。。。等。这些行为是固定的?
是固定的。如果用枚举、字符串数组,其它类应该如何订阅,该如何实现?
原始的需求,有些复杂,简单来说就是:
第三方的网站会通知我有订单创建、订单付款或其它的事件了,我这边需要对这一事件进行处理,同一个事件可能会在多个地方处理。
@lay_god:
AbsListener.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace OrderHelper { abstract class AbsListener { public abstract void Update(string orderId, OrderOperatorEnums.OrderOperator operatorType); } }
Listeners.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace OrderHelper { class Listener1 : AbsListener { public override void Update(string orderId, OrderOperatorEnums.OrderOperator operatorType) { if (operatorType == OrderOperatorEnums.OrderOperator.订单创建) { Console.WriteLine("我处理订单创建"); } } } class Listener2: AbsListener { public override void Update(string orderId, OrderOperatorEnums.OrderOperator operatorType) { if (operatorType == OrderOperatorEnums.OrderOperator.订单付款) { Console.WriteLine("我处理订单付款"); } } } class Listener3 : AbsListener { public override void Update(string orderId, OrderOperatorEnums.OrderOperator operatorType) { if (operatorType == OrderOperatorEnums.OrderOperator.订单评价) { Console.WriteLine("我处理订单评价"); } } } class Listener4: AbsListener { public override void Update(string orderId, OrderOperatorEnums.OrderOperator operatorType) { if (operatorType == OrderOperatorEnums.OrderOperator.订单评价) { Console.WriteLine("我也处理订单评价"); } } } class Listener5 : AbsListener { public override void Update(string orderId, OrderOperatorEnums.OrderOperator operatorType) { Console.WriteLine("我什么都能处理"); switch (operatorType) { case OrderOperatorEnums.OrderOperator.订单创建://code here break; case OrderOperatorEnums.OrderOperator.订单付款://code here break; case OrderOperatorEnums.OrderOperator.订单评价://code here break; default: break; } } } }
OrderOperatorEnums
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace OrderHelper { class OrderOperatorEnums { public enum OrderOperator { 订单创建, 订单付款, 订单评价 } } }
OrderSubject.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace OrderHelper { class OrderSubject { private List<AbsListener> _list = new List<AbsListener>(); public void AddListener(AbsListener listener) { _list.Add(listener); } public void RemoveListener(AbsListener listener) { _list.Remove(listener); } public void GetOrderChange(String orderId, OrderHelper.OrderOperatorEnums.OrderOperator type) { this.Notify(orderId, type); } private void Notify(String orderId, OrderHelper.OrderOperatorEnums.OrderOperator type) { foreach (var item in _list) { item.Update(orderId, type); } } } }
Program
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace OrderHelper { class Program { static void Main(string[] args) { OrderSubject subject = new OrderSubject(); subject.AddListener(new Listener1()); subject.AddListener(new Listener2()); subject.AddListener(new Listener3()); subject.AddListener(new Listener4()); subject.AddListener(new Listener5()); String orderId = "123"; OrderHelper.OrderOperatorEnums.OrderOperator type = OrderOperatorEnums.OrderOperator.订单创建; //OrderHelper.OrderOperatorEnums.OrderOperator type = OrderOperatorEnums.OrderOperator.订单付款; //OrderHelper.OrderOperatorEnums.OrderOperator type = OrderOperatorEnums.OrderOperator.订单评价; subject.GetOrderChange(orderId, type); Console.ReadKey(); } } }
楼主你看看是否满足需求。那些集成抽象类的子类实例化是写死的,楼主如果有需求可以搞个抽象工厂什么的,根据反射创建
观察者模式的推和拉综合运用,可以实现你的需求。