java隨記

          堅持就是勝利!

           

          訪問者模式實戰:構建通用的數據庫插入操作


          在做一些簡單的JDBC的API應用時,就老想只用一個方法向數據庫不同的表做插入操作,省得
          用一大堆的insert語句。訪問者模式可以實現對未知的類進行操作,于是就用了這個簡化了的模
          式的實現方案。請高手指正。 在使用訪問者模式之前先敘述一點概念性的東西。
          靜態類型的概念:變量被申明時的類型。實際類型:變量的實際類型。
          比如 Object object=new String(); object靜態類型是Object,實際類型是String.
          觀察者模式是一個比較難理解的模式,在理解觀察者模式之前當然應該先理解雙重分派的概念。
          java語言支持靜態的多分派跟動態的單分派。java通重載支持靜態的多分派。書上的例子:
          public class Mozi {
          ???
          ??? public void ride(Horse h){
          ??????? System.out.println("ridding a horse");
          ??? }
          ??? public void ride(WhiteHorse w){
          ??????? System.out.println("ridding a white horse");
          ??? }
          ??? public void ride(BlackHorse b){
          ??????? System.out.println("rdding a black horse");
          ??? }

          ??? public static void main(String[] args){
          ????? Mozi mozi=new Mozi();
          ????? Horse w=new WhiteHorse();
          ????? Horse b=new BlackHorse();
          ????? mozi.ride(w);
          ????? mozi.ride(b);
          ??? }
          }?
          程序打印輸出:
          ridding a horse
          ridding a horse
          原因就是對兩次ride方法的調用傳入的參量不同,但是它們的靜態類型是一樣的,都是 Horse;
          這個過程在編譯時期就完成了。
          java通過方法置換支持動態分派。比如 String s1="ab"; Object o=s1+"c"; String s="abc";
          o.equals(s) 打印true? o.equals()方法執行的是String類的equals()方法.java調用對象的
          真實類型的方法,這就是動態分派。
          雙重分派:
          public abstract class Vistor{

          protected void processStrig(Object e){
          ?if(e instanceof String){
          ???? String tmp=(String) e;
          ???? String need="'"+e+"'";
          ???? System.out.println(nedd);
          ?? }else if(e instanceof Integer){
          ?????? String need=e.toString();
          ?????? System.out.println(need);
          ??? }else if(e instanceof Date){
          ???????????? Date tmp=(Date) e;
          ???????????? String need="'"+tmp.toString()+"'";
          ??????? }
          ????? ....
          ??? }

          }

          public class ConcreteVisitor extends Visitor{

          protected void processString(Object e){
          ???? super.processString(e);
          ?? }??
          }
          方法的調用Visitor v=new ConcreteVisitor(); v.processString(new String("tt"));
          v.processString()方法在調用的時候會檢察v的真實類型,調用真實類型的方法,這個時候就
          發生了一動態的單分派過程.當子類調用超類的方法的時候明顯的根據instanceof判斷的真實類
          型去執行不同的方法,又發生了一次動態分派的過程.這個就是雙重分派的實現。這種方法實現的
          程序比較冗長和容易出錯.
          “返傳球”方案:
          public abstract class Vistor{

          ?? public abstract String processStrig(Object e);

          }

          public class ConcreteVisitor extends Visitor{

          ? public String processString(WrapperString e){
          ??? String tmp= t.toString();
          ??? System.out.println(tmp);
          ?? }??

          ? public String processInteger(WrapperInteger e){
          ??? String tmp=e.toString();
          ??? System.out.println(tmp);

          ?? }

          }

          public class abstract Wrapper{
          ? public abstract String processString(Vistor v);
          }

          public class WrapperString extends Wrapper{

          ? public String processString(Vistor v){
          ??? v.processString(this);
          ?? }
          ? public String toString(){
          ?? ...
          ?? }
          }

          public class WrapperInteger extends Wrapper{
          ??? public String processInteger(Visitor v){
          ???? v.processString(this);
          ??? }
          ??? public String toString(){
          ???? ...
          ??? }
          ?}
          方法的調用:
          Visitor v = new ConcreteVisitor();
          Wrapper wrapper= new WrapperString();
          wrapper.processString(v);
          當wrapper.processString()方法執行的時候會檢察wrapper的真實類型,這個就產生了一次
          動態單分派,processString()里面的語句v.processString()在執行的時候也會檢察v的真
          實類型,動態雙重分派就發生了。
          訪問者模式的核心就是“返傳球“方案的雙重分派。其示意性類圖:(注:虛線箭頭劃錯了)



          visitor.jpg

          在一個方法內實現向不同的表插入不同數據的具體實現方案(簡化了的):因為整個方案里只需
          要一個訪問者對象,因此使用簡化了的訪問者模式。因為java基本類型及對應的類是不變模式的
          實現:因此包裝一下這些基本類型和類并實現訪問者模式需要的方法。
          public abstract class Wrapper {
          ??? public Wrapper() {
          ??? }
          ??? public abstract String action(Visitor visitor);

          }

          包裝Date類:
          import java.util.Date;
          public class WrapperDate extends Wrapper {
          ??? private Date date;
          ??? public WrapperDate(Date date) {
          ??????? this.date=date;
          ??? }
          ??? public String action(Visitor visitor){
          ???????? return( visitor.visit(this));
          ??? }

          ??? public String toString(){
          ??????? if (date==null){
          ??????????? return "null";
          ??????? }
          ??????? return "'"+date.toString()+"'";
          ??? }

          }


          包裝Integer類:
          public class WrapperInteger extends Wrapper {
          ??? private Integer value;

          ??? public WrapperInteger(Integer value) {
          ??????? this.value=value;

          ??? }
          ??? public WrapperInteger(int value){

          ??????? this.value=new Integer(value);
          ??? }
          ??? public WrapperInteger(String value){

          ????? this.value=new Integer(value);
          ??? }

          ??? public String action(Visitor visitor){
          ?????? return( visitor.visit(this));
          ??? }
          ??? public String toString(){
          ??????? if(value==null){
          ??????????? return "null";
          ??????? }
          ??????? return value.toString();
          ??? }
          }

          包裝String類:
          public class WrapperString extends Wrapper {
          ??? private String wrapper;
          ??? public WrapperString( String wrapper) {

          ??????? this.wrapper = wrapper;
          ??? }

          ??? public WrapperString( char[] wrap) {
          ??????? wrapper = new String(wrap);
          ??? }

          ??? public String action(Visitor visitor) {
          ??????? return (visitor.vistit(this));
          ??? }

          ??? public String toString() {
          ??????? if(wrapper==null){
          ??????????? return "null";
          ??????? }
          ??????? return "'" + wrapper + "'";
          ??? }


          }

          具體訪問者的實現:
          public class Visitor {
          ??? public Visitor() {
          ??? }


          ??? public String vistit(WrapperString wrap){
          ?????? return wrap.toString();
          ??? }
          ??? public String visit(WrapperInteger value){
          ??????? return value.toString();
          ??? }
          ??? public String visit(WrapperDate date){
          ??????? return date.toString();
          ??? }
          }

          具體應用類的實現:

          import java.util.*;

          public class Test {


          ??? private Visitor visitor = new Visitor();

          ??? public Test() {
          ??? }

          ??? public Visitor getVisitor() {
          ??????? return visitor;
          ??? }

          ??


          ??? public int insertData(String tablename, List columNameCollection,
          ????????????????????????? List values) {

          ??????? StringBuffer query = new StringBuffer("insert into " + tablename + " (");

          ??????? int count = 0;

          ??????? for (Iterator it = columNameCollection.iterator(); it.hasNext(); ) {
          ??????????? String columName = (String) it.next();
          ??????????? query.append(columName);
          ??????????? query.append(",");
          ??????? }
          ??????? query.deleteCharAt(query.length() - 1);
          ??????? query.append(") values(");
          ??????? for (Iterator it = values.iterator(); it.hasNext(); ) {
          ??????????? Wrapper wrapper = (Wrapper) it.next();
          ??????????? String tmp = wrapper.action(getVisitor());
          ??????????? query.append(tmp);
          ??????????? query.append(",");
          ??????? }
          ??????? query.deleteCharAt(query.length() - 1);
          ??????? query.append(")");

          ??????? System.out.println(query.toString());
          ??????? return count;
          ??? }


          ??? public static void main(String[] args) {
          ??????? Test test = new Test();
          ??????? String tableName = "cutomer";
          ??????? List columNameCollection = new ArrayList();
          ??????? String columName = "name";
          ??????? String columAge = "age";
          ??????? String columFunctionTime="fuctiontime";
          ??????? columNameCollection.add(columName);
          ??????? columNameCollection.add(columAge);
          ??????? columNameCollection.add(columFunctionTime);
          ??????? List values = new ArrayList();
          ??????? String name=null;
          ??????? Wrapper wrapper1 = new WrapperString(name);
          ??????? Wrapper wrapper2 = new WrapperInteger(1);
          ??????? Wrapper wrapper3= new WrapperDate(new java.util.Date());
          ??????? values.add(wrapper1);
          ??????? values.add(wrapper2);
          ??????? values.add(wrapper3);
          ??????? test.insertData(tableName,columNameCollection,values);
          ???????


          ??? }
          }

          程序打印結果:

          insert into cutomer (name,age,fuctiontime) values(null,1,'Sat Aug 12 13:46:58 CST 2006')

          這個輸出是滿足MSSQL執行插入的語法要求的.雖然這樣就實現了想要的結果,
          但是insertData(String tablename, List columNameCollection, List values) 方法在每次調
          用的時候需要輸入表名跟該表的列的集合,還是很麻煩,不盡人意,而且不同的數
          據庫的表名是不一樣的,因此最好用配置文件來解決這一個問題.

          歡迎加入QQ群:30406099?

          ?


          ?

          posted on 2006-08-14 14:39 傻 瓜 閱讀(2381) 評論(2)  編輯  收藏 所屬分類: 雜項

          評論

          # re: 訪問者模式實戰:構建通用的數據庫插入操作 2006-08-14 15:08 伯伯

          暈了!

          還是下面這個夠清楚
          Proxy Visitor Pattern
          http://www.hibernate.org/280.html

            回復  更多評論   

          # re: 訪問者模式實戰:構建通用的數據庫插入操作 2006-10-08 12:29 我的


            回復  更多評論   

          導航

          統計

          常用鏈接

          留言簿(7)

          我參與的團隊

          隨筆分類

          隨筆檔案

          文章分類

          友情鏈接

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 滦南县| 酒泉市| 铜鼓县| 安乡县| 保亭| 绥滨县| 巴塘县| 安康市| 尼玛县| 桑日县| 镇平县| 沙河市| 大荔县| 金湖县| 神池县| 儋州市| 曲周县| 兴山县| 西盟| 六安市| 江永县| 灌南县| 台江县| 方山县| 开封县| 广安市| 朝阳区| 南汇区| 巍山| 丰镇市| 洞头县| 郓城县| 雷州市| 神农架林区| 双辽市| 屏东市| 大荔县| 湘阴县| 十堰市| 翁牛特旗| 嘉黎县|