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

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

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

    隨筆:93 文章:11 評(píng)論:22 引用:0
    首頁 發(fā)新隨筆
    發(fā)新文章 聯(lián)系 聚合管理

         摘要:   Java接口和Java抽象類     在沒有好好地研習(xí)面向?qū)ο笤O(shè)計(jì)的設(shè)計(jì)模式之前,我對(duì)Java接口和Java抽象類的認(rèn)識(shí)還是很模糊,很不可理解。         剛學(xué)Java語言時(shí),就很難理解為什么要有接口這個(gè)概念,雖說是可以實(shí)現(xiàn)所謂的多繼承,可一個(gè)只有方法名,沒有方法體的東西,...  閱讀全文
    posted @ 2009-05-20 10:41 redcoatjk 閱讀(651) | 評(píng)論 (0)編輯 收藏
     
     

    Java語言中, abstract class interface 是支持抽象類定義的兩種機(jī)制。正是由于這兩種機(jī)制的存在,才賦予了Java強(qiáng)大的 面向?qū)ο竽芰Α?/span>abstract classinterface之間在對(duì)于抽象類定義的支持方面具有很大的相似性,甚至可以相互替換,因此很多開發(fā)者在進(jìn)行抽象類定義時(shí)對(duì)于abstract classinterface的選擇顯得比較隨意。其實(shí),兩者之間還是有很大的區(qū)別的,對(duì)于它們的選擇甚至反映出對(duì)于問題領(lǐng)域本質(zhì)的理解、對(duì)于設(shè)計(jì)意圖的理解是否正確、合理。本文將對(duì)它們之間的區(qū)別進(jìn)行一番剖析,試圖給開發(fā)者提供一個(gè)在二者之間進(jìn)行選擇的依據(jù)。


    理解抽象類

    abstract class
    interfaceJava語言中都是用來進(jìn)行抽象類(本文 中的抽象類并非從abstract class翻譯而來,它表示的是一個(gè)抽象體,而abstract classJava語言中用于定義抽象類的一種方法,請(qǐng)讀者注意區(qū)分)定義的,那么什么是抽象類,使用抽象類能為我們帶來什么好處呢?

    面向?qū)ο蟮母拍钪校覀冎浪械膶?duì)象都是通過類來描繪的,但是反過來卻不是這樣。并不是所有的類都是用來描繪對(duì)象的,如果一個(gè)類中沒有包含足夠的信息來描繪一個(gè)具體的對(duì)象,這樣的類就是抽象類。抽象類往往用來表征我們?cè)趯?duì)問題領(lǐng)域進(jìn)行分析、設(shè)計(jì)中得出的抽象概念,是對(duì)一系列看上去不同,但是本質(zhì)上相同的具體概念的抽象。比如:如果我們進(jìn)行一個(gè)圖形編輯軟件的開發(fā),就會(huì)發(fā)現(xiàn)問題領(lǐng)域存在著圓、三角形這樣一些具體概念,它們是不同的,但是它們又都屬于形狀這樣一個(gè)概念,形狀這個(gè)概念在問題領(lǐng)域是不存在的,它就是一個(gè)抽象概念。正是因?yàn)槌橄蟮母拍钤趩栴}領(lǐng)域沒有對(duì)應(yīng)的具體概念,所以用以表征抽象概念的抽象類是不能夠?qū)嵗摹?/span>

    在面向?qū)ο箢I(lǐng)域,抽象類主要用來進(jìn)行類型隱藏。 我們可以構(gòu)造出一個(gè)固定的一組行為的抽象描述,但是這組行為卻能夠有任意個(gè)可能的具體實(shí)現(xiàn)方式。這個(gè)抽象描述就是抽象類,而這一組任意個(gè)可能的具體實(shí)現(xiàn)則表現(xiàn)為所有可能的派生類。模塊可以操作一個(gè)抽象體。由于模塊依賴于一個(gè)固定的抽象體,因此它可以是不允許修改的;同時(shí),通過從這個(gè)抽象體派生,也可擴(kuò)展此模塊的行為功能。熟悉OCP的讀者一定知道,為了能夠?qū)崿F(xiàn)面向?qū)ο笤O(shè)計(jì)的一個(gè)最核心的原則OCP(Open-Closed Principle),抽象類是其中的關(guān)鍵所在。

    從語法定義層面看abstract class interface

    在語法層面,Java語言對(duì)于abstract classinterface給出了不同的定義方式,下面以定義一個(gè)名為Demo的抽象類為例來說明這種不同。

    使用abstract class的方式定義Demo抽象類的方式如下:
    抽象類
    abstract class Demo
    abstract void method1();
    abstract void method2();



    使用interface的方式定義Demo抽象類的方式如下:
    接口
    interface Demo{
    void method1();
    void method2();

    }


    abstract class方式中,Demo可以有自己的數(shù)據(jù)成員,也可以有非 abstract的成員方法,(抽象類可以有非抽象的方法,有抽象方法的類一定要是抽象類)

     

    而在interface方式的實(shí)現(xiàn)中,Demo只能夠有靜態(tài)不能被修改的數(shù)據(jù)成員(也就是必須是static final 的,不過在interface中一般不定義數(shù)據(jù)成員),所有的成員方法都是abstract從某種意義上說,interface是一種特殊形式的 abstract class

    從編程的角度來看,abstract classinterface都可以用來實(shí)現(xiàn) "design by contract" 的思想。但是在具體的使用上面還是有一些區(qū)別的。
    區(qū)別:
    首先,abstract class Java 語言中表示的是一種繼承關(guān)系,一個(gè)類只能使用一次繼承關(guān)系(因?yàn)?/span>Java不支持多繼承 -- 轉(zhuǎn)注)。但是,一個(gè)類卻可以實(shí)現(xiàn)多個(gè)interface。也許,這是Java語言的設(shè)計(jì)者在考慮Java對(duì)于多重繼承的支持方面的一種折中考慮吧。 (即實(shí)現(xiàn)方式不同)

    其次,在abstract class的定義中,我們可以賦予方法的默認(rèn)行為。但是在interface的定義中,方法卻不能擁有默認(rèn)行為,為了繞過這個(gè)限制,必須使用委托,但是這會(huì)增加一些復(fù)雜性,有時(shí)會(huì)造成很大的麻煩。

    抽象類中不能定義默認(rèn)行為還存在另一個(gè)比較嚴(yán)重的問題,那就是可能會(huì)造成維護(hù)上的麻煩。因 為如果后來想修改類的界面(一般通過 abstract class 或者interface來表示)以適應(yīng)新的情況(比如,添加新的方法或者給已用的方法中添加新的參數(shù))時(shí),就會(huì)非常的麻煩,可能要花費(fèi)很多的時(shí)間(對(duì)于派生類很多的情況,尤為如此)。但是如果界面是通過abstract class來實(shí)現(xiàn)的,那 么可能就只需要修改定義在abstract class中的默認(rèn)行為就可以了。

    同樣,如果不能在抽象類中定 義默認(rèn)行為,就會(huì)導(dǎo)致同樣的方法實(shí)現(xiàn)出現(xiàn)在該抽象類的每一個(gè)派生類中,違反了 "one ruleone place" 原則,造成代碼重復(fù),同樣不利于以后的維護(hù)。因此,在abstract classinterface間進(jìn)行選擇時(shí)要非常的小心。

    從設(shè)計(jì)理念層面看 abstract class interface

    上面主要從語法定義和編程的角度論述了abstract classinterface的區(qū)別,這些層面的區(qū)別是比較低層次的、非本質(zhì)的。本小節(jié)將從另一個(gè)層面:abstract classinterface所反映出的設(shè)計(jì)理念,來分析一下二者的區(qū)別。作者認(rèn)為,從這個(gè)層面進(jìn)行分析才能理解二者概念的本質(zhì)所在。

    前面已經(jīng)提到過,abstract classJava語言中體現(xiàn)了一種繼承關(guān)系,要想使得繼承關(guān)系合理,父類和派生類之間必須存在"is-a"關(guān)系,即父類和派生類在概念本質(zhì)上應(yīng)該是相同的。對(duì)于interface來說則不然,并不要求 interface的實(shí)現(xiàn)者和interface定義在概念本質(zhì)上是一致的,僅僅是實(shí)現(xiàn)了interface定義的契約而已。為了使論述便于理解,下面將通過一個(gè)簡(jiǎn)單的實(shí)例進(jìn)行說明。

    考慮這樣一個(gè)例子,假設(shè)在我們的問題領(lǐng)域中有一個(gè)關(guān)于Door的抽象概念,該Door具有執(zhí)行兩個(gè)動(dòng)作openclose,此時(shí)我們可以通過abstract class或者interface來定義一個(gè)表示該抽象概念的類型,定義方式分別如下所示:

    使用abstract class方式定義Door

    abstract class Door{
    abstract void open();
    abstract void close()

    }

    使用interface方式定義Door

    interface Door{
    void open();
    void close();
    }

    其他具體的Door類型可以extends使用abstract class方式定義的Door或者implements使用interface方式定義的Door。看起來好像使用abstract classinterface沒有大的區(qū)別。

    如果現(xiàn)在要求Door還要具有報(bào)警的功能。我們?cè)撊绾卧O(shè)計(jì)針對(duì)該例子的類結(jié)構(gòu)呢(在本例中, 主要是為了展示 abstract class interface 反映在設(shè)計(jì)理念上的區(qū)別,其他方面無關(guān)的問題都做了簡(jiǎn)化或者忽略)?下面將羅列出可能的解決方案,并從設(shè)計(jì)理念層面對(duì)這些不同的方案進(jìn)行分析。

    解決方案一:

    簡(jiǎn)單的在Door的定義中增加一個(gè)alarm方法,如下:

    abstract class Door{
    abstract void open();
    abstract void close()

    abstract void alarm();
    }

    或者

    interface Door{
    void open();
    void close();
    void alarm();
    }

    那么具有報(bào)警功能的AlarmDoor的定義方式如下:

    class AlarmDoor extends Door{
    void open(){…}
    void close(){…}
    void alarm(){…}
    }

    或者

    class AlarmDoor implements Door

    void open(){…}
    void close(){…}
    void alarm(){…}


    這種方法違反了面向?qū)ο笤O(shè)計(jì)中的一個(gè)核心原則 ISP (Interface Segregation Principle),在Door的定義中把Door概念本身固有的行為方法和另外一個(gè)概念"報(bào)警器"的行為方法混在了一起。這樣引起的一個(gè)問題是那些僅僅依賴于Door這個(gè)概念的模塊會(huì)因?yàn)?/span>"報(bào)警器"這個(gè)概念的改變(比如:修改alarm方法的參數(shù))而改變,反之依然。

    解決方案二:

    既然openclosealarm屬于兩個(gè)不同的概念,根據(jù)ISP原則應(yīng)該把它們分別 定義在代表這兩個(gè)概念的抽象類中。定義方式有:這兩個(gè)概念都使用 abstract class 方式定義;兩個(gè)概念都使用interface方式定義;一個(gè)概念 使用 abstract class 方式定義,另一個(gè)概念使用interface方式定義。

    顯然,由于Java語言不支持多重繼承,所以兩個(gè)概念都使用abstract class方式定義是不可行的。后面兩種方式都是可行的,但是對(duì)于它們的選擇卻反映出對(duì)于問題領(lǐng)域中的概念本質(zhì)的理解、對(duì)于設(shè)計(jì)意圖的反映是否正確、合理。我們一一來分析、說明。

    如果兩個(gè)概念都使用interface方式來定義,那么就反映出兩個(gè)問題:1、我們可能沒有理解清楚問題領(lǐng)域,AlarmDoor在概念本質(zhì)上到底是Door還是報(bào)警器?2、如果我們對(duì)于問題領(lǐng)域的理解沒有問題,比如:我們通過對(duì)于問題領(lǐng)域的分析發(fā)現(xiàn)AlarmDoor在概念本質(zhì)上和Door是一致的,那么我們?cè)趯?shí)現(xiàn)時(shí)就沒有能夠正確的揭示我們的設(shè)計(jì)意圖,因?yàn)樵谶@兩個(gè)概念的定義上(均使用 interface方式定義)反映不出上述含義。

    如果我們對(duì)于問題領(lǐng)域的理解是:AlarmDoor在概念本質(zhì)上是Door,同時(shí)它 有具有報(bào)警的功能。我們?cè)撊绾蝸碓O(shè)計(jì)、實(shí)現(xiàn)來明確的反映出我們的意思呢?前面已經(jīng)說過,abstract classJava語言中表示一種繼承關(guān)系,而繼承關(guān)系 在本質(zhì)上是"is-a"關(guān)系。所以對(duì)于Door這個(gè)概念,我們應(yīng)該使用abstarct class方式來定義。另外,AlarmDoor又具有報(bào)警功能,說明它又能夠完成報(bào)警概念中定義的行為,所以報(bào)警概念可以通過interface方式定義。如下所示:

    abstract class Door{
    abstract void open();
    abstract void close()

    }
    interface Alarm{
    void alarm();
    }
    class Alarm Door extends Door implements Alarm{
    void open(){…}
    void close(){…}
    void alarm(){…}
    }

    這種實(shí)現(xiàn)方式基本上能夠明確的反映出我們對(duì)于問題領(lǐng)域的理解,正確的揭示我們的設(shè)計(jì)意圖。 實(shí)abstract class表示的是"is-a"關(guān)系,interface表示的是"like-a"關(guān)系,大家在選擇時(shí)可以作為一個(gè)依據(jù),當(dāng)然這是建立在對(duì)問題領(lǐng)域的理解上的,比如:如果我們認(rèn)為AlarmDoor在概念本質(zhì)上是報(bào)警器,同時(shí)又具有Door的功能,那么上述的定義方式就要反過來了。

    小結(jié)

    1.abstract class
    Java 語言中表示的是一種繼承關(guān)系,一個(gè)類只能使用一次繼承關(guān)系。但是,一個(gè)類卻可以實(shí)現(xiàn)多個(gè)interface

    2.
    abstract class 中可以有自己的數(shù)據(jù)成員,也可以有非abstarct的成員方法.

    interface中,只能夠有靜態(tài)的不能被修改的數(shù)據(jù)成員(也就是必須是 static final的,不過在 interface中一般不定義數(shù)據(jù)成員),所有的成員方法都是abstract的。

    3.abstract classinterface所反映出的設(shè)計(jì)理念不同。其實(shí)abstract class表示的是"is-a"關(guān)系,interface表示的是"like-a"關(guān)系。

    4.
    實(shí)現(xiàn)抽象類和接口的類必須實(shí)現(xiàn)其中的所有方法。抽象類中可以有非抽象方法接口中則不能有實(shí)現(xiàn)方法。

    5.
    接口中定義的變量默認(rèn)是public static final 型,且必須給其初值,所以實(shí)現(xiàn)類中不能重新定義,也不能改變其值。

    6.
    抽象類中的變量默認(rèn)是 friendly 型,其值可以在子類中重新定義,也可以重新賦值。

    7.
    接口中的方法默認(rèn)都是 public,abstract 類型的

    結(jié)論

    abstract class
    interface Java語言中的兩種定義抽象類的方式,它們之間有很大的相似性。但是對(duì)于它們的選擇卻又往往反映出對(duì)于問題領(lǐng)域中的概念本質(zhì)的理解、對(duì)于設(shè)計(jì)意圖的反映是否正確、合理,因?yàn)樗鼈儽憩F(xiàn)了概念間的不同的關(guān)系(雖然都能夠?qū)崿F(xiàn)需求的功能)。這其實(shí)也是語言的一種的慣用法,希望讀者朋友能夠細(xì)細(xì)體會(huì)。

     

    ---

      補(bǔ)充一個(gè): 接口可以extends接口 這個(gè)稱之為接口的擴(kuò)充

    posted @ 2009-05-19 09:55 redcoatjk 閱讀(117) | 評(píng)論 (0)編輯 收藏
     
    Java 5 添加了許多強(qiáng)大的語言特性:泛型、枚舉、注釋、自動(dòng)裝箱和增強(qiáng)的 for 循環(huán)。但是,許多工作組仍然被綁定在 JDK 1.4 或以前的版本上,可能需要花些時(shí)間才能使用新版本。但是,這些開發(fā)人員仍然可以使用這些功能強(qiáng)大的語言特性,同時(shí)在 JVM 早期版本上部署。

      隨著最新的 Java 6.0 的發(fā)布,您可能認(rèn)為 Java 5 的語言特性是 “舊的新特性”。但是即使在現(xiàn)在,當(dāng)我詢問開發(fā)人員在開發(fā)時(shí)使用的 Java 平臺(tái)的版本時(shí),通常只有一半人在使用 Java 5 —— 另一半則只能表示羨慕。他們非常希望使用 Java 5 中添加的語言特性,例如泛型和注釋,但仍有許多因素妨礙他們這樣做。

      不能利用 Java 5 特性的開發(fā)人員包括那些開發(fā)組件、庫或應(yīng)用程序框架的開發(fā)人員。因?yàn)樗麄兊目蛻艨赡苋匀辉谑褂?JDK 1.4 或以前的版本,并且 JDK 1.4 或以前的 JVM 不能裝載用 Java 5 編譯的類,所以使用 Java 5 語言特性會(huì)把他們的客戶基數(shù)限制在已經(jīng)遷移到 Java 5 的公司。

      另一類經(jīng)常避免使用 Java 5 的開發(fā)人員是使用 Java EE 的開發(fā)人員。許多開發(fā)團(tuán)隊(duì)不愿在 Java EE 1.4 及以前的版本上使用 Java 5,因?yàn)閾?dān)心其應(yīng)用服務(wù)器的廠商不支持 Java 5。這些開發(fā)人員要遷移到 Java EE 5 可能還有待時(shí)日。除了 Java EE 5 和 Java SE 5 規(guī)范之間的滯后,商業(yè) Java EE 5 容器沒有必要在規(guī)范剛剛制定好就能使用,企業(yè)也沒有必要在應(yīng)用服務(wù)器出現(xiàn)下一個(gè)版本時(shí)就立即升級(jí),而且在升級(jí)應(yīng)用服務(wù)器之后,可能還需要花些時(shí)間在新平臺(tái)上驗(yàn)證其應(yīng)用程序。

      Java 5 語言特性的實(shí)現(xiàn)

      Java 5 中添加的語言特性 —— 泛型、枚舉、注釋、自動(dòng)裝箱和增強(qiáng)的 for 循環(huán) —— 不需要修改 JVM 的指令集,幾乎全部是在靜態(tài)編譯器(javac)和類庫中實(shí)現(xiàn)的。當(dāng)編譯器遇到使用泛型的情況時(shí),會(huì)試圖檢查是否保證了類型安全(如果不能檢查,會(huì)發(fā)出 “unchecked cast”),然后發(fā)出字節(jié)碼,生成的字節(jié)碼與等價(jià)的非泛型代碼、類型強(qiáng)制轉(zhuǎn)換所生成的字節(jié)碼相同。類似的,自動(dòng)裝箱和增強(qiáng)的 for 循環(huán)僅僅是等價(jià)的 “語法糖”,只是更復(fù)雜的語法和枚舉被編譯到普通的類中。

      在理論上,可以采用 javac 生成的類文件,在早期的 JVM 中裝入它們,這實(shí)際上正是 JSR 14(負(fù)責(zé)泛型的 Java Community Process 工作組)的成立目的。但是,其他問題(例如注釋的保持)迫使類文件的版本在 Java 1.4 和 Java 5 之間變化,因此妨礙了早期 JVM 中裝入用 Java 5 編譯的代碼。而且,在 Java 5 中添加的有些語言特性依賴于 Java 5 庫。如果用 javac -target 1.5 編譯類,并試圖將它裝入早期 JVM 中,就會(huì)得到 UnsupportedClassVersionError,因?yàn)?-target 1.5 選項(xiàng)生成的類的類文件版本是 49,而 JDK 1.4 只支持版最大為 48 的類文件版本。

      for-each 循環(huán)

      增強(qiáng)的 for 循環(huán)有時(shí)叫做 for-each 循環(huán),編譯器編譯它的時(shí)候,情形與程序員提供舊式 for 循環(huán)一樣。for-each 循環(huán)能夠迭代數(shù)組或集合中的元素。清單 1 顯示了用 for-each 在集合上迭代的語法:

      清單 1. for-each 循環(huán)

      Collection fooCollection = ...
      for (Foo f : fooCollection) {
      doSomething(f);
      }

      編譯器把這個(gè)代碼轉(zhuǎn)換成等價(jià)的基于迭代器的循環(huán),如清單 2 所示:

      清單 2. 清單 1 基于迭代器的等價(jià)循環(huán)

      for (Iterator iter=f.iterator(); f.hasNext();) {
      Foo f = iter.next();
      doSomething(f);
      }

      編譯器如何知道提供的參數(shù)有一個(gè) iterator() 方法呢? javac 編譯器的設(shè)計(jì)者可能已經(jīng)內(nèi)置了對(duì)集合框架的理解,但是這種方法有些不必要的限制。所以,創(chuàng)建了一個(gè)新的接口 java.lang.Iterable(請(qǐng)參閱清單 3 ),并翻新集合類使其實(shí)現(xiàn) Iterable 接口。這樣,不是在核心集合框架上構(gòu)建的容器類也能利用新的 for-each 循環(huán)。但是這樣做會(huì)形成對(duì) Java 5 類庫的依賴,因?yàn)樵?JDK 1.4 中沒有 Iterable。

      清單 3. Iterable 接口

      public interface Iterable {
      Iterator iterator();
      }

    枚舉和自動(dòng)裝箱

      正像 for-each 循環(huán)一樣,枚舉也要求來自類庫的支持。當(dāng)編譯器遇到枚舉類型時(shí),生成的類將擴(kuò)展庫類 java.lang.Enum。但是,同 Iterable 一樣,在 JDK 1.4 類庫中也沒有 Enum 類。

      類似的,自動(dòng)裝箱依賴于添加到原始包裝器類(例如 Integer)的 valueOf() 方法。當(dāng)裝箱需要從 int 轉(zhuǎn)換到 Integer 時(shí),編譯器并不調(diào)用 new Integer(int),而是生成對(duì) Integer.valueOf(int) 的調(diào)用。valueOf() 方法的實(shí)現(xiàn)利用 享元(flyweight)模式 為常用的整數(shù)值緩存 Integer 對(duì)象(Java 6 的實(shí)現(xiàn)緩存從 -128 到 127 的整數(shù)),由于消除了冗余的實(shí)例化,可能會(huì)提高性能。而且,就像 Iterable 和 Enum 一樣,valueOf() 方法在 JDK 1.4 類庫中也不存在。

      變長參數(shù)

      當(dāng)編譯器遇到用變長參數(shù)列表定義的方法時(shí),會(huì)把其轉(zhuǎn)換成包含正確組件類型數(shù)組的方法;當(dāng)編譯器遇到帶有變長參數(shù)列表方法的調(diào)用時(shí),就把參數(shù)裝進(jìn)數(shù)組。

      注釋

      定義了注釋的之后,可以用 @Retention 對(duì)它進(jìn)行注釋,它可以決定編譯器對(duì)使用這個(gè)注釋的類、方法或字段執(zhí)行什么處理。已經(jīng)定義的保持策略有 SOURCE (在編譯時(shí)舍棄注釋數(shù)據(jù))、CLASS (在類文件中記錄注釋)或 RUNTIME (在類文件中記錄注釋,并在運(yùn)行時(shí)保留注釋,這樣就可以反射地訪問它們了)。

      其他的庫依賴關(guān)系

      在 Java 5 之前,當(dāng)編譯器遇到嘗試連接兩個(gè)字符串的情況時(shí),會(huì)使用幫助器類 StringBuffer 執(zhí)行連接。在 Java 5 及以后的版本中,轉(zhuǎn)而調(diào)用新的 StringBuilder 類,JDK 1.4 及以前的類庫中不存在該類。

      訪問 Java 5 特性

      因?yàn)檎Z言特性對(duì)庫支持的依賴,即使使用 Java 5 編譯器生成的類文件能夠裝入早期 JVM 版本,執(zhí)行也會(huì)因?yàn)轭愌b入錯(cuò)誤而失敗。但是,通過對(duì)字節(jié)碼進(jìn)行適當(dāng)轉(zhuǎn)換,仍有可能解決這些問題,因?yàn)檫@些遺漏的類并不包含實(shí)際的新功能。

      JSR 14

      在 Java 泛型規(guī)范(以及其他 Java 5 新添加的語言特性)的開發(fā)期間,在 javac 編譯器中添加了試驗(yàn)性的支持,以便讓它能使用 Java 5 的語言特性,并生成能在 Java 1.4 JVM 上運(yùn)行的字節(jié)碼。雖然這些特性不受支持(甚至是文檔),但許多開源項(xiàng)目都使用了它們,使得開發(fā)人員能使用 Java 5 語言特性編碼,并生成能在早期 JVM 上使用的 JAR 文件。而且,既然 javac 是開源的,那么這個(gè)特性有可能得到第三方的支持。要激活這些特性,可以用 -source 1.5 和 -target jsr14 選項(xiàng)調(diào)用 javac。

      javac 的 JSR 14 目標(biāo)模式使編譯器生成與 Java 5 語言特性對(duì)應(yīng)的 JDK 1.4 兼容字節(jié)碼:

    •   泛型和變長參數(shù):編譯器在泛型出現(xiàn)的地方插入的強(qiáng)制轉(zhuǎn)換不依賴類庫,所以能夠在 Java 5 之前的 JVM 上很好地執(zhí)行。類似的,編譯器在出現(xiàn)變長參數(shù)列表的地方生成的代碼也不依賴類庫。
    •   for-each 循環(huán):當(dāng)?shù)鷶?shù)組時(shí),編譯器生成歸納變量和標(biāo)準(zhǔn)的數(shù)組迭代語法。當(dāng)在 Collection 上迭代時(shí),編譯器生成標(biāo)準(zhǔn)的基于迭代器的語法。當(dāng)在非集合的 Iterable 上迭代時(shí),編譯器生成錯(cuò)誤。
    •   自動(dòng)裝箱:編譯器不生成對(duì)包裝器類的 valueOf() 方法的調(diào)用,而是生成對(duì)構(gòu)造函數(shù)的調(diào)用。
    •   字符串連接:javac 的 JSR 14 目標(biāo)模式使編譯器生成對(duì) StringBuffer 的調(diào)用而不是對(duì) StringBuilder 的調(diào)用。
    •   枚舉:javac JSR 14 目標(biāo)模式對(duì)枚舉沒有特殊支持。嘗試使用枚舉的代碼會(huì)失敗,在尋找 java.lang.Enum 基類時(shí)出現(xiàn) NoClassDefFoundError。

      使用 JSR 14 目標(biāo)模式允許在 “簡(jiǎn)易” 情況下編寫使用泛型、自動(dòng)裝箱和 for-each 循環(huán)的代碼,這對(duì)多數(shù)項(xiàng)目來說可能足夠了。這很方便,如果不支持的話,編譯器會(huì)一次生成基本兼容的字節(jié)碼。

    posted @ 2009-05-19 09:14 redcoatjk 閱讀(326) | 評(píng)論 (0)編輯 收藏
     
    JDK5新特性匯總(與1.4對(duì)照)
     

    1 循環(huán)
    5.0
    1.4
    for (type variable : array){
       body
    }
     
    for (int i = 0; i < array.length; i++){
       type variable = array[i];
       body
    }
    for (type variable : arrayList){
       body
    }
    for (int i = 0; i < arrayList.size(); i++){
       type variable = (type) arrayList.get(i);
       body
    }
     
    2 泛型
    以ArrayList為例,包括創(chuàng)建一個(gè)容器對(duì)象和取得容器內(nèi)對(duì)象操作:
    5.0
    1.4
    ArrayList arrayList =
          new ArrayList()
    ArrayList arrayList =
          new ArrayList();
    arrayList.get(i)
    (Type) arrayList.get(i)
     
    3 自動(dòng)裝箱拆箱
    在JDK5.0以前,在原始類型與相應(yīng)的包裝類之間的轉(zhuǎn)化是不能自動(dòng)完成的。要完成這種轉(zhuǎn)化,需要手動(dòng)調(diào)用包裝類的構(gòu)造函數(shù):
    5.0
    1.4
    Integer wrapper = n;
    Integer wrapper = new Integer(n);
     
    在JDK5.0環(huán)境中,可以自動(dòng)轉(zhuǎn)化,不再需要手工干預(yù):
    5.0
    1.4
    int n = wrapper;
    int n = wrapper.intValue();
     
    4 可變參數(shù)列表
    5.0
    1.4
    method(other params, p1, p2, p3)
    method(other params, new Type[] { p1, p2, p3 })
     
    5 可變的返回類型
    在JDK5.0以前,當(dāng)覆蓋父類方法時(shí),返回類型是不能改變的。現(xiàn)在有新的規(guī)則用于覆蓋方法。如下,一個(gè)典型的例子就是clone()方法:
    5.0
    1.4
    public Employee clone() { ... }
    ...
    Employee cloned = e.clone();
     
    public Object clone() { ... }
    ...
    Employee cloned = (Employee) e.clone();
     
     
     
     
     
     
     
    6 靜態(tài)導(dǎo)入
    靜態(tài)導(dǎo)入功能對(duì)于JDK 5.0以前的版本是不支持的。
    5.0
    1.4
    import static java.lang.Math;
    import static java.lang.System;
    ...
    out.println(sqrt(PI));
     
    System.out.println(Math.sqrt(Math.PI));
     
     
    7 控制臺(tái)輸入
    JDK 5.0先前的版本沒有Scanner類,只能使用JOptionPane.showInputDialog類代替。
    5.0
    1.4
    Scanner in = new Scanner(System.in);System.out.print(prompt);
    int n = in.nextInt();
    double x = in.nextDouble();
    String s = in.nextLine();
    String input = JOptionPane.showInputDialog(prompt);
    int n = Integer.parseInt(input);
    double x = Double.parseDouble(input);
    s = input;
     
     
     
     
     
     
     
     
     
     
    8 格式化輸出
    JDK5.0以前的版本沒有print方法,只能使用NumberFormat.getNumberInstance來代替。
    5.0
    1.4
    System.out.printf("%8.2f", x);
    NumberFormat formatter
       = NumberFormat.getNumberInstance();
    formatter.setMinimumFractionDigits(2);
    formatter.setMaximumFractionDigits(2);
    String formatted = formatter.format(x);
    for (int i = formatted.length(); i < 8; i++)
       System.out.print(" "); System.out.print(formatted);
     
    9 內(nèi)容面板代理
    在JDK5.0先前的版本中,JFrame,JDialog,JApplet等類沒有代理add和setLayout方法。
    5.0
    1.4
    add(component)
    getContentPane().add(component)
    setLayout(manager)
    getContentPane().setLayout(manager)
     
    10 StringBuilder類
    JDK 5.0引入了StringBuilder類,這個(gè)類的方法不具有同步,這使得該類比StringBuffer類更高效。
    5.0
    1.4
    StringBuilder
    StringBuffer
    posted @ 2009-05-19 08:58 redcoatjk 閱讀(1102) | 評(píng)論 (2)編輯 收藏
     

    摘自http://blog.ahnw.gov.cn/user1/itblog/archives/2007/8599.html
    mal(numeric )             同義,用于精確存儲(chǔ)數(shù)值

    float 和 real                      不能精確存儲(chǔ)數(shù)值


    decimal 數(shù)據(jù)類型最多可存儲(chǔ) 38 個(gè)數(shù)字,所有數(shù)字都能夠放到小數(shù)點(diǎn)的右邊。decimal 數(shù)據(jù)類型存儲(chǔ)了一個(gè)準(zhǔn)確(精確)的數(shù)字表達(dá)法;不存儲(chǔ)值的近似值。

    定義 decimal 的列、變量和參數(shù)的兩種特性如下:

    • p   小數(shù)點(diǎn)左邊和右邊數(shù)字之和,不包括小數(shù)點(diǎn)。如 123.45,則 p=5,s=2。

      指定精度或?qū)ο竽軌蚩刂频臄?shù)字個(gè)數(shù)。

    • s

      指定可放到小數(shù)點(diǎn)右邊的小數(shù)位數(shù)或數(shù)字個(gè)數(shù)。

      p 和 s 必須遵守以下規(guī)則:0 <= s <= p <= 38。

    numericdecimal 數(shù)據(jù)類型的默認(rèn)最大精度值是 38。在 Transact-SQL 中,numeric decimal 數(shù)據(jù)類型在功能上等效。

    當(dāng)數(shù)據(jù)值一定要按照指定精確存儲(chǔ)時(shí),可以用帶有小數(shù)的 decimal 數(shù)據(jù)類型來存儲(chǔ)數(shù)字。

    float 和 real 數(shù)據(jù)

    float real 數(shù)據(jù)類型被稱為近似的數(shù)據(jù)類型。在近似數(shù)字?jǐn)?shù)據(jù)類型方面,floatreal 數(shù)據(jù)的使用遵循 IEEE 754 標(biāo)準(zhǔn)。

    近似數(shù)字?jǐn)?shù)據(jù)類型并不存儲(chǔ)為多數(shù)數(shù)字指定的精確值,它們只儲(chǔ)存這些值的最近似值。在很多應(yīng)用程序中,指定值與存儲(chǔ)值之間的微小差異并不明顯。但有時(shí)這些差異也值得引起注意。由于 floatreal 數(shù)據(jù)類型的這種近似性,當(dāng)要求精確的數(shù)字狀態(tài)時(shí),比如在財(cái)務(wù)應(yīng)用程序中,在那些需要舍入的操作中,或在等值核對(duì)的操作中,就不使用這些數(shù)據(jù)類型。這時(shí)就要用 integerdecimalmoneysmallmone 數(shù)據(jù)類型。

    在 WHERE 子句搜索條件中(特別是 = 和 <> 運(yùn)算符),應(yīng)避免使用 floatreal 列。最好限制使用 floatreal 列做 > 或 < 的比較。

    IEEE 754 規(guī)格提供了四種舍入模式:舍入到最接近的值、上舍入、下舍入和舍入到零。Microsoft® SQL Server™ 使用上舍入。所有的數(shù)值必須精確到確定的精度,但會(huì)產(chǎn)生細(xì)小的浮點(diǎn)值變化。因?yàn)楦↑c(diǎn)數(shù)字的二進(jìn)制表示法可以采用很多合法舍入規(guī)則中的任意一條,因此我們不可能可靠地量化一個(gè)浮點(diǎn)值。

    轉(zhuǎn)換 decimal 和 numeric 數(shù)據(jù)

    對(duì)于 decimal numeric 數(shù)據(jù)類型,Microsoft® SQL Server™ 將精度和小數(shù)位數(shù)的每個(gè)特定組合看作是不同的數(shù)據(jù)類型。例如,decimal(5,5) 和 decimal(5,0) 被當(dāng)作不同的數(shù)據(jù)類型。

    在 Transact-SQL 語句中,帶有小數(shù)點(diǎn)的常量自動(dòng)轉(zhuǎn)換為 numeric 數(shù)據(jù)值,且必然使用最小的精度和小數(shù)位數(shù)。例如,常量 12.345 被轉(zhuǎn)換為 numeric 值,其精度為 5,小數(shù)位為 3。

    decimal numeric floatreal 轉(zhuǎn)換會(huì)導(dǎo)致精度損失。從 intsmallinttinyintfloatrealmoney smallmoneydecimalnumeric 轉(zhuǎn)換會(huì)導(dǎo)致溢出。

    默認(rèn)情況下,在將數(shù)字轉(zhuǎn)換為較低精度和小數(shù)位數(shù)的 decimalnumeric 值時(shí),SQL Server 使用舍入法。然而,如果 SET ARITHABORT 選項(xiàng)為 ON,當(dāng)發(fā)生溢出時(shí),SQL Server 會(huì)出現(xiàn)錯(cuò)誤。若僅損失精度和小數(shù)位數(shù),則不會(huì)產(chǎn)生錯(cuò)誤.

    posted @ 2009-05-18 15:21 redcoatjk 閱讀(886) | 評(píng)論 (0)編輯 收藏
     

    hql 多對(duì)多查詢 elements

    可編寫如下Hql 語句完成查詢:

    Sql代碼
    1.  
    Sql代碼 復(fù)制代碼
    1. select Blog    
    2. from Blog, Book   
    3. where Blog.author in elements(Book.authors)   
    4.     and Book.id=?  


    對(duì)應(yīng)的Sql近似如下:

    Sql代碼
    1. select  blog.*   
    2. from  blog, book   
    3. where  (blog.author  in  ( select  author.authorid  
    4.         from  book_author   
    5.         where  book.id=book_author.bookid))   
    6.     and  book.id=? 
    posted @ 2009-05-17 22:07 redcoatjk 閱讀(536) | 評(píng)論 (0)編輯 收藏
     
    摘自:http://blog.csdn.net/escode/archive/2008/11/04/3217052.aspx
    本文中將講述Hibernate的基本配置及配置文件的應(yīng)用,這對(duì)于正確熟練使用Hibernate是相當(dāng)關(guān)鍵的。

      配置文件中映射元素詳解

      對(duì)象關(guān)系的映射是用一個(gè)XML文檔來說明的。映射文檔可以使用工具來生成,如XDoclet,Middlegen和AndroMDA等。下面從一個(gè)映射的例子開始講解映射元素,映射文件的代碼如下。

    <?xml version="1.0"?>
    <!--
    所有的XML映射文件都需要定義如下所示的DOCTYPE。
    Hibernate會(huì)先在它的類路徑(classptah)中搜索DTD文件。

    -->
    <!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

    <!--
    hibernate-mapping有幾個(gè)可選的屬性:
    schema屬性指明了這個(gè)映射的表所在的schema名稱。
    default-cascade屬性指定了默認(rèn)的級(jí)聯(lián)風(fēng)格 可取值有 none、save、update。
    auto-import屬性默認(rèn)讓我們?cè)诓樵冋Z言中可以使用非全限定名的類名 可取值有 true、false。
    package屬性指定一個(gè)包前綴。
    -->

    <hibernate-mapping schema="schemaName" default-cascade="none"
    auto-import="true" package="test">

    <!--用class元素來定義一個(gè)持久化類 -->
    <class name="People" table="person">
    <!-- id元素定義了屬性到數(shù)據(jù)庫表主鍵字段的映射。-->
    <id name="id">
    <!-- 用來為該持久化類的實(shí)例生成唯一的標(biāo)識(shí) -->
    <generator class="native"/>
    </id>
    <!-- discriminator識(shí)別器 是一種定義繼承關(guān)系的映射方法-->

    <discriminator column="subclass" type="character"/>
    <!-- property元素為類聲明了一個(gè)持久化的,JavaBean風(fēng)格的屬性-->
    <property name="name" type="string">
    <column name="name" length="64" not-null="true" />
    </property>

    <property name="sex"
    not-null="true"
    update="false"/>

    <!--多對(duì)一映射關(guān)系-->
    <many-to-one name="friend"
    column="friend_id"
    update="false"/>

    <!--設(shè)置關(guān)聯(lián)關(guān)系-->

    <set name="friends" inverse="true" order-by="id">
    <key column="friend_id"/>
    <!—一對(duì)多映射-->
    <o(jì)ne-to-many class="Cat"/>
    </set>
    </class>
    </hibernate-mapping>

      組件應(yīng)用的方法

      組件有兩種類型,即組件(component)和動(dòng)態(tài)組件(dynamic-component)。在配置文件中,component元素為子對(duì)象的元素與父類對(duì)應(yīng)表的字段建立起映射關(guān)系。然后組件可以聲明它們自己的屬性、組件或者集合。component元素的定義如下所示:

    <component name="propertyName" class="className" insert="true|false"
    upate="true|false" access="field|property|ClassName">

    <property ...../>
    <many-to-one .... />
    ........
    </component>

      在這段代碼中,name是指屬性名,class是類的名字,insert指的是被映射的字段是否出現(xiàn)在SQL的INSERT語句中,upate指出被映射的字段是否出現(xiàn)在SQL的UPDATE語句中,access指出訪問屬性的策略。
      Hiebernate的基本配置

      Hibernate的數(shù)據(jù)庫連接信息是從配置文件中加載的。Hibernate 的配置文件有兩種形式:一種是XML格式的文件,一種是properties屬性文件。properties形式的配置文件默認(rèn)文件名是 hibernate.properties,一個(gè)properties形式的配置文件內(nèi)容如下所示:

    #指定數(shù)據(jù)庫使用的驅(qū)動(dòng)類
    hibernate.connection.driver_class = com.mysql.jdbc.Driver r

    #指定數(shù)據(jù)庫連接串
    hibernate.connection.url = jdbc:mysql://localhost:3306/db


    #指定數(shù)據(jù)庫連接的用戶名
    hibernate.connection.username = user

    #指定數(shù)據(jù)庫連接的密碼
    hibernate.connection.password = password

    #指定數(shù)據(jù)庫使用的方言
    hibernate.dialect = net.sf.hibernate.dialect.MySQLDialect

    #指定是否打印SQL語句
    hibernate.show_sql=true

      在配置文件中包含了一系列屬性的配置,Hibernate將根據(jù)這些屬性來連接數(shù)據(jù)庫。

      在XML格式的配置文件中,除了基本的Hibernate配置信息,還可以指定具體的持久化類的映射文件,這可以避免將持久化類的配置文件硬編碼在程序中。XML格式的配置文件的默認(rèn)文件名為hibernate.cfg.xml,一個(gè)XML配置文件的示例如下所示:

    <?xml version='1.0' encoding='UTF-8'?>

    <!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

    <hibernate-configuration>
    <session-factory>
    <!--顯示執(zhí)行的SQL語句-->
    <property name="show_sql">true</property>

    <!--連接字符串-->
    <property name="connection.url">jdbc:mysql://localhost:3306/STU</property>

    <!--連接數(shù)據(jù)庫的用戶名-->
    <property name="connection.username">root</property>

    <!--數(shù)據(jù)庫用戶密碼-->
    <property name="connection.password">root</property>

    <!--數(shù)據(jù)庫驅(qū)動(dòng)-->
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>

    <!--選擇使用的方言-->
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

    <!--映射文件 -->
    <mapping resource="com/stuman/domain/Admin.hbm.xml" />

    <!--映射文件-->
    <mapping resource="com/stuman/domain/Student.hbm.xml" />

    </session-factory>
    </hibernate-configuration>

      properties形式的配置文件和XML格式的配置文件可以同時(shí)使用。當(dāng)同時(shí)使用兩種類型的配置文件時(shí),XML配置文件中的設(shè)置會(huì)覆蓋properties配置文件的相同的屬性。

      對(duì)象標(biāo)識(shí)符號(hào)

      在關(guān)系數(shù)據(jù)庫表中,主鍵(Primary Key)用來識(shí)別記錄,并保證每條記錄的唯一性。在Java語言中,通過比較兩個(gè)變量所引用對(duì)象的內(nèi)存地址是否相同,或者比較兩個(gè)變量引用的對(duì)象值是否相同來判斷兩對(duì)象是否相等。Hibernate為了解決兩者之間的不同,使用對(duì)象標(biāo)識(shí)符(OID)來標(biāo)識(shí)對(duì)象的唯一性。OID是關(guān)系數(shù)據(jù)庫中主鍵在Java 對(duì)象模型中的等價(jià)物。在運(yùn)行時(shí),Hibernate根據(jù)OID來維持Java對(duì)象和數(shù)據(jù)庫表中記錄的對(duì)應(yīng)關(guān)系。如下代碼所示,三次調(diào)用了Session的 load()方法,分別加載OID為1或3的User對(duì)象。

    Transaction tx = session.beginTransaction();
    User user1 = (User)session.load(User.class,new Long(1));
    User user2 = (User)session.load(User.class,new Long(1));
    User user3 = (User)session.load(User.class,new Long(3));
    System.out.println( user1 == user2 );
    System.out.println( user1 == user3 );

      應(yīng)用程序在執(zhí)行上述代碼時(shí),第一次加載OID為1的User對(duì)象,從數(shù)據(jù)庫中查找ID為1的記錄,然后創(chuàng)建相應(yīng)的User實(shí)例,并把它保存在 Session緩存中,最后將該實(shí)例的引用賦值給變量user1。第二次加載OID為1的對(duì)象時(shí),直接把Session緩存中OID為1的實(shí)例的引用賦值給變量user2。因此,表達(dá)式user1==user2的結(jié)果為true。

      標(biāo)識(shí)的生成可以使用不同的策略,表1為Hibernate內(nèi)置的標(biāo)識(shí)生成策略。

      表1 Hibernate標(biāo)識(shí)生成策略
    標(biāo)識(shí)符生成器
    描述
    increment 適用于代理主鍵。由Hibernate自動(dòng)以遞增方式生成。
    identity 適用于代理主鍵。由底層數(shù)據(jù)庫生成標(biāo)識(shí)符。
    sequence 適用于代理主鍵。Hibernate根據(jù)底層數(shù)據(jù)庫的序列生成標(biāo)識(shí)符,這要求底層數(shù)據(jù)庫支持序列。
    hilo 適用于代理主鍵。Hibernate分局high/low算法生成標(biāo)識(shí)符。
    seqhilo 適用于代理主鍵。使用一個(gè)高/低位算法來高效的生成long,short或者int類型的標(biāo)識(shí)符。
    native 適用于代理主鍵。根據(jù)底層數(shù)據(jù)庫對(duì)自動(dòng)生成標(biāo)識(shí)符的方式,自動(dòng)選擇identity、sequence或hilo。
    uuid.hex 適用于代理主鍵。Hibernate采用128位的UUID算法生成標(biāo)識(shí)符。

    uuid.string
    適用于代理主鍵。UUID被編碼成一個(gè)16字符長的字符串。
    assigned 適用于自然主鍵。由Java應(yīng)用程序負(fù)責(zé)生成標(biāo)識(shí)符。
    foreign 適用于代理主鍵。使用另外一個(gè)相關(guān)聯(lián)的對(duì)象的標(biāo)識(shí)符。
      Hibernate映射類型

      在對(duì)象/關(guān)系映射文件中,Hibernate采用映射類型作為Java類型和SQL類型的橋梁。Hibernate映射類型分為2種:內(nèi)置映射類型和自定義映射類型。

      1、內(nèi)置映射類型

      Hibernate對(duì)所有的Java原生類型、常用的Java類型如String、Date等都定義了內(nèi)置的映射類型。表2列出了Hibernate映射類型、對(duì)應(yīng)的Java類型以及對(duì)應(yīng)的標(biāo)準(zhǔn)SQL類型。

      表2 Hibernate內(nèi)置映射類型
    Hibernate映射類型 Java類型 標(biāo)準(zhǔn)SQL類型 大小
    integer/int java.lang.Integer/int INTEGER 4字節(jié)
    long java.lang.Long/long BIGINT 8字節(jié)
    short java.lang.Short/short SMALLINT 2字節(jié)
    byte java.lang.Byte/byte TINYINT 1字節(jié)
    float java.lang.Float/float FLOAT 4字節(jié)
    double java.lang.Double/double DOUBLE 8字節(jié)
    big_decimal java.math.BigDecimal NUMERIC  
    character java.lang.Character/java.lang.String/char CHAR(1) 定長字符
    string java.lang.String VARCHAR 變長字符
    boolean/ yes_no/true_false java.lang.Boolean/Boolean BIT 布爾類型
    date java.util.Date/java.sql.Date DATE 日期
    timestamp java.util.Date/java.util.Timestamp TIMESTAMP 日期
    calendar java.util.Calendar TIMESTAMP 日期
    calendar_date java.util.Calendar DATE 日期
    binary byte[] BLOB
    BLOB
    text java.lang.String TEXT CLOB
    serializable 實(shí)現(xiàn)java.io.Serializablej接口的任意Java類 BLOB BLOB
    clob java.sql.Clob CLOB CLOB
    blob java.sql.Blob BLOB BLOB
    class java.lang.Class VARCHAR 定長字符
    locale java.util.Locale VARCHAR 定長字符
    timezone java.util.TimeZone VARCHAR 定長字符
    currency java.util.Currency VARCHAR 定長字符

      2、自定義映射類型

      Hibernate提供了自定義映射類型接口,允許用戶以編程的方式創(chuàng)建自定義的映射類型。用戶自定義的映射類型需要實(shí)現(xiàn) net.sf.hibernate.UserType或net.sf.hibernate.CompositeUserType接口。具體的創(chuàng)建自定義映射類型的方法請(qǐng)參考hibernate官方文檔或相關(guān)資料,這里不再詳細(xì)介紹。
    posted @ 2009-05-13 18:10 redcoatjk 閱讀(541) | 評(píng)論 (0)編輯 收藏
     
    Spring XML配置的12個(gè)技巧
    Spring是一個(gè)強(qiáng)有力的java程序框架,其被廣泛應(yīng)用于java的程序中。它用POJO提供了企業(yè)級(jí)服務(wù)。Spring利用依賴注入可以獲得簡(jiǎn)單而有效的測(cè)試能力。Spring beans,依賴關(guān)系,以及服務(wù)所需要的bean都將在配置文件中予以描述,配置文件一般采用XML格式。然而XML配置文件冗長而不易使用,在你進(jìn)行一個(gè)使用了大量bean的大項(xiàng)目中它將變得難以閱讀和控制。



    在這篇文章中我將給你展示12種的有關(guān)Spring XML配置文件的最佳技巧。它們中的一些具有更多的實(shí)際意義,而不僅是最好的技巧。請(qǐng)注意另外一些因素,例如域模型的設(shè)計(jì),會(huì)影響到XML配置,但是這篇文章更關(guān)注于XML配置的可讀性和可操控性。



    1. 避免使用自動(dòng)裝配

    Spring可以通過bean類的自省來實(shí)現(xiàn)自動(dòng)裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構(gòu)造函數(shù)的參數(shù)。根據(jù)屬性名稱活匹配類型,bean屬性可以自動(dòng)進(jìn)行裝配。而構(gòu)造函數(shù)可以根據(jù)匹配類型自動(dòng)裝配。你甚至可以設(shè)置自動(dòng)裝配進(jìn)行自動(dòng)偵測(cè),這樣Spring替你就會(huì)選擇一個(gè)合適的機(jī)制。請(qǐng)看下面的例子:





    Spring可以通過bean類的自省來實(shí)現(xiàn)自動(dòng)裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構(gòu)造函數(shù)的參數(shù)。根據(jù)屬性名稱活匹配類型,bean屬性可以自動(dòng)進(jìn)行裝配。而構(gòu)造函數(shù)可以根據(jù)匹配類型自動(dòng)裝配。你甚至可以設(shè)置自動(dòng)裝配進(jìn)行自動(dòng)偵測(cè),這樣Spring替你就會(huì)選擇一個(gè)合適的機(jī)制。請(qǐng)看下面的例子:



      <bean id="orderService"

        class="com.lizjason.spring.OrderService"

        autowire="byName"/>



    OrderService類的屬性名被用來和容器中的一個(gè)bean實(shí)例進(jìn)行匹配。自動(dòng)裝配會(huì)默默的保存一些類型信息并降低混亂。然而,由于它會(huì)犧牲掉這種配置的直觀性和可維護(hù)性,你在實(shí)際的項(xiàng)目中將不會(huì)用到它。許多指南和陳述材料都把它吹捧為Spring的一個(gè)非常cool的特性,而沒有提到它的這個(gè)缺點(diǎn)。依我之見,就像Spring的對(duì)象池一樣,它更多了一些商業(yè)味道。它看起來好像可以使XML配置文件更精簡(jiǎn)一些,但實(shí)際上卻增加其復(fù)雜性,尤其是在你的較大規(guī)模的工程中已經(jīng)定義了很多bean的時(shí)候更是如此。Spring允許你混合使用自動(dòng)和手動(dòng)裝配,但是這種矛盾會(huì)使XML配置更加的令人費(fèi)解。



    2. 使用命名規(guī)范

    和Java編碼的理念一樣,在項(xiàng)目中始終用清晰的,描述性的,一致的命名規(guī)范對(duì)開發(fā)人員理解XML配置非常有用。拿bean ID舉例來說,你可以遵循Java類中屬性的命名規(guī)范。比如說,OrderServiceDAO的bean ID應(yīng)該是orderServiceDAO。對(duì)于大項(xiàng)目來說,在bean ID前加包名來作為前綴。



    3. 使用簡(jiǎn)化格式

    簡(jiǎn)化格式有利于減少冗余,因?yàn)樗褜傩灾岛鸵米鳛閷傩裕皇亲釉亍?聪旅娴睦樱?br />
      <bean id="orderService"     class="com.lizjason.spring.OrderService">     <property name="companyName">         <value>lizjason</value>     </property>     <constructor-arg>         <ref bean="orderDAO">     </constructor-arg>   </bean>以上程序可以重新以簡(jiǎn)化格式書寫為:

      <bean id="orderService"     class="com.lizjason.spring.OrderService">     <property name="companyName"         value="lizjason"/>     <constructor-arg ref="orderDAO"/>   </bean>簡(jiǎn)化格式在1.2版本時(shí)已經(jīng)可用了,但請(qǐng)注意不存在<ref local="...">這種簡(jiǎn)化格式不僅可以較少你的代碼輸入量,而且可以使XML配置更加的清晰。當(dāng)你的配置文件中存在大量的bean定義時(shí),它可以顯著地提高可讀性。



    4. 盡量使用type而不是index去解決構(gòu)造函數(shù)參數(shù)的匹配問題

    當(dāng)構(gòu)造函數(shù)中有多個(gè)同類型的參數(shù)時(shí),Spring只允許你使用從0開始的index或者value標(biāo)簽來解決這個(gè)問題。請(qǐng)看下面的例子:

      <bean id="billingService"     class="com.lizjason.spring.BillingService">     <constructor-arg index="0" value="lizjason"/>     <constructor-arg index="1" value="100"/>   </bean>最好用type屬性取代上面的做法:

      <bean id="billingService"     class="com.lizjason.spring.BillingService">     <constructor-arg type="java.lang.String"         value="lizjason"/>     <constructor-arg type="int" value="100"/>   </bean>

    用index可以稍微減少冗余,但是它更容易出錯(cuò)且不如type屬性可讀性高。你應(yīng)該僅在構(gòu)造函數(shù)中有參數(shù)沖突時(shí)使用index。



    5. 如可能,盡量復(fù)用bean定義

    Spring提供了一種類似于繼承的機(jī)制來降低配置信息的重復(fù)并使XML配置更加的簡(jiǎn)單。一個(gè)子bean可以從它的父bean繼承配置信息,本質(zhì)上這個(gè)父bean就像它的子bean的一個(gè)模板。這是一個(gè)在大型項(xiàng)目中必須使用的特性。所有你要做的就是把父bean的abstract屬性置為true,并在子bean中加以引用。例如:

      <bean id="abstractService" abstract="true"     class="com.lizjason.spring.AbstractService">     <property name="companyName"         value="lizjason"/>   </bean>   <bean id="shippingService"     parent="abstractService"     class="com.lizjason.spring.ShippingService">     <property name="shippedBy" value="lizjason"/>   </bean>shippingService bean繼承了abstractService bean的屬性companyName的值lizjason。注意,如果你為bean聲名一個(gè)class或工廠方法,這個(gè)bean將會(huì)默認(rèn)為abstract



    6. 盡量使用ApplicationContext裝配bean,而不是用import

    像Ant腳本中imports一樣,Spring的import 元素對(duì)于模塊化bean的裝配非常有用,例如:

      <beans>     <import resource="billingServices.xml"/>     <import resource="shippingServices.xml"/>     <bean id="orderService"         class="com.lizjason.spring.OrderService"/>   <beans>然而,比起在XML中用imports預(yù)裝配這些bean,利用ApplicationContext來配置它們將更加靈活,也可以使XML配置更加的易于管理。你可以像下面這樣傳遞一個(gè)bean定義數(shù)組到ApplicationContext的構(gòu)造函數(shù)中:

      String[] serviceResources =

        {"orderServices.xml",

        "billingServices.xml",

        "shippingServices.xml"};

    ApplicationContext orderServiceContext = new

    ClassPathXmlApplicationContext(serviceResources);



    7. 用id來標(biāo)識(shí)bean

    你可以用id或名字作為bean的標(biāo)識(shí)。用id可讀性較差,但是它可以影響XML分析器使bean的reference有效。如果id由于XML IDREF約束而無法使用,你可以用name作為bean的標(biāo)識(shí)。XML IDREF約束是指id必須以字母開始(或者是在XML聲名了的一個(gè)標(biāo)點(diǎn)符號(hào)),后面可以是字母,數(shù)字,連字符,下劃線,冒號(hào)或full stops(不知道怎么翻譯好)。在實(shí)際應(yīng)用中很少會(huì)遇到XML IDREF約束問題。



    8. 在開發(fā)階段使用依賴檢查

    你可以為bean的dependency-check屬性設(shè)置一個(gè)值來取代默認(rèn)的none,比如說simple,objects或者all,這樣的話容器將替你做依賴有效性的檢查。當(dāng)一個(gè)bean的所有屬性(或者某些屬性目錄)都被明確設(shè)置,或利用自動(dòng)裝配時(shí)將會(huì)非常有用。

      <bean id="orderService"     class="com.lizjason.spring.OrderService"     dependency-check="objects">     <property name="companyName"         value="lizjason"/>     <constructor-arg ref="orderDAO"/>   </bean>在這個(gè)例子中,容器將確保這些屬性不是privitives或者保證collections是為orderService bean設(shè)置的。為所有的bean設(shè)置默認(rèn)的依賴檢查是可能的,但這個(gè)特性由于有些bean的屬性不需要設(shè)置而很少使用。



    9. 為每個(gè)配置文件加一個(gè)描述注釋

    在XML配置文件中最好使用有描述性的id和name,而不是成堆的注釋。另外,加一個(gè)文件描述頭將會(huì)非常有用,這個(gè)描述可以概括文件中定義的bean。另一個(gè)選擇,你可以在description元素中加入描述信息。例如:

      <beans>     <description>         This file defines billing service         related beans and it depends on         baseServices.xml,which provides         service bean templates...     </description>     ...   </beans>用description元素的一個(gè)好處就是工具可以很容易的把描述信息從這個(gè)元素中提取出來。



    10.   和team members溝通變更

    當(dāng)你修改java源碼后,要確保更改了配置文件中的相應(yīng)部分并把這個(gè)情況告知你的team members。XML配置文件也是代碼,它們是程序的重要組成部分,但它們很難閱讀和維護(hù)。大多數(shù)時(shí)間里,你需要同時(shí)看XML配置文件和java代碼才能知道是怎么回事。



    11.   setter注入和構(gòu)造函數(shù)注入,優(yōu)先使用前者

    Spring提供了三種注入方式:構(gòu)造函數(shù)注入,setter注入和方法注入。一般我們使用前兩種。

      <bean id="orderService"     class="com.lizjason.spring.OrderService">     <constructor-arg ref="orderDAO"/>   </bean>   <bean id="billingService"     class="com.lizjason.spring.BillingService">     <property name="billingDAO"         ref="billingDAO">   </bean>在這個(gè)例子中,orderService bean用了構(gòu)造函數(shù)注入,而BillingService bean用了setter注入。構(gòu)造函數(shù)注入可以確保bean正確地構(gòu)建,但是setter注入更加的靈活和易于控制,特別是當(dāng)class有多個(gè)屬性并且它們中的一些是可選的情況是更是如此。



    12.   不要濫用注入

    就像前面提到的,Spring的ApplicationContext可以替你創(chuàng)建java對(duì)象,但不是所有的java對(duì)象都應(yīng)該通過注入創(chuàng)建。例如,域?qū)ο缶筒粦?yīng)該通過ApplicationContext創(chuàng)建。Spring是一個(gè)優(yōu)秀的框架,但是考慮到可讀性和可操控性,基于XML配置的配置會(huì)在定義很多bean的時(shí)候出現(xiàn)麻煩。過渡使用依賴注入將會(huì)使XML配置更加的復(fù)雜和冗長。切記,當(dāng)使用高效的IDE時(shí),例如Eclipse and IntelliJ,java代碼更加的易于閱讀,維護(hù)和管理比使XML文件



    結(jié)論

    XML是Spring流行的配置格式。存在大量bean定義時(shí),基于XML的配置會(huì)變得冗長而不易使用。Spring提供了豐富的配置選項(xiàng)。適當(dāng)?shù)厥褂眠@些選項(xiàng)可以使XML配置更加的清晰,但其它的一些選項(xiàng),例如自動(dòng)裝配,可能會(huì)降低可讀性和可維護(hù)性。參考本文中提到的這些技巧可能會(huì)幫助你創(chuàng)建干凈而易讀的XML配置文件。
    posted @ 2009-05-10 09:47 redcoatjk 閱讀(145) | 評(píng)論 (0)編輯 收藏
     

    1、如何將java.util.Date轉(zhuǎn)化為java.sql.Date?
    轉(zhuǎn)化:

    java.sql.Date sd;
    java.util.Date ud;
    //initialize the ud such as ud = new java.util.Date();

    sd = new java.sql.Date(ud.getTime());

    2、如果要插入到數(shù)據(jù)庫并且相應(yīng)的字段為Date類型
    那么可以用PreparedStatement.setDate(int ,java.sql.Date)方法
    其中的java.sql.Date可以用上面的方法得到

    也可以用數(shù)據(jù)庫提供TO_DATE函數(shù)
    比如 現(xiàn)有 ud
    TO_DATE(new SimpleDateFormat().format(ud,"yyyy-MM-dd HH:mm:ss"),
    "YYYY-MM-DD HH24:MI:SS")
    注意java中表示格式和數(shù)據(jù)庫提供的格式的不同

    一個(gè)實(shí)際的例子

    sql="update tablename set timer=to_date('"+t+"','yyyymmddhh24miss') where ....."

    這里的t為變量為類似:20051211131223

     

    3、如何將"yyyy-mm-dd"格式的字符串轉(zhuǎn)換為java.sql.Date

    方法1

    SimpleDateFormat bartDateFormat =  
            new SimpleDateFormat("yyyy-MM-dd");  
           String dateStringToParse = "2007-7-12";  
           try {  
            java.util.Date date = bartDateFormat.parse(dateStringToParse);  
            java.sql.Date sqlDate = new java.sql.Date(date.getTime());
            System.out.println(sqlDate.getTime());  
           }  
           catch (Exception ex) {  
            System.out.println(ex.getMessage());  
           }

    ------------------------------------------------------------
    方法2
           String     strDate     =     "2002-08-09";   
           StringTokenizer     st     =     new     StringTokenizer(strDate,     "-");   
           java.sql.Date     date     =     new     java.sql.Date(Integer.parseInt(st.nextToken()),
                    Integer.parseInt(st.nextToken()),
                     Integer.parseInt(st.nextToken()));

      
    java.util.Date和java.sql.Date的異同
    java.sql.Date,java.sql.Time和java.sql.Timestamp三個(gè)都是java.util.Date的子類(包裝類)。

            但是為什么java.sql.Date類型的值插入到數(shù)據(jù)庫中Date字段中會(huì)發(fā)生數(shù)據(jù)截取呢?

            java.sql.Date是為了配合SQL DATE而設(shè)置的數(shù)據(jù)類型。“規(guī)范化”的java.sql.Date只包含年月日信息,時(shí)分秒毫秒都會(huì)清零。格式類似:YYYY-MM-DD。當(dāng)我們調(diào)用ResultSet的getDate()方法來獲得返回值時(shí),java程序會(huì)參照"規(guī)范"的java.sql.Date來格式化數(shù)據(jù)庫中的數(shù)值。因此,如果數(shù)據(jù)庫中存在的非規(guī)范化部分的信息將會(huì)被劫取。

            在sun提供的ResultSet.java中這樣對(duì)getDate進(jìn)行注釋的:
           Retrieves the of the designated column in the current row of this <code>ResultSet</code> object as a “java.sql.Date” object in the Java programming language.

             同理。如果我們把一個(gè)java.sql.Date值通過PrepareStatement的setDate方法存入數(shù)據(jù)庫時(shí),java程序會(huì)對(duì)傳入的java.sql.Date規(guī)范化,非規(guī)范化的部分將會(huì)被劫取。然而,我們java.sql.Date一般由java.util.Date轉(zhuǎn)換過來,如:java.sql.Date sqlDate=new java.sql.Date(new java.util.Date().getTime()).
    顯然,這樣轉(zhuǎn)換過來的java.sql.Date往往不是一個(gè)規(guī)范的java.sql.Date.要保存java.util.Date的精確值,
    我們需要利用java.sql.Timestamp.
    Calendar

    Calendar   calendar=Calendar.getInstance();  
    //獲得當(dāng)前時(shí)間,聲明時(shí)間變量  
    int   year=calendar.get(Calendar.YEAR);  
    //得到年
    int   month=calendar.get(Calendar.MONTH);  
    //得到月,但是,月份要加上1  
    month=month+1;
    int   date=calendar.get(Calendar.DATE);  
    //獲得日期  
    String   today=""+year+"-"+month+"-"+date+"";



    java.util.Date 就是在除了SQL語句的情況下面使用
    java.sql.Date 是針對(duì)SQL語句使用的,它只包含日期而沒有時(shí)間部分
    它都有g(shù)etTime方法返回毫秒數(shù),自然就可以直接構(gòu)建
    java.util.Date d = new java.util.Date(sqlDate.getTime());
    ...

     


     


    java.util.Date 是 java.sql.Date 的父類(注意拼寫)
    前者是常用的表示時(shí)間的類,我們通常格式化或者得到當(dāng)前時(shí)間都是用他
    后者之后在讀寫數(shù)據(jù)庫的時(shí)候用他,因?yàn)镻reparedStament的setDate()的第2參數(shù)和ResultSet的getDate()方法的第2個(gè)參數(shù)都是java.sql.Date 
    轉(zhuǎn)換是
    java.sql.Date date=new Java.sql.Date();
    java.util.Date d=new java.util.Date (date.getTime());
    反過來是一樣的

     


     


    同意 jFresH_MaN

     


     


    繼承關(guān)系:java.lang.Object  --》  java.util.Date --》 java.sql.Date
    具體的轉(zhuǎn)換關(guān)系就是java.util.Date d=new java.util.Date (new Java.sql.Date());

     


     


    sql.date,一般是在數(shù)據(jù)庫的時(shí)間字段,util.date一般是日常日期字段

     


     


    java.sql.Date主要是用于sql中的!
    而java.util.Date用語一般的環(huán)境下都行!

     


     

    SimpleDateFormat f=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
           java.util.Date utilDate=new Date();      
           java.sql.Date sqlDate=new java.sql.Date(utilDate.getTime());  
          
           java.sql.Time sTime=new java.sql.Time(utilDate.getTime());
          
          
          
           java.sql.Timestamp stp=new java.sql.Timestamp(utilDate.getTime());
                
          
           System.out.println(utilDate.getYear());

    這里所有時(shí)間日期都可以被SimpleDateFormat格式化format()

    f.format(stp);f.format(sTime);f.format(sqlDate);f.format(utilDate)

     

    java.sql.Date sqlDate=java.sql.Date.valueOf("2005-12-12");
          
           utilDate=new java.util.Date(sqlDate.getTime());

     

    --------------------------------------------------------------------------------------------------

    另類取得年月日的方法:

    import java.text.SimpleDateFormat;import java.util.*;java.util.Date date = new java.util.Date();//如果希望得到Y(jié)YYYMMDD的格式SimpleDateFormat sy1=new SimpleDateFormat("yyyyMMDD");String dateFormat=sy1.format(date);//如果希望分開得到年,月,日SimpleDateFormat sy=new SimpleDateFormat("yyyy");SimpleDateFormat sm=new SimpleDateFormat("MM");SimpleDateFormat sd=new SimpleDateFormat("dd");String syear=sy.format(date);String smon=sm.format(date);String sday=sd.format(date);

     


          



    Trackback: http://tb.donews.net/TrackBack.aspx?PostId=463449

    posted @ 2009-05-08 16:59 redcoatjk 閱讀(3202) | 評(píng)論 (0)編輯 收藏
     
    ERP、OA、MIS、CRM、BI等等都是什么 引用:http://www.zuoyefeng.com/html/2006-12/484.htm -------------------------------------------------------------------------------- ERP -------------------------------------------------------------------------------- ERP是指英文Enterprise Resource Planning(企業(yè)資源計(jì)劃)的簡(jiǎn)寫 本著整體規(guī)劃,分步實(shí)施的原則,對(duì)ERP項(xiàng)目所有方面的計(jì)劃、組織、管理和監(jiān)控,是為了達(dá)到項(xiàng)目實(shí)施后的預(yù)期成果和目標(biāo)而采取內(nèi)部和外部的持續(xù)性的工作程序。這是對(duì)時(shí)間、成本,以及產(chǎn)品、服務(wù)細(xì)節(jié)的需求相互間可能發(fā)生矛盾進(jìn)行平衡的基本原則。建立起一整套行之有效的項(xiàng)目和風(fēng)險(xiǎn)管理機(jī)制,對(duì)提高ERP系統(tǒng)的實(shí)施成功率至關(guān)重要。 ERP項(xiàng)目管理相關(guān)背景(ERP History of Project Management) 既然ERP是企業(yè)管理信息系統(tǒng),實(shí)施應(yīng)用必然要結(jié)合業(yè)務(wù)流程的優(yōu)化,也就是企業(yè)資源配置的合理化,而企業(yè)的效益又依賴于描述這種配置規(guī)劃模型的優(yōu)化,那么就讓我們把建立規(guī)劃模型的優(yōu)化作為我們首要的同時(shí)也是最終的目標(biāo),其他任務(wù)都放在次要的從屬地位上。在ERP的實(shí)施中,要把ERP與工業(yè)自動(dòng)控制系統(tǒng)的概念分開。ERP是一個(gè)資源調(diào)度或決策支持系統(tǒng),其中有對(duì)生產(chǎn)、設(shè)備、能力及各種工藝的評(píng)估和計(jì)算,但不能等同于自動(dòng)控制。的評(píng)估和計(jì)算,但不能等同于自動(dòng)控制。 OA -------------------------------------------------------------------------------- OA是OFFICE AUTOMATION的縮寫,本意為利用技術(shù)的手段提高辦公的效率,進(jìn)而實(shí)現(xiàn)辦公的自動(dòng)化處理。 采用Internet/Intranet技術(shù),基于工作流的概念,使企業(yè)內(nèi)部人員方便快捷地共享信息,高效地協(xié)同工作;改變過去復(fù)雜、低效的手工辦公方式,實(shí)現(xiàn)迅速、全方位的信息采集、信息處理,為企業(yè)的管理和決策提供科學(xué)的依據(jù)。一個(gè)企業(yè)實(shí)現(xiàn)辦公自動(dòng)化的程度也是衡量其實(shí)現(xiàn)現(xiàn)代化管理的標(biāo)準(zhǔn)。OA從最初的以大規(guī)模采用復(fù)印機(jī)等辦公設(shè)備為標(biāo)志的初級(jí)階段,發(fā)展到今天的以運(yùn)用網(wǎng)絡(luò)和計(jì)算機(jī)為標(biāo)志的現(xiàn)階段,對(duì)企業(yè)辦公方式的改變和效率的提高起到了積極的促進(jìn)作用 CRM -------------------------------------------------------------------------------- CRM是customer relationship management(客戶關(guān)系管理)的縮寫,它是一項(xiàng)綜合的IT技術(shù),也是一種新的運(yùn)作模式,它源于“以客戶為中心”的新型商業(yè)模式,是一種旨在改善企業(yè)與客戶關(guān)系的新型管理機(jī)制。通過向企業(yè)的銷售、市場(chǎng)、服務(wù)等部門和人員提供全面及個(gè)性化的客戶資料,并強(qiáng)化跟蹤服務(wù)、信息分析能力,使他們能夠協(xié)同建立和維護(hù)一系列與客戶以及商業(yè)伙伴之間卓有成效的“一對(duì)一關(guān)系”,從而使企業(yè)得以提供更快捷和周到的優(yōu)質(zhì)服務(wù),提高客戶滿意度,吸引和保持更多的客戶,從而增加營業(yè)額,并通過信息共享和優(yōu)化商業(yè)流程有效地降低企業(yè)經(jīng)營成本。通俗地說,CRM就是利用軟件、硬件和網(wǎng)絡(luò)技術(shù),為企業(yè)建立一個(gè)客戶信息收集、管理、分析、利用的信息系統(tǒng)。 客戶關(guān)系管理的功能主要分為四大部分: 1.客戶信息管理 整合記錄企業(yè)各部門、每個(gè)人所接觸的客戶資料進(jìn)行統(tǒng)一管理,這包括對(duì)客戶類型的劃分、客戶基本信息、客戶聯(lián)系人信息、企業(yè)銷售人員的跟蹤記錄、客戶狀態(tài)、合同信息等。 2.市場(chǎng)營銷管理 制訂市場(chǎng)推廣計(jì)劃,并對(duì)各種渠道(包括傳統(tǒng)營銷、電話營銷、網(wǎng)上營銷)接觸客戶進(jìn)行記錄、分類和辨識(shí),提供對(duì)潛在客戶的管理,并對(duì)各種市場(chǎng)活動(dòng)的成效進(jìn)行評(píng)價(jià)。CRM營銷管理最重要的是實(shí)現(xiàn)1 for 1營銷,從“宏?duì)I銷”到“微營銷”的轉(zhuǎn)變。 3.銷售管理 功能包括對(duì)銷售人員電話銷售、現(xiàn)場(chǎng)銷售、銷售傭金等管理,支持現(xiàn)場(chǎng)銷售人員的移動(dòng)通信設(shè)備或掌上電腦接入。進(jìn)一步擴(kuò)展的功能還包括幫助企業(yè)建立網(wǎng)上商店、支持網(wǎng)上結(jié)算管理及與物流軟件系統(tǒng)的接口。 4.服務(wù)管理與客戶關(guān)懷 功能包括產(chǎn)品安裝檔案、服務(wù)請(qǐng)求、服務(wù)內(nèi)容、服務(wù)網(wǎng)點(diǎn)、服務(wù)收費(fèi)等管理信息,詳細(xì)記錄服務(wù)全程進(jìn)行情況。支持現(xiàn)場(chǎng)服務(wù)與自助服務(wù),輔助支持實(shí)現(xiàn)客戶關(guān)懷。 MIS -------------------------------------------------------------------------------- MIS(管理信息系統(tǒng)--Management Information System)系統(tǒng) ,是一個(gè)由人、計(jì)算機(jī)及其他外圍設(shè)備等 組成的能進(jìn)行信息的收集、傳遞、存貯、加工、維護(hù)和使用的系統(tǒng)。它是一門新興的科學(xué),其主要任務(wù)是最大限度的利用現(xiàn)代計(jì)算機(jī)及網(wǎng)絡(luò)通訊技術(shù)加強(qiáng)企業(yè)的信息管理,通過對(duì)企業(yè)擁有的人力、物力、財(cái)力、設(shè)備、技術(shù)等資源的調(diào)查了解,建立正確的數(shù)據(jù),加工處理并編制成各種信息資料及時(shí)提供給管理人員,以便進(jìn)行正確的決策,不斷提高企業(yè)的管理水平和經(jīng)濟(jì)效益。目前,企業(yè)的計(jì)算機(jī)網(wǎng)絡(luò)已成為企業(yè)進(jìn)行技術(shù)改造及提高企業(yè)管理水平的重要手段。隨著我國與世界信息高速公路的接軌,企業(yè)通過計(jì)算機(jī)網(wǎng)絡(luò)獲得信息必將為企業(yè)帶來巨大的經(jīng)濟(jì)效益和社會(huì)效益,企業(yè)的辦公及管理都將朝著高效、快速、無紙化的方向發(fā)展。MIS系統(tǒng)通常用于系統(tǒng)決策,例如,可以利用MIS系統(tǒng)找出目前迫切需要解決的問題,并將信息及時(shí)反饋給上層管理人員,使他們了解當(dāng)前工作發(fā)展的進(jìn)展或不足。換句話說,MIS系統(tǒng)的最終目的是使管理人員及時(shí)了解公司現(xiàn)狀,把握將來的發(fā)展路徑。 一個(gè)完整的MIS應(yīng)包括:輔助決策系統(tǒng)(DSS)、工業(yè)控制系統(tǒng)(IPC)、辦公自動(dòng)化系統(tǒng)(OA)以及數(shù)據(jù)庫、模型庫、方法庫、知識(shí)庫和與上級(jí)機(jī)關(guān)及外界交換信息的接口。其中,特別是辦公自動(dòng)化系統(tǒng)(OA)、與上級(jí)機(jī)關(guān)及外界交換信息等都離不開Intranet的應(yīng)用。可以這樣說,現(xiàn)代企業(yè)MIS不能沒有Intranet,但I(xiàn)ntranet的建立又必須依賴于MIS的體系結(jié)構(gòu)和軟硬件環(huán)境。 傳統(tǒng)的MIS系統(tǒng)的核心是CS(Client/Server——客戶端/服務(wù)器)架構(gòu),而基于Internet的MIS系統(tǒng)的核心是BS(Browser/Server——瀏覽器/服務(wù)器)架構(gòu)。BS架構(gòu)比起CS架構(gòu)有著很大的優(yōu)越性,傳統(tǒng)的MIS系統(tǒng)依賴于專門的操作環(huán)境,這意味著操作者的活動(dòng)空間受到極大限制;而BS架構(gòu)則不需要專門的操作環(huán)境,在任何地方,只要能上網(wǎng),就能夠操作MIS系統(tǒng),這其中的優(yōu)劣差別是不言而喻的。 基于Internet上的MIS系統(tǒng)是對(duì)傳統(tǒng)MIS系統(tǒng)概念上的擴(kuò)展,它不僅可以用于高層決策,而且可以用于進(jìn)行普通的商務(wù)管理。通過用戶的具名登錄(或匿名登錄),以及相應(yīng)的權(quán)限控制,可以實(shí)現(xiàn)在遠(yuǎn)端對(duì)系統(tǒng)的瀏覽、查詢、控制和審閱。隨著Internet的擴(kuò)展,現(xiàn)有的公司和學(xué)校不再局限于物理的有形的真實(shí)的地域,網(wǎng)絡(luò)本身成為事實(shí)上發(fā)展的空間。基于Internet上的MIS系統(tǒng),彌補(bǔ)了傳統(tǒng)MIS系統(tǒng)的不足,充分體現(xiàn)了現(xiàn)代網(wǎng)絡(luò)時(shí)代的特點(diǎn)。隨著Internet技術(shù)的高速發(fā)展,因特網(wǎng)必將成為人類新社會(huì)的技術(shù)基石。基于Internet的MIS系統(tǒng)必將成為網(wǎng)絡(luò)時(shí)代的新一代管理信息系統(tǒng),前景極為樂觀。 BI -------------------------------------------------------------------------------- Business Intelligence(BI) 商務(wù)智能 IDC將商業(yè)智能定義為下列軟件工具的集合: 1.終端用戶查詢和報(bào)告工具。專門用來支持初級(jí)用戶的原始數(shù)據(jù)訪問,不包括適用于專業(yè)人士的成品報(bào)告生成工具 2.OLAP工具。提供多維數(shù)據(jù)管理環(huán)境,其典型的應(yīng)用是對(duì)商業(yè)問題的建模與商業(yè)數(shù)據(jù)分析。OLAP也被稱為多維分析 3.數(shù)據(jù)挖掘(Data Mining)軟件。使用諸如神經(jīng)網(wǎng)絡(luò)、規(guī)則歸納等技術(shù),用來發(fā)現(xiàn)數(shù)據(jù)之間的關(guān)系,做出基于數(shù)據(jù)的推斷。 4.數(shù)據(jù)集市(Data Mart)和數(shù)據(jù)倉庫(Data Warehouse)產(chǎn)品。包括數(shù)據(jù)轉(zhuǎn)換、管理和存取等方面的預(yù)配置軟件,通常還包括一些業(yè)務(wù)模型,如財(cái)務(wù)分析模型。 5.主管信息系統(tǒng)(EIS,Executive Information System) 這個(gè)定義應(yīng)該是比較學(xué)術(shù)了,客戶多半不明白。 其實(shí)BI通俗來講就是收集相關(guān)信息并加以分析,以幫助您做決策。成功的BI系統(tǒng)多采用了數(shù)據(jù)倉庫技術(shù)。 Rose -------------------------------------------------------------------------------- 強(qiáng)大的面向?qū)ο蟮目梢暬治觥⒃O(shè)計(jì)、建模工具;      Rational Rose支持各類可視化建模,諸如系統(tǒng)需求、事務(wù)進(jìn)程、企業(yè)商務(wù)對(duì)象、及軟件組件、軟件結(jié)構(gòu)、軟件對(duì)象的 可視化建模等。Rational Rose 支持統(tǒng)一建模語言(UML),UML是對(duì)軟件組件及其交互作用進(jìn)行可視化建模的工業(yè)標(biāo)準(zhǔn),已經(jīng)得到了Microsoft,Oracle,Hewlett-Packard,Texas Instruments和MC I Systemhouse等眾多公司的正式認(rèn)可。       Rational Rose可以和任何一種面向?qū)ο髴?yīng)用程序結(jié)構(gòu)組合使用。循環(huán)迭代開發(fā) ---包括源代碼生成的正向工程和已存在代碼返回到圖形對(duì)象模型的逆向工程--- 通過Rational Rose系列產(chǎn)品得到各類主要編程語言和快速應(yīng)用開發(fā)工具的直接支持。       關(guān)鍵效益 *提高溝通能力。 團(tuán)隊(duì)所有人員使用同一語言,避免了在術(shù)語及需求上的混亂。由于設(shè)計(jì)人員和實(shí)施人員的準(zhǔn)確溝通,使得計(jì)劃和編程的過渡時(shí)間縮短,減少了錯(cuò)誤的發(fā)生。 *可管理的復(fù)雜性。 有著大量變數(shù)的復(fù)雜系統(tǒng)可以很容易的被理解。設(shè)計(jì)人員可以集中進(jìn)行大圖的設(shè)計(jì),而不是更小的細(xì)節(jié)。這樣的結(jié)果是開發(fā)的時(shí)間縮短了,所建的系統(tǒng)是邏輯型和流線型的。 *詳細(xì)的軟件結(jié)構(gòu)。 能創(chuàng)建出軟件設(shè)計(jì)的藍(lán)圖,需求及變量被清楚的定義。這樣的結(jié)果是在設(shè)計(jì)過程中有更少的錯(cuò)誤發(fā)生,所創(chuàng)造的系統(tǒng)更強(qiáng)大更具彈性。 *重用。 創(chuàng)建應(yīng)用設(shè)計(jì)的可控單元,只需改變模型或部分模型,無需改變整個(gè)應(yīng)用,就可以改變或更新項(xiàng)目。這樣既省時(shí)又提高了生產(chǎn)率。 *獲取商務(wù)進(jìn)程。 系統(tǒng)的需求在Use Case中抓取,從用戶的角度來定義商務(wù)進(jìn)程。定義進(jìn)程是用文本格式來,而不是用計(jì)算機(jī)術(shù)語。這樣,一個(gè)流暢的開發(fā)進(jìn)程就創(chuàng)建出來了,因?yàn)閺囊婚_始所有的需求就十分明確,所以最終產(chǎn)品也能滿足最終用戶的需求
    posted @ 2009-05-03 10:19 redcoatjk 閱讀(202) | 評(píng)論 (0)編輯 收藏
    僅列出標(biāo)題
    共8頁: 上一頁 1 2 3 4 5 6 7 8 下一頁 
    CALENDER
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    留言簿(3)

    隨筆分類(22)

    隨筆檔案(76)

    文章分類(12)

    文章檔案(17)

    搜索

    •  

    積分與排名

    • 積分 - 250517
    • 排名 - 227

    最新評(píng)論

    評(píng)論排行榜


    Powered By: 博客園
    模板提供滬江博客

    主站蜘蛛池模板: 亚洲综合另类小说色区| 美女露100%胸无遮挡免费观看| 99久久国产精品免费一区二区| 国产成人精品男人免费| 亚洲欧洲日韩国产一区二区三区| 色猫咪免费人成网站在线观看| 国产成人综合亚洲亚洲国产第一页| 精品久久久久亚洲| 男女啪啪永久免费观看网站| 精品亚洲成在人线AV无码| **真实毛片免费观看| 亚洲性天天干天天摸| 在线观看人成视频免费无遮挡| 国产偷窥女洗浴在线观看亚洲| 暖暖免费中文在线日本| 国产在线观看免费视频播放器| 亚洲国产精品成人AV在线| 毛片A级毛片免费播放| 亚洲一久久久久久久久| 啦啦啦中文在线观看电视剧免费版| 亚洲精品在线播放| 99在线观看视频免费| 亚洲五月激情综合图片区| 99蜜桃在线观看免费视频网站| 亚洲国产二区三区久久| 亚洲免费视频在线观看| 无码专区—VA亚洲V天堂| 久久aa毛片免费播放嗯啊| 亚洲av综合色区| 久久国产精品免费专区| 亚洲尹人九九大色香蕉网站| 久久九九全国免费| 亚洲AV日韩AV高潮无码专区| 四虎国产成人永久精品免费| 麻豆亚洲AV永久无码精品久久| 性xxxxx大片免费视频| 亚洲系列中文字幕| 成年人视频免费在线观看| 亚洲Av高清一区二区三区| 成年人免费网站在线观看| 亚洲精品人成网线在线播放va|