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

    評論

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

    暈了!

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

      回復  更多評論   

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


      回復  更多評論   

    導航

    統計

    常用鏈接

    留言簿(7)

    我參與的團隊

    隨筆分類

    隨筆檔案

    文章分類

    友情鏈接

    搜索

    積分與排名

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 羞羞网站在线免费观看| 成在人线av无码免费高潮水| 免费国产精品视频| 国产成人无码精品久久久免费| 久久国产精品亚洲一区二区| 在线看片免费不卡人成视频| 免费人成网站永久| 久久精品国产亚洲AV嫖农村妇女 | 日日麻批免费40分钟无码| 亚洲AV无码久久久久网站蜜桃| 亚洲日韩在线观看| 国产成人精品免费视频大| 自拍偷自拍亚洲精品偷一| 亚洲国产精品久久久天堂| 日韩激情无码免费毛片| 久久九九全国免费| 阿v免费在线观看| 精品亚洲国产成人| 久久国产亚洲精品麻豆| 日本人护士免费xxxx视频| 日韩免费高清大片在线| 免费很黄无遮挡的视频毛片| 亚洲国产日韩女人aaaaaa毛片在线 | 无码 免费 国产在线观看91| 亚洲免费视频网址| 亚洲人精品午夜射精日韩 | 亚洲国产高清精品线久久| 国产曰批免费视频播放免费s| 老湿机一区午夜精品免费福利| 91嫩草亚洲精品| 亚洲v高清理论电影| 亚洲午夜日韩高清一区| 四虎影院在线免费播放| 0588影视手机免费看片| 国产精品免费大片| 两个人看的www视频免费完整版| 性色av极品无码专区亚洲| 国产精品亚洲精品青青青| 亚洲精品视频在线播放| 亚洲国产成人片在线观看| 国产亚洲一区区二区在线|