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

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

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

    Java && C#

    要學(xué)得東西很多,但我們的時(shí)間卻不是很多!
    數(shù)據(jù)加載中……

    2007年3月13日

    點(diǎn)點(diǎn)滴滴

         N長(zhǎng)時(shí)間沒有來了.......
         忙中偷閑,整理點(diǎn)代碼。
         /** 
         *  復(fù)制單個(gè)文件 
         *  @param  oldPath  String  原文件路徑  如:c:/fqf.txt 
         *  @param  newPath  String  復(fù)制后路徑  如:f:/fqf.txt 
         *  @return  boolean 
         */ 
       public  void  copyFile(String  oldPath,  String  newPath) 
       { 
           try  { 
               int  bytesum  =  0; 
               int  byteread  =  0; 
               File  oldfile  =  new  File(oldPath); 
               if  (oldfile.exists())  {  //文件存在時(shí) 
                   InputStream  inStream  =  new  FileInputStream(oldPath);  //讀入原文件 
                   FileOutputStream  fs  =  new  FileOutputStream(newPath); 
                   byte[]  buffer  =  new  byte[1444]; 
                   int  length; 
                   while  (  (byteread  =  inStream.read(buffer))  !=  -1)  { 
                       bytesum  +=  byteread;  //字節(jié)數(shù)  文件大小 
                       System.out.println(bytesum); 
                       fs.write(buffer,  0,  byteread); 
                   } 
                   inStream.close(); 
               } 
           } 
           catch  (Exception  e)  { 
               System.out.println("復(fù)制單個(gè)文件操作出錯(cuò)"); 
               e.printStackTrace();  
           }  
       }  

    //保存文件的方法
    public String Savefiles(FormFile file,String path)
     {  
      String fileName= file.getFileName();
      String contentType = file.getContentType();
      String size = (file.getFileSize() + " bytes");
      try
      {
       ByteArrayOutputStream baos = new ByteArrayOutputStream();
       InputStream stream = file.getInputStream();
       OutputStream bos = new FileOutputStream(path+fileName);
       int bytesRead = 0;
       byte[] buffer = new byte[8192];
       while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {
        bos.write(buffer, 0, bytesRead);
       }
       bos.close();      
       stream.close();  
      }
      catch (IOException e) {
       return e.getMessage();
      }
      return "1";
     }

    //生成15位的字符串
    public String GenTradeId()
     {
      String tradeId = "";
      RandomStrg.setCharset("a-zA-Z0-9");  
      RandomStrg.setLength("15");  
      try
      {
       RandomStrg.generateRandomObject();
       tradeId=RandomStrg.getRandom();   
      }
      catch (Exception e)
      {    
      }
      return tradeId;  
     }

    /**
      * 刪除字符串中的空格,至多只保留一個(gè)空格
      * 
      * @String txt:輸入需要處理的字符串
      * @return String :返回處理后的字符串
      * 
      */
     public String deleteWhitespace(String txt){
      if((txt!=null)&&(txt.trim().length()>1)){
       
      }
      else{
       return "";
      }
      
      txt = txt.replaceAll("\n"," ").replaceAll("\t"," ");
      String temp="";
      try{
       int flag =0,num=0;
       char c = 'x';
       StringBuffer sb = new StringBuffer("");
       for(int x=0;x<txt.length();x++){
        c = txt.charAt(x);
        if((c==' ')&&(flag==0)){
         sb.append(c);
         flag =1;
        }
        else if((c!=' ')){
         sb.append(c);
         flag =0;
        }
       }
       temp = sb.toString().trim();
      }
      catch(Exception e){
       ;
      }
      return temp;
     }

    posted @ 2007-08-08 11:03 Bill111 閱讀(1534) | 評(píng)論 (0)編輯 收藏
    JavaScript Example

         摘要: 1.文本框焦點(diǎn)問題onBlur:當(dāng)失去輸入焦點(diǎn)后產(chǎn)生該事件onFocus:當(dāng)輸入獲得焦點(diǎn)后,產(chǎn)生該文件Onchange:當(dāng)文字值改變時(shí),產(chǎn)生該事件Onselect:當(dāng)文字加亮后,產(chǎn)生該文件 <input type="text" value="郭強(qiáng)" onfocus="if(value=='郭強(qiáng)') {value=''}" onblur="if (value=='')...  閱讀全文

    posted @ 2007-03-27 17:18 Bill111 閱讀(2249) | 評(píng)論 (0)編輯 收藏
    SQL執(zhí)行效率

    SQL語句中,IN、EXISTS、NOT IN、NOT EXISTS的效率較低,尤其是后兩種語句,當(dāng)數(shù)據(jù)量較大時(shí),更常給人一種死機(jī)般的感覺。本文提供一種使用連接的方法代替以上的四種語句,可大副提高SQL語句的運(yùn)行效率。以NOT IN為例,當(dāng)數(shù)據(jù)量達(dá)到一萬時(shí),效率可提高20倍,數(shù)據(jù)量越大,效率提高的幅度也就越大。

    本文所舉的例子在Oracle 7.0下運(yùn)行通過,但本文所推薦的方法在各種大型數(shù)據(jù)庫上皆適用。
    為了能夠更好的說明問題,我們采用示例的方式來說明問題。下面,我們將創(chuàng)建一些數(shù)據(jù)庫表和數(shù)據(jù),用于在舉例時(shí)使用。

    下面的語句將創(chuàng)建我們示例中將使用的表,并分別在表1(TAB1)中存入10000條數(shù)據(jù),表2(TAB2)中存入5000條數(shù)據(jù)。

    SQL語句如下:

    CREATE TABLE TAB1
    (
    COL1 VARCHAR(20) NOT NULL,
    COL2 INTEGER,
    PRIMARY KEY(COL1)
    );
    CREATE TABLE TAB2
    (
    COL1 VARCHAR(20) NOT NULL,
    PRIMARY KEY(COL1)
    );
    CREATE TABLE TAB3
    (
    COL1 VARCHAR(20) NOT NULL,
    PRIMARY KEY(COL1)
    );
    CREATE OR REPLACE TRIGGER T_TAB3 BEFORE INSERT ON TAB3 FOR EACH ROW
    DECLARE
    NUM1 NUMBER;
    BEGIN
    NUM1:=1;
    LOOP
    EXIT WHEN NUM1>10000;
    INSERT INTO TAB1 VALUES (NUM1,NUM1);
    IF NUM1<=5000 THEN INSERT INTO TAB2 VALUES (NUM1);
    END IF;
    NUM1:=NUM1+1;
    END LOOP;
    END;
    INSERT INTO TAB3 VALUES('1');

    下面,我們將舉2個(gè)例子來具體說明使用連接替換IN、NOT IN、EXISTS、NOT EXISTS的方法。

     讀取表1中第2列(COL2)數(shù)據(jù)的總和,且其第1列數(shù)據(jù)存在于表2的第1列中。

    1. 使用IN的SQL語句:

    SELECT SUM(COL2) FROM TAB1 WHERE COL1 IN(SELECT COL1 FROM TAB2)

    2. 使用EXISTS的SQL語句:

    SELECT SUM(COL2) FROM TAB1 WHERE EXISTS(SELECT * FROM TAB2 WHERE TAB1.COL1=TAB2.COL1)

    3. 使用連接的SQL語句:

    SELECT SUM(A.COL2) FROM TAB1 A,TAB2 B

    WHERE A.COL1=B.COL1

     讀取表1中第2列(COL2)數(shù)據(jù)的總和,且其第1列數(shù)據(jù)不存在于表2的第1列中。


    1. 使用NOT IN的SQL語句:

    SELECT SUM(COL2) FROM TAB1 WHERE COL1 NOT IN(SELECT COL1 FROM TAB2)

    2. 使用NOT EXISTS的SQL語句:

    SELECT SUM(COL2) FROM TAB1 WHERE NOT EXISTS(SELECT * FROM TAB2 WHERE
    TAB1.COL1=TAB2.COL1)

    3. 使用外連接的SQL語句:

    SELECT SUM(A.COL2) FROM TAB1 A,TAB2 B WHERE A.COL1=B.COL1(+) AND B.COL1 IS NULL

    下面介紹IN、NOT IN、EXIST、NOT EXIST在DELETE和UPDATE語句中的效率提高方法。

    下面所舉的例子在Microsoft SQL Server 7.0下運(yùn)行通過,但所推薦的方法在各種大型數(shù)據(jù)庫上皆適用。下面,我們將創(chuàng)建一些數(shù)據(jù)庫表和數(shù)據(jù),用于舉例說明。我們將分別在表A(TA)中存入 10000條數(shù)據(jù),表B(TB)中存入5000條數(shù)據(jù)。

    SQL語句如下:

    CREATE TABLE TA
    (
    CA INT
    )
    CREATE TABLE TB
    (
    CA INT
    )
    CREATE TABLE TC
    (
    CA INT
    )
    CREATE TRIGGER TRA ON TC
    FOR INSERT
    AS
    DECLARE @MINT INT
    BEGIN
    SELECT @MINT=1
    WHILE (@MINT<=5000)
    BEGIN
    INSERT INTO TA VALUES(@MINT)
    INSERT INTO TB VALUES(@MINT)
    SELECT @MINT=@MINT+1
    END
    WHILE (@MINT<=10000)
    BEGIN
    INSERT INTO TA VALUES(@MINT)
    SELECT @MINT=@MINT+1
    END
    END
    GO
    INSERT INTO TC VALUES(1)
    GO

     刪除表A中表A和表B相同的數(shù)據(jù)

    1. 用IN的SQL語句:
    DELETE FROM TA WHERE TA.CA IN (SELECT CA FROM TB)

    2. 用EXISTS的SQL語句:
    DELETE FROM TA WHERE EXISTS (SELECT * FROM TB WHERE TB.CA=TA.CA)

    3. 使用連接的SQL語句:
    DELETE TA FROM TA,TB WHERE TA.CA=TB.CA

     刪除表A中表A存在但表B中不存在的數(shù)據(jù)

    1. 使用IN的SQL語句:
    DELETE FROM TA WHERE TA.CA NOT IN (SELECT CA FROM TB)

    2. 使用EXISTS的SQL語句:
    DELETE FROM TA WHERE NOT EXISTS (SELECT CA FROM TB WHERE TB.CA=TA.CA)

    3. 使用連接的SQL語句:
    DELETE TA FROM TA LEFT OUTER JOIN TB ON TA.CA=TB.CA WHERE TB.CA IS NULL


     更新表A中表A和表B相同的數(shù)據(jù)
    1. 使用IN的SQL語句:
    UPDATE TA SET CA=CA+10000 WHERE CA IN (SELECT CA FROM TB)

    2. 使用EXISTS的SQL語句:
    UPDATE TA SET CA=CA+10000 WHERE EXISTS (SELECT CA FROM TB WHERE TB.CA=TA.CA)

    3. 使用連接的SQL語句:
    UPDATE TA SET TA.CA=TA.CA+10000 FROM TA,TB WHERE TA.CA=TB.CA


     更新表A中表A存在但表B中不存在的數(shù)據(jù)

    1. 使用IN的SQL語句:
    UPDATE TA SET CA=CA+10000 WHERE CA NOT IN (SELECT CA FROM TB)

    2. 使用EXISTS的SQL語句:
    UPDATE TA SET CA=CA+10000 WHERE NOT EXISTS (SELECT CA FROM TB WHERE TB.CA=TA.CA)

    3. 使用連接的SQL語句:
    UPDATE TA SET TA.CA=TA.CA+10000 FROM TA LEFT OUTER JOIN TB ON TA.CA=TB.CA WHERE TB.CA IS NULL

    posted @ 2007-03-23 13:50 Bill111 閱讀(3620) | 評(píng)論 (2)編輯 收藏
    java基礎(chǔ)知識(shí)回顧

    問題一:我聲明了什么!

    String s = "Hello world!";

    許多人都做過這樣的事情,但是,我們到底聲明了什么?回答通常是:一個(gè)String,內(nèi)容是“Hello world!”。這樣模糊的回答通常是概念不清的根源。如果要準(zhǔn)確的回答,一半的人大概會(huì)回答錯(cuò)誤。
    這個(gè)語句聲明的是一個(gè)指向?qū)ο蟮囊茫麨椤皊”,可以指向類型為String的任何對(duì)象,目前指向"Hello world!"這個(gè)String類型的對(duì)象。這就是真正發(fā)生的事情。我們并沒有聲明一個(gè)String對(duì)象,我們只是聲明了一個(gè)只能指向String對(duì)象的引用變量。所以,如果在剛才那句語句后面,如果再運(yùn)行一句:

    String string = s;

    我們是聲明了另外一個(gè)只能指向String對(duì)象的引用,名為string,并沒有第二個(gè)對(duì)象產(chǎn)生,string還是指向原來那個(gè)對(duì)象,也就是,和s指向同一個(gè)對(duì)象。

    問題二:"=="和equals方法究竟有什么區(qū)別?

    ==操作符專門用來比較變量的值是否相等。比較好理解的一點(diǎn)是:
    int a=10;
    int b=10;
    則a==b將是true。
    但不好理解的地方是:
    String a=new String("foo");
    String b=new String("foo");
    則a==b將返回false。

    根據(jù)前一帖說過,對(duì)象變量其實(shí)是一個(gè)引用,它們的值是指向?qū)ο笏诘膬?nèi)存地址,而不是對(duì)象本身。a和b都使用了new操作符,意味著將在內(nèi)存中產(chǎn)生兩個(gè)內(nèi)容為"foo"的字符串,既然是“兩個(gè)”,它們自然位于不同的內(nèi)存地址。a和b的值其實(shí)是兩個(gè)不同的內(nèi)存地址的值,所以使用"=="操作符,結(jié)果會(huì)是 false。誠然,a和b所指的對(duì)象,它們的內(nèi)容都是"foo",應(yīng)該是“相等”,但是==操作符并不涉及到對(duì)象內(nèi)容的比較。
    對(duì)象內(nèi)容的比較,正是equals方法做的事。

    看一下Object對(duì)象的equals方法是如何實(shí)現(xiàn)的:
    boolean equals(Object o){

    return this==o;

    }
    Object 對(duì)象默認(rèn)使用了==操作符。所以如果你自創(chuàng)的類沒有覆蓋equals方法,那你的類使用equals和使用==會(huì)得到同樣的結(jié)果。同樣也可以看出, Object的equals方法沒有達(dá)到equals方法應(yīng)該達(dá)到的目標(biāo):比較兩個(gè)對(duì)象內(nèi)容是否相等。因?yàn)榇鸢笐?yīng)該由類的創(chuàng)建者決定,所以O(shè)bject把這個(gè)任務(wù)留給了類的創(chuàng)建者。

    看一下一個(gè)極端的類:
    Class Monster{
    private String content;
    ...
    boolean equals(Object another){ return true;}

    }
    我覆蓋了equals方法。這個(gè)實(shí)現(xiàn)會(huì)導(dǎo)致無論Monster實(shí)例內(nèi)容如何,它們之間的比較永遠(yuǎn)返回true。

    所以當(dāng)你是用equals方法判斷對(duì)象的內(nèi)容是否相等,請(qǐng)不要想當(dāng)然。因?yàn)榭赡苣阏J(rèn)為相等,而這個(gè)類的作者不這樣認(rèn)為,而類的equals方法的實(shí)現(xiàn)是由他掌握的。如果你需要使用equals方法,或者使用任何基于散列碼的集合(HashSet,HashMap,HashTable),請(qǐng)察看一下java doc以確認(rèn)這個(gè)類的equals邏輯是如何實(shí)現(xiàn)的。

    問題三:String到底變了沒有?

    沒有。因?yàn)镾tring被設(shè)計(jì)成不可變(immutable)類,所以它的所有對(duì)象都是不可變對(duì)象。請(qǐng)看下列代碼:

    String s = "Hello";
    s = s + " world!";

    s 所指向的對(duì)象是否改變了呢?從本系列第一篇的結(jié)論很容易導(dǎo)出這個(gè)結(jié)論。我們來看看發(fā)生了什么事情。在這段代碼中,s原先指向一個(gè)String對(duì)象,內(nèi)容是 "Hello",然后我們對(duì)s進(jìn)行了+操作,那么s所指向的那個(gè)對(duì)象是否發(fā)生了改變呢?答案是沒有。這時(shí),s不指向原來那個(gè)對(duì)象了,而指向了另一個(gè) String對(duì)象,內(nèi)容為"Hello world!",原來那個(gè)對(duì)象還存在于內(nèi)存之中,只是s這個(gè)引用變量不再指向它了。
    通過上面的說明,我們很容易導(dǎo)出另一個(gè)結(jié)論,如果經(jīng)常對(duì)字符串進(jìn)行各種各樣的修改,或者說,不可預(yù)見的修改,那么使用String來代表字符串的話會(huì)引起很大的內(nèi)存開銷。因?yàn)?String對(duì)象建立之后不能再改變,所以對(duì)于每一個(gè)不同的字符串,都需要一個(gè)String對(duì)象來表示。這時(shí),應(yīng)該考慮使用StringBuffer類,它允許修改,而不是每個(gè)不同的字符串都要生成一個(gè)新的對(duì)象。并且,這兩種類的對(duì)象轉(zhuǎn)換十分容易。
    同時(shí),我們還可以知道,如果要使用內(nèi)容相同的字符串,不必每次都new一個(gè)String。例如我們要在構(gòu)造器中對(duì)一個(gè)名叫s的String引用變量進(jìn)行初始化,把它設(shè)置為初始值,應(yīng)當(dāng)這樣做:
    public class Demo {
    private String s;
    ...
    public Demo {
    s = "Initial Value";
    }
    ...
    }
    而非
    s = new String("Initial Value");
    后者每次都會(huì)調(diào)用構(gòu)造器,生成新對(duì)象,性能低下且內(nèi)存開銷大,并且沒有意義,因?yàn)镾tring對(duì)象不可改變,所以對(duì)于內(nèi)容相同的字符串,只要一個(gè)String對(duì)象來表示就可以了。也就說,多次調(diào)用上面的構(gòu)造器創(chuàng)建多個(gè)對(duì)象,他們的String類型屬性s都指向同一個(gè)對(duì)象。
    上面的結(jié)論還基于這樣一個(gè)事實(shí):對(duì)于字符串常量,如果內(nèi)容相同,Java認(rèn)為它們代表同一個(gè)String對(duì)象。而用關(guān)鍵字new調(diào)用構(gòu)造器,總是會(huì)創(chuàng)建一個(gè)新的對(duì)象,無論內(nèi)容是否相同。
    至于為什么要把String類設(shè)計(jì)成不可變類,是它的用途決定的。其實(shí)不只String,很多Java標(biāo)準(zhǔn)類庫中的類都是不可變的。在開發(fā)一個(gè)系統(tǒng)的時(shí)候,我們有時(shí)候也需要設(shè)計(jì)不可變類,來傳遞一組相關(guān)的值,這也是面向?qū)ο笏枷氲捏w現(xiàn)。不可變類有一些優(yōu)點(diǎn),比如因?yàn)樗膶?duì)象是只讀的,所以多線程并發(fā)訪問也不會(huì)有任何問題。當(dāng)然也有一些缺點(diǎn),比如每個(gè)不同的狀態(tài)都要一個(gè)對(duì)象來代表,可能會(huì)造成性能上的問題。所以Java標(biāo)準(zhǔn)類庫還提供了一個(gè)可變版本,即 StringBuffer。

    問題四:final關(guān)鍵字到底修飾了什么?

    final使得被修飾的變量"不變",但是由于對(duì)象型變量的本質(zhì)是“引用”,使得“不變”也有了兩種含義:引用本身的不變,和引用指向的對(duì)象不變。

    引用本身的不變:
    final StringBuffer a=new StringBuffer("immutable");
    final StringBuffer b=new StringBuffer("not immutable");
    a=b;//編譯期錯(cuò)誤

    引用指向的對(duì)象不變:
    final StringBuffer a=new StringBuffer("immutable");
    a.append(" broken!"); //編譯通過

    可見,final只對(duì)引用的“值”(也即它所指向的那個(gè)對(duì)象的內(nèi)存地址)有效,它迫使引用只能指向初始指向的那個(gè)對(duì)象,改變它的指向會(huì)導(dǎo)致編譯期錯(cuò)誤。至于它所指向的對(duì)象的變化,final是不負(fù)責(zé)的。這很類似==操作符:==操作符只負(fù)責(zé)引用的“值”相等,至于這個(gè)地址所指向的對(duì)象內(nèi)容是否相等,==操作符是不管的。

    理解final問題有很重要的含義。許多程序漏洞都基于此----final只能保證引用永遠(yuǎn)指向固定對(duì)象,不能保證那個(gè)對(duì)象的狀態(tài)不變。在多線程的操作中,一個(gè)對(duì)象會(huì)被多個(gè)線程共享或修改,一個(gè)線程對(duì)對(duì)象無意識(shí)的修改可能會(huì)導(dǎo)致另一個(gè)使用此對(duì)象的線程崩潰。一個(gè)錯(cuò)誤的解決方法就是在此對(duì)象新建的時(shí)候把它聲明為final,意圖使得它“永遠(yuǎn)不變”。其實(shí)那是徒勞的。

    問題五:到底要怎么樣初始化!

    本問題討論變量的初始化,所以先來看一下Java中有哪些種類的變量。
    1. 類的屬性,或者叫值域
    2. 方法里的局部變量
    3. 方法的參數(shù)

    對(duì)于第一種變量,Java虛擬機(jī)會(huì)自動(dòng)進(jìn)行初始化。如果給出了初始值,則初始化為該初始值。如果沒有給出,則把它初始化為該類型變量的默認(rèn)初始值。

    int類型變量默認(rèn)初始值為0
    float類型變量默認(rèn)初始值為0.0f
    double類型變量默認(rèn)初始值為0.0
    boolean類型變量默認(rèn)初始值為false
    char類型變量默認(rèn)初始值為0(ASCII碼)
    long類型變量默認(rèn)初始值為0
    所有對(duì)象引用類型變量默認(rèn)初始值為null,即不指向任何對(duì)象。注意數(shù)組本身也是對(duì)象,所以沒有初始化的數(shù)組引用在自動(dòng)初始化后其值也是null。

    對(duì)于兩種不同的類屬性,static屬性與instance屬性,初始化的時(shí)機(jī)是不同的。instance屬性在創(chuàng)建實(shí)例的時(shí)候初始化,static屬性在類加載,也就是第一次用到這個(gè)類的時(shí)候初始化,對(duì)于后來的實(shí)例的創(chuàng)建,不再次進(jìn)行初始化。這個(gè)問題會(huì)在以后的系列中進(jìn)行詳細(xì)討論。

    對(duì)于第二種變量,必須明確地進(jìn)行初始化。如果再?zèng)]有初始化之前就試圖使用它,編譯器會(huì)抗議。如果初始化的語句在try塊中或if塊中,也必須要讓它在第一次使用前一定能夠得到賦值。也就是說,把初始化語句放在只有if塊的條件判斷語句中編譯器也會(huì)抗議,因?yàn)閳?zhí)行的時(shí)候可能不符合if后面的判斷條件,如此一來初始化語句就不會(huì)被執(zhí)行了,這就違反了局部變量使用前必須初始化的規(guī)定。但如果在else塊中也有初始化語句,就可以通過編譯,因?yàn)闊o論如何,總有至少一條初始化語句會(huì)被執(zhí)行,不會(huì)發(fā)生使用前未被初始化的事情。對(duì)于try-catch也是一樣,如果只有在try塊里才有初始化語句,編譯部通過。如果在 catch或finally里也有,則可以通過編譯。總之,要保證局部變量在使用之前一定被初始化了。所以,一個(gè)好的做法是在聲明他們的時(shí)候就初始化他們,如果不知道要出事化成什么值好,就用上面的默認(rèn)值吧!

    其實(shí)第三種變量和第二種本質(zhì)上是一樣的,都是方法中的局部變量。只不過作為參數(shù),肯定是被初始化過的,傳入的值就是初始值,所以不需要初始化。

    問題六:instanceof是什么東東?

    instanceof是Java的一個(gè)二元操作符,和==,>,<是同一類東東。由于它是由字母組成的,所以也是Java的保留關(guān)鍵字。它的作用是測(cè)試它左邊的對(duì)象是否是它右邊的類的實(shí)例,返回boolean類型的數(shù)據(jù)。舉個(gè)例子:

    String s = "I AM an Object!";
    boolean isObject = s instanceof Object;

    我們聲明了一個(gè)String對(duì)象引用,指向一個(gè)String對(duì)象,然后用instancof來測(cè)試它所指向的對(duì)象是否是Object類的一個(gè)實(shí)例,顯然,這是真的,所以返回true,也就是isObject的值為True。
    instanceof有一些用處。比如我們寫了一個(gè)處理賬單的系統(tǒng),其中有這樣三個(gè)類:

    public class Bill {//省略細(xì)節(jié)}
    public class PhoneBill extends Bill {//省略細(xì)節(jié)}
    public class GasBill extends Bill {//省略細(xì)節(jié)}

    在處理程序里有一個(gè)方法,接受一個(gè)Bill類型的對(duì)象,計(jì)算金額。假設(shè)兩種賬單計(jì)算方法不同,而傳入的Bill對(duì)象可能是兩種中的任何一種,所以要用instanceof來判斷:

    public double calculate(Bill bill) {
    if (bill instanceof PhoneBill) {
    //計(jì)算電話賬單
    }
    if (bill instanceof GasBill) {
    //計(jì)算燃?xì)赓~單
    }
    ...
    }
    這樣就可以用一個(gè)方法處理兩種子類。

    然而,這種做法通常被認(rèn)為是沒有好好利用面向?qū)ο笾械亩鄳B(tài)性。其實(shí)上面的功能要求用方法重載完全可以實(shí)現(xiàn),這是面向?qū)ο笞兂蓱?yīng)有的做法,避免回到結(jié)構(gòu)化編程模式。只要提供兩個(gè)名字和返回值都相同,接受參數(shù)類型不同的方法就可以了:

    public double calculate(PhoneBill bill) {
    //計(jì)算電話賬單
    }

    public double calculate(GasBill bill) {
    //計(jì)算燃?xì)赓~單
    }

    所以,使用instanceof在絕大多數(shù)情況下并不是推薦的做法,應(yīng)當(dāng)好好利用多態(tài)。

    posted @ 2007-03-16 15:19 Bill111 閱讀(254) | 評(píng)論 (0)編輯 收藏
    何為J2ee?

    J2ee(Java 2 Enterprise Edition)是建立在Java 2平臺(tái)上的企業(yè)級(jí)應(yīng)用的解決方案。J2EE技術(shù)的基礎(chǔ)便是Java 2平臺(tái),不但有J2SE平臺(tái)的所有功能,同時(shí)還提供了對(duì)EJBServlet,JSP,XML等技術(shù)的全面支持,其最終目標(biāo)是成為一個(gè)支持企業(yè)級(jí)應(yīng)用開發(fā)的體系結(jié)構(gòu),簡(jiǎn)化企業(yè)解決方案的開發(fā),部署和管理等復(fù)雜問題。事實(shí)上,J2EE已經(jīng)成為企業(yè)級(jí)開發(fā)的工業(yè)標(biāo)準(zhǔn)和首選平臺(tái)。

      J2EE并非一個(gè)產(chǎn)品,而是一系列的標(biāo)準(zhǔn)。市場(chǎng)上可以看到很多實(shí)現(xiàn)了J2EE的產(chǎn)品,如BEA WebLogic,IBM WebSphere以及開源JBoss等等。

    ????? J2EE,是sun公司提出的一個(gè)標(biāo)準(zhǔn),符合這個(gè)標(biāo)準(zhǔn)的產(chǎn)品叫"實(shí)現(xiàn)";其中你下載的sun公司的j2ee開發(fā)包中就有一個(gè)這樣的"實(shí)現(xiàn)",而 jboss,weblogic,websphere都是j2ee標(biāo)準(zhǔn)的一個(gè)"實(shí)現(xiàn)"。由于jboss,weblogic,websphere自身帶有 j2ee的api,所以可以不使用sun的j2ee實(shí)現(xiàn)。

    一. J2EE的概念

    ????? 目前,Java 2平臺(tái)有3個(gè)版本,它們是適用于小型設(shè)備和智能卡的Java 2平臺(tái)Micro版(Java 2 Platform Micro Edition,J2ME)、適用于桌面系統(tǒng)的Java 2平臺(tái)標(biāo)準(zhǔn)版(Java 2 Platform Standard Edition,J2SE)、適用于創(chuàng)建服務(wù)器應(yīng)用程序和服務(wù)的Java2平臺(tái)企業(yè)版(Java 2 Platform Enterprise Edition,J2EE)。

    ????? J2EE是一種利用Java 2平臺(tái)來簡(jiǎn)化企業(yè)解決方案的開發(fā)、部署和管理相關(guān)的復(fù)雜問題的體系結(jié)構(gòu)。J2EE技術(shù)的基礎(chǔ)就是核心Java平臺(tái)或Java 2平臺(tái)的標(biāo)準(zhǔn)版,J2EE不僅鞏固了標(biāo)準(zhǔn)版中的許多優(yōu)點(diǎn),例如"編寫一次、隨處運(yùn)行"的特性、方便存取數(shù)據(jù)庫JDBC API、CORBA技術(shù)以及能夠在Internet應(yīng)用中保護(hù)數(shù)據(jù)的安全模式等等,同時(shí)還提供了對(duì) EJB(Enterprise JavaBeans)、Java Servlets API、JSP(Java Server Pages)以及XML技術(shù)的全面支持。其最終目的就是成為一個(gè)能夠使企業(yè)開發(fā)者大幅縮短投放市場(chǎng)時(shí)間的體系結(jié)構(gòu)。

    ????? J2EE體系結(jié)構(gòu)提供中間層集成框架用來滿足無需太多費(fèi)用而又需要高可用性、高可靠性以及可擴(kuò)展性的應(yīng)用的需求。通過提供統(tǒng)一的開發(fā)平臺(tái),J2EE降低了開發(fā)多層應(yīng)用的費(fèi)用和復(fù)雜性,同時(shí)提供對(duì)現(xiàn)有應(yīng)用程序集成強(qiáng)有力支持,完全支持Enterprise JavaBeans,有良好的向?qū)еС执虬筒渴饝?yīng)用,添加目錄支持,增強(qiáng)了安全機(jī)制,提高了性能。

    二. J2EE的優(yōu)勢(shì)

    ???? J2EE為搭建具有可伸縮性、靈活性、易維護(hù)性的商務(wù)系統(tǒng)提供了良好的機(jī)制:
    ????? 保留現(xiàn)存的IT資產(chǎn): 由于企業(yè)必須適應(yīng)新的商業(yè)需求,利用已有的企業(yè)信息系統(tǒng)方面的投資,而不是重新制定全盤方案就變得很重要。這樣,一個(gè)以漸進(jìn)的(而不是激進(jìn)的,全盤否定的)方式建立在已有系統(tǒng)之上的服務(wù)器端平臺(tái)機(jī)制是公司所需求的。J2EE架構(gòu)可 以充分利用用戶原有的投資,如一些公司使用的BEA Tuxedo、IBM CICS, IBM Encina,、Inprise VisiBroker 以及Netscape Application Server。這之所以成為可能是因?yàn)镴2EE擁有廣泛的業(yè)界支持和一些重要的'企業(yè)計(jì)算'領(lǐng)域供應(yīng)商的參與。每一個(gè)供應(yīng)商都對(duì)現(xiàn)有的客戶提供了不用廢棄 已有投資,進(jìn)入可移植的J2EE領(lǐng)域的升級(jí)途徑。由于基于J2EE平臺(tái)的產(chǎn)品幾乎能夠在任何操作系統(tǒng)和硬件配置上運(yùn)行,現(xiàn)有的操作系統(tǒng)和硬件也能被保留使用。

    ????? 高效的開發(fā): J2EE允許公司把一些通用的、很繁瑣的服務(wù)端任務(wù)交給中間件供應(yīng)商去完成。這樣開發(fā)人員可以集中精力在如何創(chuàng)建商業(yè)邏輯上,相應(yīng)地縮短了開發(fā)時(shí)間。高級(jí)中間件供應(yīng)商提供以下這些復(fù)雜的中間件服務(wù):

    ????? 狀態(tài)管理服務(wù) -- 讓開發(fā)人員寫更少的代碼,不用關(guān)心如何管理狀態(tài),這樣能夠更快地完成程序開發(fā)。
    ????? 持續(xù)性服務(wù) -- 讓開發(fā)人員不用對(duì)數(shù)據(jù)訪問邏輯進(jìn)行編碼就能編寫應(yīng)用程序,能生成更輕巧,與數(shù)據(jù)庫無關(guān)的應(yīng)用程序,這種應(yīng)用程序更易于開發(fā)與維護(hù)。
    ????? 分布式共享數(shù)據(jù)對(duì)象CACHE服務(wù) -- 讓開發(fā)人員編制高性能的系統(tǒng),極大提高整體部署的伸縮性。
    ????? 支持異構(gòu)環(huán)境: J2EE能夠開發(fā)部署在異構(gòu)環(huán)境中的可移植程序。基于J2EE的應(yīng)用程序不依賴任何特定操作系統(tǒng)、中間件、硬件。因此設(shè)計(jì)合理的基于J2EE的程序只需開 發(fā)一次就可部署到各種平臺(tái)。這在典型的異構(gòu)企業(yè)計(jì)算環(huán)境中是十分關(guān)鍵的。J2EE標(biāo)準(zhǔn)也允許客戶訂購與J2EE兼容的第三方的現(xiàn)成的組件,把他們部署到異構(gòu)環(huán)境中,節(jié)省了由自己制訂整個(gè)方案所需的費(fèi)用。
    ????? 可伸縮性: 企業(yè)必須要選擇一種服務(wù)器端平臺(tái),這種平臺(tái)應(yīng)能提供極佳的可伸縮性去滿足那些在他們系統(tǒng)上進(jìn)行商業(yè)運(yùn)作的大批新客戶。基于J2EE平臺(tái)的應(yīng)用程序可被部署 到各種操作系統(tǒng)上。例如可被部署到高端UNIX與大型機(jī)系統(tǒng),這種系統(tǒng)單機(jī)可支持64至256個(gè)處理器。(這是NT服務(wù)器所望塵莫及的)J2EE領(lǐng)域的供 應(yīng)商提供了更為廣泛的負(fù)載平衡策略。能消除系統(tǒng)中的瓶頸,允許多臺(tái)服務(wù)器集成部署。這種部署可達(dá)數(shù)千個(gè)處理器,實(shí)現(xiàn)可高度伸縮的系統(tǒng),滿足未來商業(yè)應(yīng)用的 需要。
    ????? 穩(wěn)定的可用性: 一個(gè)服務(wù)器端平臺(tái)必須能全天候運(yùn)轉(zhuǎn)以滿足公司客戶、合作伙伴的需要。因?yàn)镮NTERNET是全球化的、無處不在的,即使在夜間按計(jì)劃停機(jī)也可能造成嚴(yán)重?fù)p 失。若是意外停機(jī),那會(huì)有災(zāi)難性后果。J2EE部署到可靠的操作環(huán)境中,他們支持長(zhǎng)期的可用性。一些J2EE部署在WINDOWS環(huán)境中,客戶也可選擇健 壯性能更好的操作系統(tǒng)如Sun Solaris、IBM OS/390。最健壯的操作系統(tǒng)可達(dá)到99.999%的可用性或每年只需5分鐘停機(jī)時(shí)間。這是實(shí)時(shí)性很強(qiáng)商業(yè)系統(tǒng)理想的選擇。

    三. J2EE 的四層模型

    ????? J2EE使用多層的分布式應(yīng)用模型,應(yīng)用邏輯按功能劃分為組件,各個(gè)應(yīng)用組件根據(jù)他們所在的層分布在不同的機(jī)器上。事實(shí)上,sun設(shè)計(jì)J2EE的初衷正是為了解決兩層模式(client/server)的弊端,在傳統(tǒng)模式中,客戶端擔(dān) 當(dāng)了過多的角色而顯得臃腫,在這種模式中,第一次部署的時(shí)候比較容易,但難于升級(jí)或改進(jìn),可伸展性也不理想,而且經(jīng)常基于某種專有的協(xié)議――通常是某種數(shù) 據(jù)庫協(xié)議。它使得重用業(yè)務(wù)邏輯和界面邏輯非常困難。現(xiàn)在J2EE 的多層企業(yè)級(jí)應(yīng)用模型將兩層化模型中的不同層面切分成許多層。一個(gè)多層化應(yīng)用能夠?yàn)椴煌拿糠N服務(wù)提供一個(gè)獨(dú)立的層,以下是 J2EE 典型的四層結(jié)構(gòu):

    ????? 運(yùn)行在客戶端機(jī)器上的客戶層組件
    ????? 運(yùn)行在J2EE服務(wù)器上的Web層組件
    ????? 運(yùn)行在J2EE服務(wù)器上的業(yè)務(wù)邏輯層組件
    ????? 運(yùn)行在EIS服務(wù)器上的企業(yè)信息系統(tǒng)(Enterprise information system)層軟件

    ????? J2EE應(yīng)用程序組件
    ????? J2EE應(yīng)用程序是由組件構(gòu)成的.J2EE組件是具有獨(dú)立功能的軟件單元,它們通過相關(guān)的文件組裝成J2EE應(yīng)用程序,并與其他組件交互。J2EE說明書中定義了以下的J2EE組件:
    ????? 應(yīng)用客戶端程序和applets是客戶層組件.
    ????? Java Servlet和JavaServer Pages(JSP)是web層組件.
    ????? Enterprise JavaBeans(EJB)是業(yè)務(wù)層組件.

    ????? 客戶層組件
    ????? J2EE應(yīng)用程序可以是基于web方式的,也可以是基于傳統(tǒng)方式的.
    ????? web 層組件J2EE web層組件可以是JSP 頁面或Servlets.按照J(rèn)2EE規(guī)范,靜態(tài)的HTML頁面和Applets不算是web層組件。

    ????? 正如下圖所示的客戶層那樣,web層可能包含某些 JavaBean 對(duì)象來處理用戶輸入,并把
    輸入發(fā)送給運(yùn)行在業(yè)務(wù)層上的enterprise bean 來進(jìn)行處理。

    ????? 業(yè)務(wù)層組件
    ????? 業(yè)務(wù)層代碼的邏輯用來滿足銀行,零售,金融等特殊商務(wù)領(lǐng)域的需要,由運(yùn)行在業(yè)務(wù)層上的enterprise bean 進(jìn)行處理. 下圖表明了一個(gè)enterprise bean 是如何從客戶端程序接收數(shù)據(jù),進(jìn)行處理(如果必要的話), 并發(fā)送到EIS 層儲(chǔ)存的,這個(gè)過程也可以逆向進(jìn)行。

    ????? 有三種企業(yè)級(jí)的bean: 會(huì)話(session) beans, 實(shí)體(entity) beans, 和 消息驅(qū) 動(dòng)(message-driven) beans. 會(huì)話bean 表示與客戶端程序的臨時(shí)交互. 當(dāng)客戶端程序執(zhí)行完后, 會(huì)話bean 和相關(guān)數(shù)據(jù)就會(huì)消失. 相反, 實(shí)體bean 表示數(shù)據(jù)庫的表中一行永久的記錄. 當(dāng)客戶端程序中止或服務(wù)器關(guān)閉時(shí), 就會(huì)有潛在的服務(wù)保證實(shí)體bean 的數(shù)據(jù)得以保存.消息驅(qū)動(dòng) bean 結(jié)合了會(huì)話bean 和 JMS的消息監(jiān)聽器的特性, 允許一個(gè)業(yè)務(wù)層組件異步接收J(rèn)MS 消息.

    ????? 企業(yè)信息系統(tǒng)層
    ????? 企業(yè)信息系統(tǒng)層處理企業(yè)信息系統(tǒng)軟件包括企業(yè)基礎(chǔ)建設(shè)系統(tǒng)例如企業(yè)資源計(jì)劃 (ERP), 大型機(jī)事務(wù)處理, 數(shù)據(jù)庫系統(tǒng),和其它的遺留信息系統(tǒng). 例如,J2EE 應(yīng)用組件可能為了數(shù)據(jù)庫連接需要訪問企業(yè)信息系統(tǒng)

    ????? 我們就J2EE的各種組件、服務(wù)和API,進(jìn)行更加詳細(xì)的闡述,看看在開發(fā)不同類型的企業(yè)級(jí)應(yīng)用時(shí),根據(jù)各自需求和目標(biāo)的不同,應(yīng)當(dāng)如何靈活使用并組合不同的組件和服務(wù)。

    · Servlet

    ????? Servlet是Java平臺(tái)上的CGI技術(shù)。Servlet在服務(wù)器端運(yùn)行,動(dòng)態(tài)地生成Web頁面。與傳統(tǒng)的CGI和許多其它類似CGI的技術(shù)相比, Java Servlet具有更高的效率并更容易使用。對(duì)于Servlet,重復(fù)的請(qǐng)求不會(huì)導(dǎo)致同一程序的多次轉(zhuǎn)載,它是依靠線程的方式來支持并發(fā)訪問的。

    · JSP

    ????? JSP(Java Server Page)是一種實(shí)現(xiàn)普通靜態(tài)HTML和動(dòng)態(tài)頁面輸出混合編碼的技術(shù)。從這一點(diǎn)來看,非常類似Microsoft ASP、PHP等 技術(shù)。借助形式上的內(nèi)容和外觀表現(xiàn)的分離,Web頁面制作的任務(wù)可以比較方便地劃分給頁面設(shè)計(jì)人員和程序員,并方便地通過JSP來合成。在運(yùn)行時(shí)態(tài), JSP將會(huì)被首先轉(zhuǎn)換成Servlet,并以Servlet的形態(tài)編譯運(yùn)行,因此它的效率和功能與Servlet相比沒有差別,一樣具有很高的效率。

    · EJB

    ????? EJB定義了一組可重用的組件:Enterprise Beans。開發(fā)人員可以利用這些組件,像搭積木一樣建立分布式應(yīng)用。在裝配組件時(shí),所有的Enterprise Beans都需要配置到EJB服務(wù)器(一般的Weblogic、WebSphere等J2EE應(yīng)用服務(wù)器都 是EJB服務(wù)器)中。EJB服務(wù)器作為容器和低層平臺(tái)的橋梁管理著EJB容器,并向該容器提供訪問系統(tǒng)服務(wù)的能力。所有的EJB實(shí)例都運(yùn)行在EJB容器 中。EJB容器提供了系統(tǒng)級(jí)的服務(wù),控制了EJB的生命周期。EJB容器為它的開發(fā)人員代管了諸如安全性、遠(yuǎn)程連接、生命周期管理及事務(wù)管理等技術(shù)環(huán)節(jié), 簡(jiǎn)化了商業(yè)邏輯的開發(fā)。EJB中定義了三種Enterprise Beans:

    ◆ Session Beans

    ◆ Entity Beans

    ◆ Message-driven Beans

    · JDBC

    ????? JDBC(Java Database Connectivity,Java數(shù)據(jù)庫連接)API是一個(gè)標(biāo)準(zhǔn)SQL(Structured Query Language, 結(jié)構(gòu)化查詢語言)數(shù)據(jù)庫訪問接口,它使數(shù)據(jù)庫開發(fā)人員能夠用標(biāo)準(zhǔn)Java API編寫數(shù)據(jù)庫應(yīng)用程序。JDBC API主要用來連接數(shù)據(jù)庫和直接調(diào)用SQL命令執(zhí)行各種SQL語句。利用JDBC API可以執(zhí)行一般的SQL語句、動(dòng)態(tài)SQL語句及帶IN和OUT參數(shù)的存儲(chǔ)過程。Java中的JDBC相當(dāng)與Microsoft平臺(tái)中的ODBC(Open Database Connectivity)。

    · JMS

    ????? JMS(Java Message ServiceJava消息服務(wù)) 是一組Java應(yīng)用接口,它提供創(chuàng)建、發(fā)送、接收、讀取消息的服務(wù)。JMS API定義了一組公共的應(yīng)用程序接口和相應(yīng)語法,使得Java應(yīng)用能夠和各種消息中間件進(jìn)行通信,這些消息中間件包括IBM MQ-Series、Microsoft MSMQ及純Java的SonicMQ。通過使用JMS API,開發(fā)人員無需掌握不同消息產(chǎn)品的使用方法,也可以使用統(tǒng)一的JMS API來操縱各種消息中間件。通過使用JMS,能夠最大限度地提升消息應(yīng)用的可移植性。 JMS既支持點(diǎn)對(duì)點(diǎn)的消息通信,也支持發(fā)布/訂閱式的消息通信。

    · JNDI

    ????? 由于J2EE應(yīng)用程序組件一般分布在不同的機(jī)器上,所以需要一種機(jī)制以便于組件客戶使用者查找和引用組件及資源。在J2EE體系中,使用JNDI (Java Naming and Directory Interface)定位各種對(duì)象,這些對(duì)象包括EJB、數(shù)據(jù)庫驅(qū)動(dòng)、JDBC數(shù)據(jù)源及消息連接等。JNDI API為應(yīng)用程序提供了一個(gè)統(tǒng)一的接口來完成標(biāo)準(zhǔn)的目錄操作,如通過對(duì)象屬性來查找和定位該對(duì)象。由于JNDI是獨(dú)立于目錄協(xié)議的,應(yīng)用還可以使用 JNDI訪問各種特定的目錄服務(wù),如LDAP、NDS和DNS等。

    · JTA

    ????? JTA(Java Transaction API)提供了J2EE中處理事務(wù)的標(biāo)準(zhǔn)接口,它支持事務(wù)的開始、回滾和提交。同時(shí)在一般的J2EE平臺(tái)上,總提供一個(gè)JTS(Java Transaction Service)作為標(biāo)準(zhǔn)的事務(wù)處理服務(wù),開發(fā)人員可以使用JTA來使用JTS。

    · JCA

    ????? JCA(J2EE Connector Architecture)是J2EE體系架構(gòu)的一部分,為開發(fā)人員提供了一套連接各種企業(yè)信息系統(tǒng)(EIS,包括ERP、SCM、CRM等)的體系架構(gòu),對(duì)于EIS開發(fā)商而言,它們只需要開發(fā)一套基于JCA的EIS連接適配器,開發(fā)人員就能夠在任何的J2EE應(yīng)用服務(wù)器中連接并使用它。基于JCA的連接適配器的實(shí)現(xiàn),需要涉及J2EE中的事務(wù)管理、安全管理及連接管理等服務(wù)組件。

    · JMX

    ????? JMX(Java Management Extensions)的前身是JMAPI。JMX致力于解決分布式系統(tǒng)管理的問題。JMX是一種應(yīng)用編程接口、 可擴(kuò)展對(duì)象和方法的集合體,可以跨越各種異構(gòu)操作系統(tǒng)平臺(tái)、系統(tǒng)體系結(jié)構(gòu)和網(wǎng)絡(luò)傳輸協(xié)議,開發(fā)無縫集成的面向系統(tǒng)、網(wǎng)絡(luò)和服務(wù)的管理應(yīng)用。JMX是一個(gè)完 整的網(wǎng)絡(luò)管理應(yīng)用程序開發(fā)環(huán)境,它同時(shí)提供了廠商需要收集的完整的特性清單、可生成資源清單表格、圖形化的用戶接口;訪問SNMP的網(wǎng)絡(luò)API;主機(jī)間遠(yuǎn)程過程調(diào)用;數(shù)據(jù)庫訪問方法等。

    · JAAS

    ????? JAAS(Java Authentication and Authorization Service)實(shí)現(xiàn)了一個(gè)Java版本的標(biāo)準(zhǔn)Pluggable Authentication Module(PAM)的框架。JAAS可用來進(jìn)行用戶身份的鑒定,從而能夠可靠并安全地確定誰在執(zhí)行Java代碼。同時(shí)JAAS還能通過對(duì)用戶進(jìn)行授 權(quán),實(shí)現(xiàn)基于用戶的訪問控制。

    · JACC

    ????? JACC(Java Authorization Service Provider Contract for Containers)在J2EE應(yīng)用服務(wù)器和特定的授權(quán)認(rèn)證服務(wù)器之間定義了一個(gè)連接的協(xié)約,以便將各種授權(quán)認(rèn)證服務(wù)器插入到J2EE產(chǎn)品中去。

    · JAX-RPC

    ????? 通過使用JAX-RPC(Java API for XML-based RPC),已有的Java類或Java應(yīng)用都能夠被重新包裝,并以Web Services的形式發(fā)布。JAX-RPC提供了將RPC參數(shù)(in/out)編碼和解碼的API,使開發(fā)人員可以方便地使用SOAP消息來完成RPC 調(diào)用。同樣,對(duì)于那些使用EJB(Enterprise JavaBeans)的商業(yè)應(yīng)用而言,同樣可以使用JAX-RPC來包裝成Web服務(wù),而這個(gè)Web Servoce的WSDL界面是與原先的EJB的方法是對(duì)應(yīng)一致的。JAX-RPC為用戶包裝了Web服務(wù)的部署和實(shí)現(xiàn),對(duì)Web服務(wù)的開發(fā)人員而言, SOAP/WSDL變得透明,這有利于加速Web服務(wù)的開發(fā)周期。

    · JAXR

    ????? JAXR(Java API for XML Registries)提供了與多種類型注冊(cè)服務(wù)進(jìn)行交互的API。JAXR運(yùn)行客戶端訪問與JAXR規(guī)范相兼容的Web Servcices,這里的Web Services即為注冊(cè)服務(wù)。一般來說,注冊(cè)服務(wù)總是以Web Services的形式運(yùn)行的。JAXR支持三種注冊(cè)服務(wù)類型:JAXR Pluggable Provider、Registry-specific JAXR Provider、JAXR Bridge Provider(支持UDDI Registry和ebXML Registry/Repository等)。

    · SAAJ

    ????? SAAJ(SOAP with Attachemnts API for Java)是JAX-RPC的一個(gè)增強(qiáng),為進(jìn)行低層次的SOAP消息操縱提供了支持。

    四. J2EE 的結(jié)構(gòu)

    ????? 這種基于組件,具有平臺(tái)無關(guān)性的J2EE 結(jié)構(gòu)使得J2EE 程序的編寫十分簡(jiǎn)單,因?yàn)闃I(yè)務(wù)邏輯被封裝成可復(fù)用的組件,并且J2EE 服務(wù)器以容器的形式為所有的組件類型提供后臺(tái)服務(wù). 因?yàn)槟悴挥米约洪_發(fā)這種服務(wù), 所以你可以集中精力解決手頭的業(yè)務(wù)問題.

    ????? 容器和服務(wù)

    ????? 容器設(shè)置定制了J2EE服務(wù)器所提供得內(nèi)在支持,包括安全,事務(wù)管理,JNDI(Java Naming and Directory Interface)尋址,遠(yuǎn)程連接等服務(wù),以下列出最重要的幾種服務(wù):

    ????? J2EE安全(Security)模型可以讓你配置 web 組件或enterprise bean ,這樣只有被授權(quán)的用戶才能訪問系統(tǒng)資源. 每一客戶屬于一個(gè)特別的角色,而每個(gè)角色只允許激活特定的方法。你應(yīng)在enterprise bean的布置描述中聲明角色和可被激活的方法。由于這種聲明性的方法,你不必編寫加強(qiáng)安全性的規(guī)則。

    ????? J2EE 事務(wù)管理(Transaction Management)模型讓你指定組成一個(gè)事務(wù)中所有方法間的關(guān)系,這樣一個(gè)事務(wù)中的所有方法被當(dāng)成一個(gè)單一的單元. 當(dāng)客戶端激活一個(gè)enterprise bean中的方法,容器介入一管理事務(wù)。因有容器管理事務(wù),在enterprise bean中不必對(duì)事務(wù)的邊界進(jìn)行編碼。要求控制分布式事務(wù)的代碼會(huì)非常復(fù)雜。你只需在布置描述文件中聲明enterprise bean的事務(wù)屬性,而不用編寫并調(diào)試復(fù)雜的代碼。容器將讀此文件并為你處理此enterprise bean的事務(wù)。

    ????? JNDI 尋址(JNDI Lookup)服務(wù)向企業(yè)內(nèi)的多重名字和目錄服務(wù)提供了一個(gè)統(tǒng)一的接口,這樣應(yīng)用程序組件可以訪問名字和目錄服務(wù).

    ????? J2EE遠(yuǎn)程連接(Remote Client Connectivity)模型管理客戶端和enterprise bean間的低層交互. 當(dāng)一個(gè)enterprise bean創(chuàng)建后, 一個(gè)客戶端可以調(diào)用它的方法就象它和客戶端位于同一虛擬機(jī)上一樣.

    ????? 生存周期管理(Life Cycle Management)模型管理enterprise bean的創(chuàng)建和移除,一個(gè)enterprise bean在其生存周期中將會(huì)歷經(jīng)幾種狀態(tài)。容器創(chuàng)建enterprise bean,并在可用實(shí)例池與活動(dòng)狀態(tài)中移動(dòng)他,而最終將其從容器中移除。即使可以調(diào)用enterprisebean的create及remove方法,容 器也將會(huì)在后臺(tái)執(zhí)行這些任務(wù)。

    五、企業(yè)級(jí)應(yīng)用示例

    ????? 下面我們通過假設(shè)一個(gè)企業(yè)應(yīng)用的J2EE實(shí)現(xiàn),來了解各種組件和服務(wù)的應(yīng)用。假設(shè)應(yīng)用對(duì)象是計(jì)算機(jī)產(chǎn)品的生產(chǎn)商/零售商的銷售系統(tǒng),這個(gè)銷售系統(tǒng)能夠通過自己的網(wǎng)站發(fā)布產(chǎn)品信息,同時(shí)也能將產(chǎn)品目錄傳送給計(jì)算機(jī)產(chǎn)品交易市場(chǎng)。銷售系統(tǒng)能夠在線接受訂單(來自自己的Web網(wǎng)站或者來自計(jì)算機(jī)產(chǎn)品交易市場(chǎng)),并隨后轉(zhuǎn)入內(nèi)部企業(yè)管理系統(tǒng)進(jìn)行相關(guān)的后續(xù)處理。

    ????? 參見圖1,這個(gè)企業(yè)應(yīng)用可以這種方式架構(gòu)。該企業(yè)應(yīng)用的核心是產(chǎn)品目錄管理和產(chǎn)品定購管理這兩個(gè)業(yè)務(wù)邏輯,使用EJB加以實(shí)現(xiàn),并部署在EJB容器中。由于產(chǎn)品目錄和定購信息都需要持久化,因此使用JDBC連接數(shù)據(jù)庫,并使用JTA來完成數(shù)據(jù)庫存取事務(wù)。


    圖1 J2EE應(yīng)用示例

    ????? 然后使用JSP/Servlet來實(shí)現(xiàn)應(yīng)用的Web表現(xiàn):在線產(chǎn)品目錄瀏覽和在線定購。為了將產(chǎn)品目錄發(fā)送給特定的交易市場(chǎng),使用JMS實(shí)現(xiàn)異步的基于消 息的產(chǎn)品目錄傳輸。為了使得更多的其它外部交易市場(chǎng)能夠集成產(chǎn)品目錄和定購業(yè)務(wù),需要使用Web Services技術(shù)包裝商業(yè)邏輯的實(shí)現(xiàn)。由于產(chǎn)品定購管理需要由公司內(nèi)部雇員進(jìn)行處理,因此需要集成公司內(nèi)部的用戶系統(tǒng)和訪問控制服務(wù)以方便雇員的使 用,使用JACC集成內(nèi)部的訪問控制服務(wù),使用JNDI集成內(nèi)部的用戶目錄,并使用JAAS進(jìn)行訪問控制。由于產(chǎn)品訂購事務(wù)會(huì)觸發(fā)后續(xù)的企業(yè)ERP系統(tǒng)的 相關(guān)操作(包括倉儲(chǔ)、財(cái)務(wù)、生產(chǎn)等),需要使用JCA連接企業(yè)ERP。

    ????? 最后為了將這個(gè)應(yīng)用納入到企業(yè)整體的系統(tǒng)管理體系中去,使用Application Client架構(gòu)了一個(gè)管理客戶端(與其它企業(yè)應(yīng)用管理應(yīng)用部署在一臺(tái)機(jī)器上),并通過JMX管理這個(gè)企業(yè)應(yīng)用。

    ????????????????????????????? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ( 摘自中科永聯(lián) 高級(jí)技術(shù)培訓(xùn)中心 )

    posted @ 2007-03-14 16:58 Bill111 閱讀(325) | 評(píng)論 (0)編輯 收藏
    JUnit測(cè)試的理由

    編寫JUnit測(cè)試的理由和幾條測(cè)試習(xí)慣

    ?moneyice 發(fā)表于 2006 年 06 月 19 日

    編寫JUnit測(cè)試的理由

    ·JUnit在保證質(zhì)量的同時(shí)提高代碼編寫速度
    看起來不可思議,但是事實(shí)。使用JUnit后,花在調(diào)試的時(shí)間就會(huì)更少,在改變代碼的時(shí)候更有信心。有了這種信心,你可以在重構(gòu)代碼,添加新特性的時(shí)候更有闖勁。
    如 果沒有測(cè)試,那么重構(gòu)或者添加新特性很容易成為妄想,因?yàn)槟銦o法知曉什么地方會(huì)被破壞掉。如果擁有完善的測(cè)試套,在改變代碼后,立即運(yùn)行測(cè)試,這樣就可以 得到信心,你的改變沒有破壞任何東西。當(dāng)運(yùn)行測(cè)試時(shí),如果檢測(cè)出bug,因?yàn)榇a在腦海里還很清楚,所以bug很容易被解決。用JUnit編寫測(cè)試,可以 使你的代碼編寫達(dá)到極限速度,而且快速定位bug。
    ·JUnit 及其簡(jiǎn)單
    測(cè)試應(yīng)該很簡(jiǎn)單,這一點(diǎn)很關(guān)鍵。如果測(cè)試太復(fù)雜,花費(fèi)太多時(shí)間,編寫測(cè)試就不太值得了。使用JUnit,你可以快速的寫出測(cè)試代碼來驗(yàn)證程序。隨著軟件的增長(zhǎng)相應(yīng)的增加測(cè)試代碼。
    使用JUnit,運(yùn)行測(cè)試也變得很簡(jiǎn)單而且很快速。
    ·JUnit 驗(yàn)證它們自己的結(jié)果,而且能夠立即反饋
    JUnit測(cè)試能夠自動(dòng)運(yùn)行,它們檢查自身的結(jié)果。運(yùn)行測(cè)試后,你會(huì)立即得到可視化的反饋,測(cè)試通過或者失敗。不需要手工來輸出測(cè)試結(jié)果報(bào)告。
    ·JUnit 測(cè)試可以被組合為不同層次的測(cè)試套
    JUnit測(cè)試可以被整合到測(cè)試套中,測(cè)試套可以包含測(cè)試用例或者其他的測(cè)試套。JUnit測(cè)試的組合行為使你可以聚集一組測(cè)試用例為一個(gè)測(cè)試套,也可以將多個(gè)測(cè)試套組合到一個(gè)測(cè)試套中。你可以運(yùn)行任何一個(gè)層次的測(cè)試套。
    ·編寫 JUnit 測(cè)試代價(jià)很小
    使用JUnit測(cè)試框架,你可以代價(jià)很小的編寫測(cè)試,而且享受著測(cè)試框架提供的便利。寫測(cè)試簡(jiǎn)單到,就是編寫一個(gè)方法,使用一下要測(cè)試的代碼,定義一個(gè)期望的結(jié)果。
    ·JUnit 測(cè)試增強(qiáng)了軟件的穩(wěn)定性。測(cè)試越少,代碼的穩(wěn)定性就越差。測(cè)試驗(yàn)證了軟件的穩(wěn)定性,保證了更改沒有在項(xiàng)目中引起波紋效應(yīng)。

    JUnit 測(cè)試是程序員的測(cè)試。JUnit測(cè)試是用來提高程序員的效率和代碼質(zhì)量。與功能測(cè)試不同,功能測(cè)試是將整個(gè)系統(tǒng)視作黑盒,從整體保證軟件有效。單元測(cè)試是 用來測(cè)試實(shí)現(xiàn)基本功能的代碼塊。程序員編寫并維護(hù)JUnit測(cè)試代碼。當(dāng)一次開發(fā)迭代完成,測(cè)試代碼也要同步的更新,作為對(duì)此次迭代的質(zhì)量驗(yàn)證。

    測(cè)試習(xí)慣

    編寫JUnit測(cè)試時(shí),確保以下牢記在心:
    ·只用測(cè)試到的地方才會(huì)運(yùn)行的很好。
    ·測(cè)一點(diǎn),寫一點(diǎn), 測(cè)一點(diǎn),寫一點(diǎn)...
    ·取保所有的測(cè)試都要執(zhí)行。
    ·最少每天一次運(yùn)行所有的測(cè)試用例 (或一晚)。
    ·為最有破壞可能性的代碼編寫完善的測(cè)試。
    ·為你最有可能獲得回報(bào)的地方編寫測(cè)試。
    ·如果你總是在調(diào)試某個(gè)地方,編寫JUnit測(cè)試自動(dòng)驗(yàn)證結(jié)果來代替調(diào)試。
    ·如果有bug被報(bào)告,編寫測(cè)試來暴露這個(gè)bug。
    ·有人讓你幫助調(diào)試的時(shí)候,幫助他寫測(cè)試用例。
    ·在編寫代碼之前編寫單元測(cè)試代碼,只有測(cè)試失敗的時(shí)候才寫新代碼。寫最簡(jiǎn)單的新代碼讓測(cè)試通過。

    ?

    posted @ 2007-03-13 14:18 Bill111 閱讀(1678) | 評(píng)論 (0)編輯 收藏
    主站蜘蛛池模板: 亚洲乱码国产乱码精品精| 一级白嫩美女毛片免费| 亚洲av无码专区国产乱码在线观看| 午夜一级免费视频| 国内精自视频品线六区免费 | 日韩黄色免费观看| 久草免费在线观看视频| 免费黄色电影在线观看| 国产日韩久久免费影院| 亚洲a∨无码精品色午夜| 久久亚洲精品专区蓝色区| 亚洲精品视频在线免费| 亚洲AV日韩AV永久无码绿巨人| 最新国产AV无码专区亚洲| 亚洲欧洲日本在线| www.亚洲精品| 又粗又黄又猛又爽大片免费 | 亚洲日韩精品无码专区| 亚洲av永久无码精品天堂久久| 久久久无码精品亚洲日韩按摩| 亚洲精品无码久久一线| 亚洲色成人WWW永久网站| 精品亚洲成α人无码成α在线观看 | 四虎成人免费网址在线| 99久久免费国产精品特黄| 两性刺激生活片免费视频| 亚洲综合免费视频| 免费A级毛片无码A∨免费| 18女人腿打开无遮掩免费| 久久w5ww成w人免费| 在线观看www日本免费网站| 91热成人精品国产免费| 日本亚洲免费无线码| 人禽杂交18禁网站免费| 毛片免费全部播放一级| 嫩草影院在线免费观看| 日韩免费a级在线观看| 免费夜色污私人影院在线观看| 亚洲国产精品狼友中文久久久| 国产精品亚洲mnbav网站 | 国产啪精品视频网站免费尤物|