<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    ?

    ??1 //歡迎您的點評
    ??2
    ??3 import ?java.lang.reflect.Method;
    ??4 import ?java.util.ArrayList;
    ??5 import ?java.util.Hashtable;
    ??6 import ?java.util.Iterator;
    ??7
    ??8 import ?org.apache.commons.logging.Log;
    ??9 import ?org.apache.commons.logging.LogFactory;
    ?10
    ?11 /**
    ?12 ?*?事件基類
    ?13 ?*? @author ?Richard?Lee
    ?14 ?*?子類必須創建兩個構造函數,一個為默認構造函數,一個為override受保護構造函數EventBase(Class?handlerType)
    ?15 ? */

    ?16 public ? abstract ? class ?EventBase? {
    ?17 ? ////////////////////////////////////////////
    ?18 ? // 類常量
    ?19 ?
    ?20 ? // ?StringBuffer初始大小
    ?21 ? private ? static ? final ? int ?StringBufferInitSize? = ? 256 ;
    ?22 ?
    ?23 ? private ? static ? final ?Log?log? = ?LogFactory.getLog(EventBase. class );
    ?24
    ?25 ? ////////////////////////////////////////////
    ?26 ? // 成員變量,在創建對象時賦值,以后不可以改變。
    ?27 ?
    ?28 ? // 同步根對象
    ?29 ? public ? final ?Object?SyncRoot? = ? new ?Object();
    ?30 ?
    ?31 ? // 事件監聽者列表
    ?32 ? private ? final ?ArrayList?listeners? = ? new ?ArrayList();
    ?33 ?
    ?34 ? // 事件方法緩存
    ?35 ? private ? final ?Hashtable?eventMethodCache? = ? new ?Hashtable();
    ?36 ?
    ?37 ? // 事件處理對象(接口)類型
    ?38 ? private ? final ?Class?handlerType;
    ?39 ?
    ?40 ? ////////////////////////////////////////////
    ?41 ? // 私有方法
    ?42 ?
    ?43 ? /**
    ?44 ??*?檢查事件處理對象的類型是否符合要求
    ?45 ??*? @param ?handler
    ?46 ??*? @return
    ?47 ?? */

    ?48 ? private ? boolean ?checkHandlerType(Object?handler) {
    ?49 ?? return ? this .handlerType.isInstance(handler);
    ?50 ?}

    ?51 ?
    ?52 ? /**
    ?53 ??*?根據事件方法的名稱查找事件函數
    ?54 ??*?約束:事件函數不能夠重載(overload)
    ?55 ??*? @param ?eventMethodName
    ?56 ??*? @return
    ?57 ?? */

    ?58 ? private ?Method?getEventMethodByName(String?eventMethodName) {
    ?59 ?? if (eventMethodCache.containsKey(eventMethodName)) {
    ?60 ??? return ?(Method)eventMethodCache.get(eventMethodName);
    ?61 ??}

    ?62 ?? throw ? new ?RuntimeException( " There?is?no?' " ? + ?eventMethodName? + ? " '?event. " );
    ?63 ?}

    ?64 ?
    ?65 ? ////////////////////////////////////////////
    ?66 ? // 受保護方法
    ?67 ?
    ?68 ? /**
    ?69 ??*?受保護構造函數,創建處理接口方法緩存
    ?70 ??*? @param ?handlerType
    ?71 ?? */

    ?72 ? protected ?EventBase(Class?handlerType) {
    ?73 ?? this .handlerType? = ?handlerType;
    ?74 ??Method?[]?ms? = ?handlerType.getMethods();
    ?75 ?? for ?( int ?i? = ? 0 ;?i? < ?ms.length;?i ++ )? {
    ?76 ???eventMethodCache.put(ms[i].getName()?,?ms[i]);
    ?77 ??}

    ?78 ?}

    ?79 ?
    ?80 ? /**
    ?81 ??*?拋出事件
    ?82 ??*? @param ?eventMethodName
    ?83 ??*? @param ?args
    ?84 ?? */

    ?85 ? protected ? void ?fireEvent(String?eventMethodName?,?Object?[]?args) {
    ?86 ??Iterator?it? = ? this .listeners.iterator();
    ?87 ?? while (it.hasNext()) {
    ?88 ???Object?handler? = ?it.next();
    ?89 ??? if ( null ? == ?handler)? {
    ?90 ???? continue ;
    ?91 ???}

    ?92 ??? try ? {
    ?93 ????Method?m? = ?getEventMethodByName(eventMethodName);
    ?94 ????m.invoke(handler?,?args);
    ?95 ???}
    ? catch ?(Throwable?e)? {? // 捕捉所有的異常,統一通過onError方法處理。
    ?96 ????onError(eventMethodName?,?handler?,?e);
    ?97 ???}

    ?98 ??}

    ?99 ?}

    100 ?
    101 ? /**
    102 ??*?事件執行過程出錯的處理,?子類根據不同的異常類型進行處理
    103 ??*? @param ?eventName
    104 ??*? @param ?eventHandler
    105 ??*? @param ?e
    106 ?? */

    107 ? protected ? void ?onError(String?eventName?,?Object?eventHandler,?Throwable?e) {
    108 ?? try {
    109 ??? if (log.isErrorEnabled()) {
    110 ????StringBuffer?msg? = ? new ?StringBuffer(StringBufferInitSize);
    111 ????msg.append( " Event?class:?\ "" ).append(this.getClass().getName());
    112 ????msg.append( " \ " ,?\ "" ).append(eventName).append( " \ " ?event?execute?failed.?Event?handler:?\ "" );
    113 ???? if ( null ? != ?eventHandler) {
    114 ?????msg.append(eventHandler.toString());
    115 ????}
    else {
    116 ?????msg.append( " null?reference " );
    117 ????}

    118 ????msg.append( ' " ' );
    119 ????log.error(msg?,?e);
    120 ???}

    121 ??}
    catch (Throwable?ex) {
    122 ???log.error( " onError?execute?failed. " ?,?ex);
    123 ??}

    124 ?}

    125 ?
    126 ? ////////////////////////////////////////////
    127 ? // 公共護方法
    128 ?
    129 ? public ? boolean ?addHandler(Object?handler) {
    130 ?? if (checkHandlerType(handler)) {
    131 ??? return ?listeners.add(handler);
    132 ??}

    133 ?? throw ? new ?IllegalArgumentException( " Handler?type?is?invalid,?addHandler?method?failed. " );
    134 ?}

    135 ?
    136 ? public ? boolean ?removeHandler(Object?handler) {
    137 ?? if (checkHandlerType(handler)) {
    138 ??? return ?listeners.remove(handler);
    139 ??}

    140 ?? throw ? new ?IllegalArgumentException( " Handler?type?is?invalid,?removeHandler?method?failed. " );
    141 ?}

    142 ?
    143 ? public ? void ?removeAllHandler() {
    144 ?? this .listeners.clear();
    145 ?}

    146 ?
    147 ? public ? boolean ?hasHandler() {
    148 ?? return ? ! listeners.isEmpty();
    149 ?}

    150 }

    151
    152

    使用范例:
    首先定義一個事件處理器的接口
    public?interface?ITestEventHandler?{
    ????
    void?onEnter(Object?sender,?Object?arg);
    ????
    void?onExit(Object?sender,?Object?arg);
    }

    接著我們就編寫一個類作為事件源(Observerable)
    /**
    ?*?活動的事件
    ?*?
    @author?Richard?Lee
    ?*?非線程安全,需要使用者自行手工同步
    ?
    */

    public?class?TestEvents?extends?EventBase?implements?ITestEventHandler?{
    ????
    public?TestEvents(){
    ????????
    this(ITestEventHandler.class);
    ????}


    ????
    protected?TestEvents(Class?handlerType)?{
    ????????
    super(handlerType);
    ????}


    ????
    public?void?onEnter(Object?sender,?Object?arg)?{
    ????????fireEvent(
    "onEnter"?,?new?Object[]{sender,?arg});
    ????}


    ????
    public?void?onExit(Object?sender,?Object?arg)?{
    ????????fireEvent(
    "onExit"?,?new?Object[]{sender,?arg});
    ????}

    }

    接著我們就編寫一個類作為事件處理器:

    public?class?TestEventHandler?implements?ITestEventHandler?{

    ????
    public?void?onEnter(Object?sender,?Object?arg)?{
    ????????System.out.println(
    "OnEnter,?sender:?"?+?sender?+?",?arg:?"?+?arg);
    ????}



    ????
    public?void?onExit(Object?sender,?Object?arg)?{
    ????????System.out.println(
    "onExit,?sender:?"?+?sender?+?",?arg:?"?+?arg);
    ????}

    }


    OK,這樣就可以了,當然我們還需要一些客戶端的代碼來將TestEventHandler的實例注冊到TestEvents的實例中監聽事件,然后我們就可以在TestEvents?類中需要的地方調用onEnter或者onExit,EventBase會自動的調用監聽器的相應方法。


    對Observer/Observable的優點:1.類型安全。2.可以有多個事件函數(在接口中任意定義)而不像Observer只有一個。

    缺點:1.編寫子類略現復雜。2.未做到線程安全。

    歡迎評論和建議,謝謝。

    Feedback

    # re: 一個事件的基類,目標為改進j2sdk中的Observer  回復  更多評論   

    2006-04-27 08:51 by 指教了
    1,j2sdk中的Observer/Observable難道就不類型安全?
    2,所謂“可以有多個事件函數”,沒有很大意義,一個和多個沒有本質區別;
    3,你把Observable(TestEvents)也變成一個類型Observer(ITestEventHandler),你認為這樣設計在類型層次上elegant?還有,如果真是這樣的設計,eventBase(Class handlerType)是不是有點可笑?(“自己不知道自己”?)


    “改進j2sdk中的……”這種標題還是少用為好,免得……

    # re: 一個事件的基類,目標為改進j2sdk中的Observer  回復  更多評論   

    2006-04-27 14:28 by iceboundrock
    謝謝您的指教,對于這三個方面,我是這么考慮的:
    1,j2sdk中的Observer/Observable難道就不類型安全?
    沒錯啊,因為接口設計的太粗,所以無法保證回調時一定傳入監聽器需要的類型。
    2,多個事件函數的意義在于可以清晰的表明事件的含義,并且提高效率。監聽器不必自己處理所有的事件。
    3,TestEvents實現ITestEventHandler的確不夠優雅,不過這是為了程序編寫上的方便。另外因為TestEvents可以實現很多接口,所以把事件處理類型傳遞進去,可以減少一部分工作。您覺得這塊需要如何改進呢?
    這個類的目標是改進Observer,我也的確認為對Observer做出了一些改善,所以我保留標題。

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     

    posts - 10, comments - 15, trackbacks - 0, articles - 0

    Copyright © iceboundrock

    主站蜘蛛池模板: 亚洲AV成人无码久久精品老人 | 性xxxxx大片免费视频| 国产成人一区二区三区免费视频| 亚洲冬月枫中文字幕在线看| 5555在线播放免费播放| 亚洲综合日韩中文字幕v在线| 久久伊人免费视频| 亚洲视频在线免费观看| 国产成人精品免费午夜app| 亚洲毛片一级带毛片基地| 4虎永免费最新永久免费地址| 亚洲依依成人精品| 全免费a级毛片免费看无码| 亚洲国产成人无码AV在线| 青青草国产免费久久久下载| 边摸边脱吃奶边高潮视频免费| 亚洲成人高清在线| a级在线观看免费| 亚洲黄色在线观看网站| 天天摸天天碰成人免费视频| 国产午夜亚洲精品不卡| 亚洲真人日本在线| 美女内射无套日韩免费播放 | 亚洲老妈激情一区二区三区| 免费人成黄页在线观看日本| 久久综合亚洲色一区二区三区| 亚洲三级高清免费| 在线观看亚洲专区| 亚洲中文字幕无码一久久区| 97视频免费观看2区| 亚洲精品成a人在线观看☆| 亚洲AV无码不卡在线观看下载| 久久99久久成人免费播放| 久久久亚洲欧洲日产国码二区| 男女污污污超污视频免费在线看| 亚洲精品偷拍视频免费观看| 亚洲av日韩av无码| 国产人成免费视频网站| 处破女第一次亚洲18分钟| 国产亚洲A∨片在线观看| 无人影院手机版在线观看免费|