<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

    主站蜘蛛池模板: 国产最新凸凹视频免费| 日韩国产免费一区二区三区| 在线看片无码永久免费aⅴ| 亚洲成A∨人片在线观看无码| 日韩精品内射视频免费观看 | 中字幕视频在线永久在线观看免费| 亚洲一区二区成人| 亚洲免费在线视频观看| 亚洲va久久久久| 日韩一品在线播放视频一品免费| 亚洲av无码有乱码在线观看| 五月天婷亚洲天综合网精品偷| 一区二区免费国产在线观看 | 亚洲第一区在线观看| v片免费在线观看| 亚洲精品夜夜夜妓女网| 在线美女免费观看网站h| 亚洲一区在线观看视频| 永久在线毛片免费观看| 乱爱性全过程免费视频| 夜夜春亚洲嫩草影院| 久久99国产乱子伦精品免费| 亚洲无码一区二区三区| 免费乱码中文字幕网站| 免费网站看av片| 亚洲乱码av中文一区二区| 久久精品国产精品亚洲艾草网美妙| 国产一级在线免费观看| 亚洲大香人伊一本线| 宅男666在线永久免费观看| 成在人线av无码免费高潮水| 亚洲精品中文字幕无乱码| 国产美女做a免费视频软件| 免费国产污网站在线观看| 亚洲av无码片在线观看| 亚洲福利精品电影在线观看| 99精品热线在线观看免费视频| 日韩国产欧美亚洲v片 | 日韩亚洲国产综合久久久| 久久精品中文字幕免费| 亚洲男人天堂2022|