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


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

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

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


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 正镶白旗| 日照市| 玛纳斯县| 白山市| 巴里| 五华县| 玛沁县| 建昌县| 南丰县| 石首市| 北流市| 江北区| 屏边| 沧州市| 南投市| 渭南市| 锦屏县| 湘阴县| 治县。| 汶上县| 夏邑县| 芮城县| 丘北县| 明溪县| 天峻县| 分宜县| 榆社县| 普宁市| 江阴市| 晋宁县| 海林市| 安龙县| 达尔| 上杭县| 垫江县| 靖远县| 乌海市| 延津县| 平和县| 巩义市| 金乡县|