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

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

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

    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 傻 瓜 閱讀(2387) 評論(2)  編輯  收藏 所屬分類: 雜項

    評論

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

    暈了!

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

      回復  更多評論   

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


      回復  更多評論   

    導航

    統計

    常用鏈接

    留言簿(7)

    我參與的團隊

    隨筆分類

    隨筆檔案

    文章分類

    友情鏈接

    搜索

    積分與排名

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 日韩欧毛片免费视频| 9久9久女女免费精品视频在线观看| 亚洲国产精品一区二区成人片国内 | 在线精品自拍亚洲第一区| 美女18毛片免费视频| 国产亚洲色婷婷久久99精品91| 成人性生交大片免费看好| 亚洲中文字幕在线无码一区二区| 国产精品四虎在线观看免费| 成在线人免费无码高潮喷水| 亚洲国产精品乱码在线观看97| 免费中文字幕在线观看| 热re99久久6国产精品免费| 国产亚洲综合成人91精品| 一级女性全黄久久生活片免费 | 亚洲色婷婷六月亚洲婷婷6月| 亚洲免费网站在线观看| 日韩毛片一区视频免费| 亚洲成人在线免费观看| 亚洲综合伊人久久大杳蕉| 一个人免费观看在线视频www| 成人国产精品免费视频| 亚洲乱理伦片在线观看中字 | 美女视频黄视大全视频免费的| 久久精品国产99精品国产亚洲性色| 女人张腿给男人桶视频免费版| 大地资源网高清在线观看免费| 亚洲人成电影网站色| 99人中文字幕亚洲区 | 精品国产日韩亚洲一区| 好爽…又高潮了免费毛片| 无码日韩精品一区二区免费暖暖| 欧美激情综合亚洲一二区| 亚洲美女视频免费| 亚洲区小说区激情区图片区| 国产中文字幕免费| 久久不见久久见中文字幕免费| 美女在线视频观看影院免费天天看| 免费国产污网站在线观看不要卡| 亚洲va久久久久| 亚洲精品在线播放视频|