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

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

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

    ?

    ??1 //歡迎您的點(diǎn)評(píng)
    ??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 ?*?子類必須創(chuàng)建兩個(gè)構(gòu)造函數(shù),一個(gè)為默認(rèn)構(gòu)造函數(shù),一個(gè)為override受保護(hù)構(gòu)造函數(shù)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 ? // 成員變量,在創(chuàng)建對(duì)象時(shí)賦值,以后不可以改變。
    ?27 ?
    ?28 ? // 同步根對(duì)象
    ?29 ? public ? final ?Object?SyncRoot? = ? new ?Object();
    ?30 ?
    ?31 ? // 事件監(jiān)聽(tīng)者列表
    ?32 ? private ? final ?ArrayList?listeners? = ? new ?ArrayList();
    ?33 ?
    ?34 ? // 事件方法緩存
    ?35 ? private ? final ?Hashtable?eventMethodCache? = ? new ?Hashtable();
    ?36 ?
    ?37 ? // 事件處理對(duì)象(接口)類型
    ?38 ? private ? final ?Class?handlerType;
    ?39 ?
    ?40 ? ////////////////////////////////////////////
    ?41 ? // 私有方法
    ?42 ?
    ?43 ? /**
    ?44 ??*?檢查事件處理對(duì)象的類型是否符合要求
    ?45 ??*? @param ?handler
    ?46 ??*? @return
    ?47 ?? */

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

    ?51 ?
    ?52 ? /**
    ?53 ??*?根據(jù)事件方法的名稱查找事件函數(shù)
    ?54 ??*?約束:事件函數(shù)不能夠重載(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 ? // 受保護(hù)方法
    ?67 ?
    ?68 ? /**
    ?69 ??*?受保護(hù)構(gòu)造函數(shù),創(chuàng)建處理接口方法緩存
    ?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)? {? // 捕捉所有的異常,統(tǒng)一通過(guò)onError方法處理。
    ?96 ????onError(eventMethodName?,?handler?,?e);
    ?97 ???}

    ?98 ??}

    ?99 ?}

    100 ?
    101 ? /**
    102 ??*?事件執(zhí)行過(guò)程出錯(cuò)的處理,?子類根據(jù)不同的異常類型進(jìn)行處理
    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 ? // 公共護(hù)方法
    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

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

    接著我們就編寫(xiě)一個(gè)類作為事件源(Observerable)
    /**
    ?*?活動(dòng)的事件
    ?*?
    @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});
    ????}

    }

    接著我們就編寫(xiě)一個(gè)類作為事件處理器:

    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,這樣就可以了,當(dāng)然我們還需要一些客戶端的代碼來(lái)將TestEventHandler的實(shí)例注冊(cè)到TestEvents的實(shí)例中監(jiān)聽(tīng)事件,然后我們就可以在TestEvents?類中需要的地方調(diào)用onEnter或者onExit,EventBase會(huì)自動(dòng)的調(diào)用監(jiān)聽(tīng)器的相應(yīng)方法。


    對(duì)Observer/Observable的優(yōu)點(diǎn):1.類型安全。2.可以有多個(gè)事件函數(shù)(在接口中任意定義)而不像Observer只有一個(gè)。

    缺點(diǎn):1.編寫(xiě)子類略現(xiàn)復(fù)雜。2.未做到線程安全。

    歡迎評(píng)論和建議,謝謝。

    Feedback

    # re: 一個(gè)事件的基類,目標(biāo)為改進(jìn)j2sdk中的Observer  回復(fù)  更多評(píng)論   

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


    “改進(jìn)j2sdk中的……”這種標(biāo)題還是少用為好,免得……

    # re: 一個(gè)事件的基類,目標(biāo)為改進(jìn)j2sdk中的Observer  回復(fù)  更多評(píng)論   

    2006-04-27 14:28 by iceboundrock
    謝謝您的指教,對(duì)于這三個(gè)方面,我是這么考慮的:
    1,j2sdk中的Observer/Observable難道就不類型安全?
    沒(méi)錯(cuò)啊,因?yàn)榻涌谠O(shè)計(jì)的太粗,所以無(wú)法保證回調(diào)時(shí)一定傳入監(jiān)聽(tīng)器需要的類型。
    2,多個(gè)事件函數(shù)的意義在于可以清晰的表明事件的含義,并且提高效率。監(jiān)聽(tīng)器不必自己處理所有的事件。
    3,TestEvents實(shí)現(xiàn)ITestEventHandler的確不夠優(yōu)雅,不過(guò)這是為了程序編寫(xiě)上的方便。另外因?yàn)門(mén)estEvents可以實(shí)現(xiàn)很多接口,所以把事件處理類型傳遞進(jìn)去,可以減少一部分工作。您覺(jué)得這塊需要如何改進(jìn)呢?
    這個(gè)類的目標(biāo)是改進(jìn)Observer,我也的確認(rèn)為對(duì)Observer做出了一些改善,所以我保留標(biāo)題。

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     

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

    Copyright © iceboundrock

    主站蜘蛛池模板: 国产亚洲精品无码专区| 国产精品免费综合一区视频| 亚洲国产成人一区二区精品区| 国产成人综合久久精品亚洲| 在线观看无码的免费网站| 亚洲AV无码国产精品色| 动漫黄网站免费永久在线观看| 亚洲日韩乱码久久久久久| 无码人妻一区二区三区免费手机 | 中文字幕版免费电影网站| 亚洲福利精品电影在线观看| 一级一级一级毛片免费毛片| 亚洲色偷偷狠狠综合网| 精品视频在线免费观看| 久久91亚洲精品中文字幕| 最近免费中文字幕大全高清大全1| 亚洲欧洲视频在线观看| 99热在线精品免费全部my| 国产成人精品久久亚洲高清不卡| 四虎影视永久免费观看地址| 国产精品免费久久| 亚洲天天做日日做天天看| 毛色毛片免费观看| 免费很黄无遮挡的视频毛片| 亚洲精品无码MV在线观看 | 91在线视频免费观看| 国产av无码专区亚洲av果冻传媒| 国产精品网站在线观看免费传媒| 亚洲AV福利天堂一区二区三| 日本一区二区三区免费高清| 一级做受视频免费是看美女| 久久亚洲AV无码精品色午夜麻豆| 女人18毛片水真多免费看 | 噜噜噜亚洲色成人网站∨| 波多野结衣在线免费视频| 边摸边脱吃奶边高潮视频免费| 亚洲电影中文字幕| 国产精品免费电影| 久久成人a毛片免费观看网站| 精品国产成人亚洲午夜福利| 亚洲欧洲精品成人久久曰影片|