<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视频免费观看| 免费无码毛片一区二区APP| 最新亚洲成av人免费看| 日本xxxx色视频在线观看免费| 亚洲人成77777在线观看网| 免费a级毛片永久免费| 十八禁视频在线观看免费无码无遮挡骂过| 亚洲一区影音先锋色资源| 国产真实伦在线视频免费观看| 国产在线观a免费观看| 亚洲人成伊人成综合网久久| 免费人成网站在线高清| 亚洲免费在线视频观看| 日本精品久久久久久久久免费| 久久亚洲精品人成综合网| 午夜国产羞羞视频免费网站| 99在线观看精品免费99| 一级视频免费观看| 亚洲综合av一区二区三区不卡 | 亚洲国产精品日韩在线| 国产一级一片免费播放i| 四虎影视成人永久免费观看视频| 亚洲熟妇无码av另类vr影视| 亚洲AV永久无码精品一百度影院| 永久黄网站色视频免费| 91久久精品国产免费一区| 一区二区三区精品高清视频免费在线播放 | eeuss在线兵区免费观看| 亚洲成人一级电影| 亚洲中文字幕无码永久在线| 国产国产人免费人成免费视频| 5g影院5g天天爽永久免费影院| 一级毛片在线免费播放| 亚洲一区二区无码偷拍| 亚洲国产日韩在线成人蜜芽| 亚洲乱码国产一区三区| 免费在线观看你懂的| 好男人看视频免费2019中文| 精品熟女少妇av免费久久| 成人毛片100免费观看| 羞羞视频在线观看免费|