首页新闻找找看学习计划

方法级别的事件订阅

0
悬赏园豆:50 [已解决问题] 解决于 2014-10-21 10:16

大家好,现在有这么一个需求,请教一下有没有好的实现办法。

需求描述:

  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等方法。

描述的可能不太清楚,大家都是高手应该可能看懂我的意思,有问题请留言。

 

谢谢大家了。

carl~的主页 carl~ | 初学一级 | 园豆:84
提问于:2013-09-16 15:58
< >
分享
最佳答案
0
收获园豆:25
Launcher | 高人七级 |园豆:45040 | 2013-09-16 17:56
其他回答(3)
0

Class A中的 订单创建、订单付款、订单评价。。。等。这些行为是固定的?还是这些动作也是动态的。如果是固定的,用枚举,字符串数组等就行了,如果是动态的,是不是还要封装一下。或者楼主介绍一下最原始的需求,抛开代码实现来谈。另外:ClassAListener楼主你写了两个方法,并不是所有的订阅者都有这两个方法吧,为什么不是每个订阅者专门做一件事情,而是一个订阅者做两件事情。

收获园豆:25
会长 | 园豆:6046 (大侠五级) | 2013-09-16 16:19

Class A中的 订单创建、订单付款、订单评价。。。等。这些行为是固定的?

是固定的。如果用枚举、字符串数组,其它类应该如何订阅,该如何实现?

原始的需求,有些复杂,简单来说就是:

第三方的网站会通知我有订单创建、订单付款或其它的事件了,我这边需要对这一事件进行处理,同一个事件可能会在多个地方处理。

支持(0) 反对(0) carl~ | 园豆:84 (初学一级) | 2013-09-16 16:40

@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);
    }
}
View Code

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;
            }
        }
    }
}
View Code

OrderOperatorEnums

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

namespace OrderHelper
{
    class OrderOperatorEnums
    {
        public enum OrderOperator
        {
            订单创建,
            订单付款,
            订单评价
        }
    }
}
View Code

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);
            }
        }
    }
}
View Code

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();
        }
    }
}
View Code

 

支持(0) 反对(0) 会长 | 园豆:6046 (大侠五级) | 2013-09-16 17:35

支持(0) 反对(0) 会长 | 园豆:6046 (大侠五级) | 2013-09-16 17:38

楼主你看看是否满足需求。那些集成抽象类的子类实例化是写死的,楼主如果有需求可以搞个抽象工厂什么的,根据反射创建

支持(0) 反对(0) 会长 | 园豆:6046 (大侠五级) | 2013-09-16 17:39
0

这个可以参考一下观察者模式

sinhbv | 园豆:2579 (老鸟四级) | 2013-09-16 17:16
0

观察者模式的推和拉综合运用,可以实现你的需求。

水晶途途 | 园豆:1434 (小虾三级) | 2013-09-25 11:11
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册