隨筆-8  評論-2  文章-24  trackbacks-0


          ??? 最近在成都寫一個(gè)移動(dòng)增值項(xiàng)目,筆者負(fù)責(zé)后臺server端。功能很簡單,手機(jī)用戶通過GPRS打開Socket與服務(wù)器連接,筆者則根據(jù)用戶傳過來的數(shù)據(jù)做出響應(yīng)。做過類似項(xiàng)目的兄弟一定都知道,首先需要定義一個(gè)類似于MSNP的通訊協(xié)議,不過今天的話題是如何把這個(gè)系統(tǒng)設(shè)計(jì)得具有高度的擴(kuò)展性。由于這個(gè)項(xiàng)目本身沒有進(jìn)行過較為完善的客戶溝通和需求分析,所以以后肯定會(huì)有很多功能上的擴(kuò)展,通訊協(xié)議肯定會(huì)越來越龐大,而筆者作為一個(gè)不那么勤快的人,當(dāng)然不想以后再去修改寫好的程序,所以這個(gè)項(xiàng)目是實(shí)踐面向?qū)ο笤O(shè)計(jì)的好機(jī)會(huì)。
          首先定義一個(gè)接口來隔離類:
          package org.bromon.reflect;
          public interface Operator
          {
          public java.util.List act(java.util.List params)
          }
          根據(jù)設(shè)計(jì)模式的原理,我們可以為不同的功能編寫不同的類,每個(gè)類都繼承Operator接口,客戶端只需要針對Operator接口編程就可以避免很多麻煩。比如這個(gè)類:
          package org.bromon.reflect.*;
          public class Success implements Operator
          {
          public java.util.List act(java.util.List params)
          {
          List result=new ArrayList();
          result.add(new String(“操作成功”));
          return result;
          }
          }
          我們還可以寫其他很多類,但是有個(gè)問題,接口是無法實(shí)例化的,我們必須手動(dòng)控制具體實(shí)例化哪個(gè)類,這很不爽,如果能夠向應(yīng)用程序傳遞一個(gè)參數(shù),讓自己去選擇實(shí)例化一個(gè)類,執(zhí)行它的act方法,那我們的工作就輕松多了。
          很幸運(yùn),我使用的是Java,只有Java才提供這樣的反射機(jī)制,或者說內(nèi)省機(jī)制,可以實(shí)現(xiàn)我們的無理要求。編寫一個(gè)配置文件emp.properties:
          #成功響應(yīng)
          1000=Success
          #向客戶發(fā)送普通文本消息
          2000=Load
          #客戶向服務(wù)器發(fā)送普通文本消息
          3000=Store
          文件中的鍵名是客戶將發(fā)給我的消息頭,客戶發(fā)送1000給我,那么我就執(zhí)行Success類的act方法,類似的如果發(fā)送2000給我,那就執(zhí)行Load類的act方法,這樣一來系統(tǒng)就完全符合開閉原則了,如果要添加新的功能,完全不需要修改已有代碼,只需要在配置文件中添加對應(yīng)規(guī)則,然后編寫新的類,實(shí)現(xiàn)act方法就ok,即使我棄這個(gè)項(xiàng)目而去,它將來也可以很好的擴(kuò)展。這樣的系統(tǒng)具備了非常良好的擴(kuò)展性和可插入性。
          下面這個(gè)例子體現(xiàn)了動(dòng)態(tài)加載的功能,程序在執(zhí)行過程中才知道應(yīng)該實(shí)例化哪個(gè)類:
          package org.bromon.reflect.*;
          import java.lang.reflect.*;
          public class TestReflect
          {
          //加載配置文件,查詢消息頭對應(yīng)的類名
          private String loadProtocal(String header)
          {
          String result=null;
          try
          {
          Properties prop=new Properties();
          FileInputStream fis=new FileInputStream("emp.properties");
          prop.load(fis);
          result=prop.getProperty(header);
          fis.close();
          }catch(Exception e)
          {
          System.out.println(e);
          }
          return result;
          }
          //針對消息作出響應(yīng),利用反射導(dǎo)入對應(yīng)的類
          public String response(String header,String content)
          {
          String result=null;
          String s=null;
          try
          {
          /*
          * 導(dǎo)入屬性文件emp.properties,查詢header所對應(yīng)的類的名字
          * 通過反射機(jī)制動(dòng)態(tài)加載匹配的類,所有的類都被Operator接口隔離
          * 可以通過修改屬性文件、添加新的類(繼承MsgOperator接口)來擴(kuò)展協(xié)議
          */
          s="org.bromon.reflect."+this.loadProtocal(header);
          //加載類
          Class c=Class.forName(s);
          //創(chuàng)建類的事例
          Operator mo=(Operator)c.newInstance();
          //構(gòu)造參數(shù)列表
          Class params[]=new Class[1];
          params[0]=Class.forName("java.util.List");
          //查詢act方法
          Method m=c.getMethod("act",params);
          Object args[]=new Object[1];
          args[0]=content;
          //調(diào)用方法并且獲得返回
          Object returnObject=m.invoke(mo,args);
          }catch(Exception e)
          {
          System.out.println("Handler-response:"+e);
          }
          return result;
          }
          public static void main(String args[])
          {
          TestReflect tr=new TestReflect();
          tr.response(args[0],”消息內(nèi)容”);
          }
          }
          測試一下:java TestReflect 1000
          這個(gè)程序是針對Operator編程的,所以無需做任何修改,直接提供Load和Store類,就可以支持2000、3000做參數(shù)的調(diào)用。
          有了這樣的內(nèi)省機(jī)制,可以把接口的作用發(fā)揮到極至,設(shè)計(jì)模式也更能體現(xiàn)出威力,而不僅僅供我們飯后閑聊。

          posted on 2006-10-11 09:19 MyBox 閱讀(185) 評論(0)  編輯  收藏

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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 钦州市| 湘西| 濉溪县| 德格县| 施甸县| 庆元县| 合江县| 遂川县| 翁源县| 宾川县| 治多县| 小金县| 城口县| 桐柏县| 澄迈县| 夹江县| 汝城县| 句容市| 四平市| 琼结县| 泰和县| 任丘市| 临湘市| 大洼县| 泸水县| 南宫市| 从江县| 密山市| 凤冈县| 寻甸| 武平县| 都匀市| 宁武县| 开化县| 雷州市| 昆明市| 黄陵县| 阿坝| 板桥市| 高雄县| 隆林|