java隨記

          堅(jiān)持就是勝利!

           

          訪問者模式實(shí)戰(zhàn):構(gòu)建通用的數(shù)據(jù)庫(kù)插入操作


          在做一些簡(jiǎn)單的JDBC的API應(yīng)用時(shí),就老想只用一個(gè)方法向數(shù)據(jù)庫(kù)不同的表做插入操作,省得
          用一大堆的insert語(yǔ)句。訪問者模式可以實(shí)現(xiàn)對(duì)未知的類進(jìn)行操作,于是就用了這個(gè)簡(jiǎn)化了的模
          式的實(shí)現(xiàn)方案。請(qǐng)高手指正。 在使用訪問者模式之前先敘述一點(diǎn)概念性的東西。
          靜態(tài)類型的概念:變量被申明時(shí)的類型。實(shí)際類型:變量的實(shí)際類型。
          比如 Object object=new String(); object靜態(tài)類型是Object,實(shí)際類型是String.
          觀察者模式是一個(gè)比較難理解的模式,在理解觀察者模式之前當(dāng)然應(yīng)該先理解雙重分派的概念。
          java語(yǔ)言支持靜態(tài)的多分派跟動(dòng)態(tài)的單分派。java通重載支持靜態(tài)的多分派。書上的例子:
          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
          原因就是對(duì)兩次ride方法的調(diào)用傳入的參量不同,但是它們的靜態(tài)類型是一樣的,都是 Horse;
          這個(gè)過程在編譯時(shí)期就完成了。
          java通過方法置換支持動(dòng)態(tài)分派。比如 String s1="ab"; Object o=s1+"c"; String s="abc";
          o.equals(s) 打印true? o.equals()方法執(zhí)行的是String類的equals()方法.java調(diào)用對(duì)象的
          真實(shí)類型的方法,這就是動(dòng)態(tài)分派。
          雙重分派:
          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);
          ?? }??
          }
          方法的調(diào)用Visitor v=new ConcreteVisitor(); v.processString(new String("tt"));
          v.processString()方法在調(diào)用的時(shí)候會(huì)檢察v的真實(shí)類型,調(diào)用真實(shí)類型的方法,這個(gè)時(shí)候就
          發(fā)生了一動(dòng)態(tài)的單分派過程.當(dāng)子類調(diào)用超類的方法的時(shí)候明顯的根據(jù)instanceof判斷的真實(shí)類
          型去執(zhí)行不同的方法,又發(fā)生了一次動(dòng)態(tài)分派的過程.這個(gè)就是雙重分派的實(shí)現(xiàn)。這種方法實(shí)現(xiàn)的
          程序比較冗長(zhǎng)和容易出錯(cuò).
          “返傳球”方案:
          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(){
          ???? ...
          ??? }
          ?}
          方法的調(diào)用:
          Visitor v = new ConcreteVisitor();
          Wrapper wrapper= new WrapperString();
          wrapper.processString(v);
          當(dāng)wrapper.processString()方法執(zhí)行的時(shí)候會(huì)檢察wrapper的真實(shí)類型,這個(gè)就產(chǎn)生了一次
          動(dòng)態(tài)單分派,processString()里面的語(yǔ)句v.processString()在執(zhí)行的時(shí)候也會(huì)檢察v的真
          實(shí)類型,動(dòng)態(tài)雙重分派就發(fā)生了。
          訪問者模式的核心就是“返傳球“方案的雙重分派。其示意性類圖:(注:虛線箭頭劃錯(cuò)了)



          visitor.jpg

          在一個(gè)方法內(nèi)實(shí)現(xiàn)向不同的表插入不同數(shù)據(jù)的具體實(shí)現(xiàn)方案(簡(jiǎn)化了的):因?yàn)檎麄€(gè)方案里只需
          要一個(gè)訪問者對(duì)象,因此使用簡(jiǎn)化了的訪問者模式。因?yàn)閖ava基本類型及對(duì)應(yīng)的類是不變模式的
          實(shí)現(xiàn):因此包裝一下這些基本類型和類并實(shí)現(xiàn)訪問者模式需要的方法。
          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 + "'";
          ??? }


          }

          具體訪問者的實(shí)現(xiàn):
          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();
          ??? }
          }

          具體應(yīng)用類的實(shí)現(xiàn):

          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);
          ???????


          ??? }
          }

          程序打印結(jié)果:

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

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

          歡迎加入QQ群:30406099?

          ?


          ?

          posted on 2006-08-14 14:39 傻 瓜 閱讀(2387) 評(píng)論(2)  編輯  收藏 所屬分類: 雜項(xiàng)

          評(píng)論

          # re: 訪問者模式實(shí)戰(zhàn):構(gòu)建通用的數(shù)據(jù)庫(kù)插入操作 2006-08-14 15:08 伯伯

          暈了!

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

            回復(fù)  更多評(píng)論   

          # re: 訪問者模式實(shí)戰(zhàn):構(gòu)建通用的數(shù)據(jù)庫(kù)插入操作 2006-10-08 12:29 我的


            回復(fù)  更多評(píng)論   

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(7)

          我參與的團(tuán)隊(duì)

          隨筆分類

          隨筆檔案

          文章分類

          友情鏈接

          搜索

          積分與排名

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 探索| 合肥市| 武汉市| 大同县| 朝阳市| 杭锦旗| 龙川县| 城固县| 吐鲁番市| 九龙县| 通道| 庐江县| 佛冈县| 金塔县| 石城县| 柘荣县| 穆棱市| 社旗县| 分宜县| 漳州市| 宿州市| 陵川县| 双江| 仲巴县| 遂平县| 合肥市| 南和县| 昌都县| 遵义市| 永安市| 白水县| 阳信县| 武平县| 噶尔县| 安庆市| 呈贡县| 汉沽区| 大名县| 富裕县| 绍兴市| 长泰县|