扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
本人一直认为AS3的事件处理机制很是给力 , 今天鼓捣了出来并完美得通过了测试。在AS3中使用函数addEventListener添加事件侦听,用removeEventListener移除事件侦听。着用封装的一个类库可以彻底地终结消息传递中无规则,无规律的混乱状态,从而达到代码逻辑清晰性。改起来也相当简单(做过程序员的都懂)。
成都创新互联公司专注于泊头企业网站建设,成都响应式网站建设公司,成都做商城网站。泊头网站建设公司,为泊头等地区提供建站服务。全流程按需网站建设,专业设计,全程项目跟踪,成都创新互联公司专业和态度为您提供的服务关于此类库的实现原理 , 其实使用的是委托(delegate),让侦听函数(观察者)挂载到此委托上,当然消息有不同的类型,如windows系统中有单击,双击,右击等不同的事件类型,在这个类库里面都有实现。
首先,需要指出:
IEventType ( 所有事件类型的接口 )
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MsgEventLib.com { public interface IEventType { ////// 类的类型 /// Type EventMainType { get; } String GetEventTypeName(string type); } }
思想:事件类型以 类的Type.Name + "_" + 事件名称 。 以GetEventTypeName方法实现。
传递的消息体:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MsgEventLib.com { public class BaseEvent { public BaseEvent(string eventType, object sender, object msg) { this.eventType = eventType; this.sender = sender; this.msg = msg; } private string @eventType; public string EventType { set { this.eventType = value; } get { return this.eventType; } } private object @sender; public Object Sender { set { this.sender = value; } get { return this.sender; } } private object @msg; public object Msg { set { this.msg = value; } get { return this.msg; } } } }
其中:eventType为事件类型名称 GetEventTypeName , Sender为发送者 , Msg为消息体
事件侦听管理器的实现
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MsgEventLib.com { public sealed class EventListener : IEventListener { private static IEventListener @instance; public static IEventListener Instance { get { if (instance == null) instance = new EventListener(); return instance; } } private Dictionary@listeners; private EventListener() { @listeners = new Dictionary (); } public void AddEventListener(string type, DeListener myListener) { if (!@listeners.ContainsKey(type)) @listeners.Add(type, myListener); else @listeners[type] += myListener; } public void RemoveEventListener(string type, DeListener myListener) { if (@listeners.ContainsKey(type)) { @listeners[type] -= myListener; if (@listeners[type] == null) @listeners.Remove(type); } } public void RemoveAllEventListener() { if (@listeners != null && @listeners.Count > 0) { List keys = new List (@listeners.Keys);//获得所有的键值 for (int j = 0; j < keys.Count; j++) { if (@listeners[keys[j]] != null) { Delegate[] des = @listeners[keys[j]].GetInvocationList(); if (des != null && des.Length > 0) { for (int i = 0; i < des.Length; i++) { @listeners[keys[j]] -= des[i] as DeListener; } } } @listeners.Remove(keys[j]); } } } public DeListener GetDeListenerByType(string type) { if (@listeners != null && @listeners.ContainsKey(type)) { return @listeners[type]; } return null; } public void Destory() { this.RemoveAllEventListener(); if (@instance != null) @instance = null; } } }
值得注意的是 , 字典 : key为事件类型(GetEventTypeName) , value为委托(可能有多个挂载/观察者)
关于事件发送者(主题)
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MsgEventLib.com { public sealed class EventDispacterManager : IEventDispacterManager { private static IEventDispacterManager @instance; public static IEventDispacterManager Instance { get { if (instance == null) instance = new EventDispacterManager(); return instance; } } public void Dispatch(string type , BaseEvent @myevent) { DeListener target = EventListener.Instance.GetDeListenerByType(type); if (target != null) { target(@myevent); } } } }
测试的结果
1 , 事件类型
using System; using System.Collections.Generic; using System.Linq; using System.Text; using MsgEventLib.com; namespace TestA.com { public class MyEventType : IEventType { private static MyEventType @instance; public static MyEventType Instance { get { if (@instance == null) @instance = new MyEventType(); return @instance; } } public Type EventMainType { get { return typeof(MyEventType); } } public string GetEventTypeName(string type) { return this.EventMainType.Name + "_" + type; } public static string CLOSE_WINDOWS = "CLOSE_WINDOWS"; public static string OTHRT_TYPE = "OTHRT_TYPE"; } }
2 , 3个类(侦听着)
①:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using MsgEventLib.com; namespace TestA.com { public sealed class Listeners { public Listeners() { string type = MyEventType.Instance.GetEventTypeName(MyEventType.CLOSE_WINDOWS); EventListener.Instance.AddEventListener(type, this.Li); } private void Li(BaseEvent e) { Console.WriteLine("Listeners 触发了Event {0} ", e.Msg); } } }
②:
using MsgEventLib.com; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace TestA.com { public sealed class Lis2 { public Lis2() { string type = MyEventType.Instance.GetEventTypeName(MyEventType.CLOSE_WINDOWS); EventListener.Instance.AddEventListener(type, this.Li); } private void Li(BaseEvent e) { Console.WriteLine("Lis2 触发了Event {0} ", e.Msg); } public void RemoveLis() { string type = MyEventType.Instance.GetEventTypeName(MyEventType.CLOSE_WINDOWS); EventListener.Instance.RemoveEventListener(type, this.Li); Console.WriteLine("Lis2 移除了事件侦听!"); } } }
③:
using MsgEventLib.com; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace TestA.com { public sealed class Lis3 { public Lis3() { string type = MyEventType.Instance.GetEventTypeName(MyEventType.OTHRT_TYPE); EventListener.Instance.AddEventListener(type, this.Li); } private void Li(BaseEvent e) { Console.WriteLine("Lis3 触发了Event {0} ", e.Msg); } } }
事件发送者
using System; using System.Collections.Generic; using System.Linq; using System.Text; using MsgEventLib.com; namespace TestA.com { public sealed class Dispatch { public void Dis() { string type = MyEventType.Instance.GetEventTypeName(MyEventType.CLOSE_WINDOWS); EventDispacterManager.Instance.Dispatch(type, new BaseEvent(type, this, "Event_关闭你的窗口")); } } }
测试:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TestA.com;
namespace TestA
{
public class Program
{
static void Main(string[] args)
{
Dispatch di = new Dispatch();
Listeners li = new Listeners();
Lis2 li2 = new Lis2();
Lis3 li3 = new Lis3();
di.Dis();
li2.RemoveLis();
di.Dis();
Console.Read();
}
}
}
结果:
因为Lis3侦听的不是事件CLOSE_WINDOWS , 既不会触发 。 因为Lis2移除了事件,所以第二次不会触发。
这只是部分大码。详细请见附件。
附件:http://down.51cto.com/data/2366478另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流