直掛云帆濟滄海,展翅遨翔登九天!

          我要飛得更高...

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            19 隨筆 :: 0 文章 :: 5 評論 :: 0 Trackbacks

          2008年8月18日 #

                  從這一階段開始講述軟件設計模式,我也不再講GoF的神奇歷史,直接進入正題。在進行模式講解的同時,對于本人來說,一方面也是進行了復習,另一方面也是通過講解使自己對這些模式的使用上達到一個更加理解的層次。搞軟件的朋友都知道,在進行開發過一段時間后,會發現自己大學里學習的基礎課很重要。而目前很多朋友對軟件的理解都非常膚淺,只知道增刪改查,試用這樣的程序員能存活多久,思考很重要,學習很重要,理解很重要,領悟更重要。讓浮燥的程序員回歸理性吧,模式可能讓浮燥的心情得到凈化,在模式中進行思考,在模式中進行領悟吧。
                  第一講是裝飾器。當初我在學裝飾器模式的時候總是感覺似懂非懂,一直沒有真正理解。其實裝飾器也叫油漆工模式,再加上在我們的java類庫中有很多是實現了裝飾器模式的類。比方說:在讀取文件時
          FileReader fr = new FileReader(filename);
          BufferedReader br = new BufferedReader(fr);
          這其實就是一個decorator模式。因為針對File的讀取方式有很多,如果每種都要采用繼承的方法,那么會產生很多的子類,那樣顯然是很煩的。
                    裝飾器也稱為油漆工模式。它的目的就是給一個對象動態地添加一些功能。就像是給對象刷了一層漆,使這個對象更加豐富,而不是通過繼承來增加功能。而這些功能的添加是動態的運行期的,當然這里的動態并不是像aop中的引介introductor,大家不要混淆。
                    在我們的項目中,經常會遇到日志的情況。大凡我們會定義一個log接口就像下面。
          public interface Logger {
              public void log(String msg);
          }
          一般我們會把日志保存中文件中,所以有了一個FileLogger

          public class FileLogger implements Logger {

           public void log(String msg) {
                  //開始記錄日志到文件中
           }
          }
          此時如果在項目有些地方需要對日志進行加密,有些地方又不需要加密,或者有些地方生成的文件是以xml的方式。此時如果采用繼承的方法,也能實現,但是從面向對象的角度來說,并不建議對象的層次太深,增加系統的復雜性,這樣對于系統的擴展和維護都不是很方便。此時Decorator模式就可以幫我們解決這些問題,我們可以為這個一般的FileLogger對象上刷一層不同的漆,那么這些漆,從上面增加的功能角度來說,就是加了一個“加密”的漆,或加了一層“生成xml”的漆。
          先定義一個Decorator接口,此接口也實現了Logger接口
          public class LoggerDecorator implements Logger{
             Logger logger;
             public LoggerDecorator(Logger logger){
                  this.logger=logger;
             }
             //開始記錄日志
             public void log(String msg){
                 //此處便是給實現了Logger接口的,被刷了油漆的(增加了功能的例如加密等)對象記錄日志
                 logger.log(msg);
             }
          }
          public class EncryptDecorator extends LoggerDecorator{
              public EncryptDecorator(Logger logger){
                  super(logger);
              }
              public void log(String msg){
                  //刷加密字符串的油漆
                  msg=this.encryptMsg(msg);
                  //記錄加密后的日志
                  logger.log(msg);
              }
          }
          //客戶端的調用
          public DecoratorClient{
              public static void main(String args[]){
                   Logger logger=new FileLogger();
                   Logger decorator=new EncryptDecorator(logger);
                   decorator.log("加密的字符串");
             }
          }
          這樣就基本把Decorator模式的應用起來,當然在項目中我們可能還需要更豐富一下我們的類,此處僅用這樣的簡單示例來講述。

          posted @ 2008-08-18 23:11 周大俠 閱讀(445) | 評論 (1)編輯 收藏

          2008年8月15日 #

                   網上google一下,想找一些有用的資料,結果是搜了不少,誰知道都是轉載,而且相同的文章太多太多,達到了泛濫的地步,然后冒充自己的文章,也不提是轉載,貌似增加了網絡搜索資料的途徑,實是浪費真正想找資料的朋友的時間,殊不知別人的時間都是有限的,每次打開一個頁面結果卻都是相同的內容,你叫人氣不氣,擾亂了整個網絡的制序,損人利己,濫宇充數。
              網上的資料不是不可轉載,但請轉載者在盲目轉載的同時,請提出自己的看法意見,留下有用的信息,否則亂貼在自己的blog只會讓真正的有志之士所看不起,如果您無法原創,就請您把您的blog關閉。
              清除網絡垃圾,還我們一片干凈的網絡空間!!!
          posted @ 2008-08-15 23:35 周大俠 閱讀(196) | 評論 (1)編輯 收藏

                  Java中有關數據結構的類都在java.util包中,集合框架是每一個程序員都應該熟練掌握的一個類庫。Java的集合框架可以提供處理對象的標準方式。在很早的jdk版本中,只提供了Dictionary、Vector、Stack、Properties來存儲和操作對象。這些類之間沒有統一的api,使用這些類達不到易擴展的作用。
                  當然我們使用這些數據結構目的也是為了使用方便,能夠提供高效的存取。學過數據結構的朋友們都知道,鏈表和哈希表的結構的效率都是較高的。為了使用不同的集合之間能夠相互操作,相互擴展,那么使用通用的接口將是一個較好的選擇。所以整個集合框架被設計成了一系列的標準的接口。在Collections類中有許多靜態的算法方法。Iterator迭代器接口提供了通用的訪問集合元素的方式,因為每一個集合都實現了Iterator接口。除了集合,還提供了映射的接口和類。比方說Map就提供了存儲鍵值對。雖然它不是集合,但也被整合到了集合中。目前所有的集合都是基于泛型的。
                  下面介紹集合框架中的幾個常用的接口:
          1.Collection 允許處理一組對象,位于集合層次結構的頂部
          2.List  擴展Collection接口以處理序列
          3.Queue  擴展Collection接口以處理列表中的特殊類型,其元素只能從前面刪除
          4.Set  擴展Collection接口以處理集合,集合中的元素必須是唯一的
          5.SortedSet  擴展Set接口以處理排序的集合
          當然除了上述的接口外,集合中還使用Copmarator、Iterator、ListIterator等接口 。
                  Collection接口是構造集合框架的基礎,必須被定義集合的任意類實現,同樣它也是一個泛型接口。
          方法摘要
           boolean add(E o)
                    確保此 collection 包含指定的元素(可選操作)。
           boolean addAll(Collection<? extends E> c)
                    將指定 collection 中的所有元素都添加到此 collection 中(可選操作)。
           void clear()
                    移除此 collection 中的所有元素(可選操作)。
           boolean contains(Object o)
                    如果此 collection 包含指定的元素,則返回 true
           boolean containsAll(Collection<?> c)
                    如果此 collection 包含指定 collection 中的所有元素,則返回 true。
           boolean equals(Object o)
                    比較此 collection 與指定對象是否相等。
           int hashCode()
                    返回此 collection 的哈希碼值。
           boolean isEmpty()
                    如果此 collection 不包含元素,則返回 true。
           Iterator<E> iterator()
                    返回在此 collection 的元素上進行迭代的迭代器。
           boolean remove(Object o)
                    從此 collection 中移除指定元素的單個實例,如果存在的話(可選操作)。
           boolean removeAll(Collection<?> c)
                    移除此 collection 中那些也包含在指定 collection 中的所有元素(可選操作)。
           boolean retainAll(Collection<?> c)
                    僅保留此 collection 中那些也包含在指定 collection 的元素(可選操作)。
           int size()
                    返回此 collection 中的元素數。
           Object[] toArray()
                    返回包含此 collection 中所有元素的數組。
          <T> T[]
          toArray(T[] a)
                    返回包含此 collection 中所有元素的數組;返回數組的運行時類型與指定數組的運行時類型相同。
          List接口:
          該接口擴展了Collection接口,它聲明集合是存儲一個序列的元素。我們可以把它看成是動態數組。學過數據結構的朋友都知道,數組可以使用基于0的索引,對于泛型的List接口而言,他可以指定保存不同的對象類型。
          方法摘要
           boolean add(E o)
                    向列表的尾部追加指定的元素(可選操作)。
           void add(int index, E element)
                    在列表的指定位置插入指定元素(可選操作)。
           boolean addAll(Collection<? extends E> c)
                    追加指定 collection 中的所有元素到此列表的結尾,順序是指定 collection 的迭代器返回這些元素的順序(可選操作)。
           boolean addAll(int index, Collection<? extends E> c)
                    將指定 collection 中的所有元素都插入到列表中的指定位置(可選操作)。
           void clear()
                    從列表中移除所有元素(可選操作)。
           boolean contains(Object o)
                    如果列表包含指定的元素,則返回 true
           boolean containsAll(Collection<?> c)
                    如果列表包含指定 collection 的所有元素,則返回 true。
           boolean equals(Object o)
                    比較指定的對象與列表是否相等。
           E get(int index)
                    返回列表中指定位置的元素。
           int hashCode()
                    返回列表的哈希碼值。
           int indexOf(Object o)
                    返回列表中首次出現指定元素的索引,如果列表不包含此元素,則返回 -1。
           boolean isEmpty()
                    如果列表不包含元素,則返回 true
           Iterator<E> iterator()
                    返回以正確順序在列表的元素上進行迭代的迭代器。
           int lastIndexOf(Object o)
                    返回列表中最后出現指定元素的索引,如果列表不包含此元素,則返回 -1。
           ListIterator<E> listIterator()
                    返回列表中元素的列表迭代器(以正確的順序)。
           ListIterator<E> listIterator(int index)
                    返回列表中元素的列表迭代器(以正確的順序),從列表的指定位置開始。
           E remove(int index)
                    移除列表中指定位置的元素(可選操作)。
           boolean remove(Object o)
                    移除列表中出現的首個指定元素(可選操作)。
           boolean removeAll(Collection<?> c)
                    從列表中移除指定 collection 中包含的所有元素(可選操作)。
           boolean retainAll(Collection<?> c)
                    僅在列表中保留指定 collection 中所包含的元素(可選操作)。
           E set(int index, E element)
                    用指定元素替換列表中指定位置的元素(可選操作)。
           int size()
                    返回列表中的元素數。
           List<E> subList(int fromIndex, int toIndex)
                    返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之間的部分視圖。
           Object[] toArray()
                    返回以正確順序包含列表中的所有元素的數組。
          <T> T[]
          toArray(T[] a)
                    返回以正確順序包含列表中所有元素的數組;返回數組的運行時類型是指定數組的運行時類型。
          相對于Collection接口而言,List接口增加了add(int index, E element),add(int index,Collection c)方法,這些方法用于將元素插入到特定的位置,這也是動態數組的特性。
          Set接口:
          該接口擴展了Collection接口,但不允許有相同的存在的元素,而上述的List接口卻沒有此約束,其實很好理解,我們可以把它想象成數學中的集合,在那種集合中,是不允許有相同的元素的。
          SortedSet接口擴展了Set接口,此接口是升序的集合,由于是有序的,所有自然其中的數據元素是有意義的,否則升序的算法無從使用起。自然就不能存在為null的對象。下表是該接口特有的方法:
          方法摘要
           Comparator<? super E comparator()
                    返回與此有序集合關聯的比較器,如果使用元素的自然順序,則返回 null。
           E first()
                    返回此有序集合中當前第一個(最小的)元素。
           SortedSet<E> headSet(E toElement)
                    返回此有序集合的部分視圖,其元素嚴格小于 toElement
           E last()
                    返回此有序集合中最后一個(最大的)元素。
           SortedSet<E> subSet(E fromElement, E toElement)
                    返回此有序集合的部分視圖,元素范圍從 fromElement(包括)到 toElement(不包括)。
           SortedSet<E> tailSet(E fromElement)
                    返回此有序集合的部分視圖,其元素大于或等于 fromElement
          Queue接口:
          這個接口在1.4的版本中是沒有,新增的??疵志椭朗顷犃?,先進先出。
          方法摘要
           E element()
                    檢索,但是不移除此隊列的頭。
           boolean offer(E o)
                    如果可能,將指定的元素插入此隊列。
           E peek()
                    檢索,但是不移除此隊列的頭,如果此隊列為空,則返回 null。
           E poll()
                    檢索并移除此隊列的頭,如果此隊列為空,則返回 null
           E remove()
                    檢索并移除此隊列的頭。
          從隊列頂部刪除元素 。
          posted @ 2008-08-15 19:03 周大俠 閱讀(252) | 評論 (0)編輯 收藏

          2008年8月14日 #

                  AOP全稱叫做Aspect-Oriented Programming,即面向方面編程或叫做面向切面編程。目前基于java的開源框架有很多已經應用了AOP思想進行設計開發。在輕量級的J2EE應用開發中,AOP經??梢越鉀Q一些系統級的服務,比方說事務處理、安全檢查、系統日志等。
                  目前在AOP編程開發中,有許多新的名詞,這些名詞的出現會讓一些剛開始涉足AOP的朋友們是一頭霧水。下面我會把每個名詞的意思用自己的語言再描述一遍。
                  關注點:關注點即是需要我們去解決的去關心的問題。關注點又可分為核心關注點和橫切關注點。核心關注點指的是一個系統中的核心業務功能,也可以認為是是業務邏輯。橫切關注點指的是充斥在各個核心關注點間的可以解決同一類問題的的關注點。那么我們的系統也可以認為是由若干個關注點組成的。
                 連接點:連接點就是在程序運行時需要在某一點中插入切面,那一點就是連接點。這一點可以是一個方法、一個屬性、構造函數、類靜態初始化模塊。在Spring框架中,只關注方法的切面,即只關心的是方法連接點。
                  切入點:切入點其實就是連接點的集合。在Spring框架中我們經常可以看到利用正則表達式對切入點進行定義。
                  通知:通知其實就是一個切面的具體實現。比方說在一個業務訂單的處理中,切入了訂單處理的日志,那么這個日志的具體實現就是一個advice。比方說這個日志實現了某人某時間進行訂單的處理審批。那么通知有幾種。有前通知、后通知、環繞通知、當然Spring框架中還有Exception通知。
                  切面:上面講到的切入點與通知就是切面的組成部分。
                  引介:引介很強大,但是目前用的比較少。它可以強大到給一個定義好的類在運行時動態地添加方法、屬性。
                  織入:光有切面與核心關注點是不夠的,因為這樣兩者還沒有建立關系起來。那么織入的目的就是讓兩者建立起關系??椚胍灿腥N方式:
          1.通過Java代理實現織入。那么又有兩種方式。一種是基于代理接口的Java動態代理。另一種是動態字節碼生成器代理,也就是在spring中的經常發現的cglib.jar包。
          2.有些Aop的實現織入采用了自定義的類加載器,在虛擬機加載字節碼的時候進行織入。
          3.最后一種就是使用專門的編譯器來編譯整個應用程序,在編譯的過程中就進行織入。
                  攔截器:攔截器故名思意就是進行攔截。它可以對連接點進行攔截。那么攔截器也可以組成鏈通常也稱為棧。攔截器的說明可見我上一篇文章。
                 
                 
          未完待續!
          posted @ 2008-08-14 22:53 周大俠 閱讀(259) | 評論 (0)編輯 收藏

          2008年8月10日 #

               摘要:         本文為本人翻譯struts2的官方網站上的關于攔截器的說明文檔,官方網站上的說明均是英文的,不方便熱愛學習而英語又不太好的朋友。該說明文檔地址是http://struts.apache.org/2.0.11/docs/interceptors.html。     &nbs...  閱讀全文
          posted @ 2008-08-10 00:12 周大俠 閱讀(3149) | 評論 (3)編輯 收藏

          2008年7月29日 #

                  Unified Modeling Language 的出現給當今面向對象的世界增添了濃墨淡彩的一筆??梢暬慕9ぞ咦岄_發人員豐富地表達了他們的想象力,并且以uml的方式向其他人展示。
                  首先我們得理解什么是面向對象(Object Oriented)。對象是各種各樣的實體,即是具體的事物也是抽象的事物。面向對象不光是對對象的屬性和行為建模,它還包括其它方面。其中就有抽象、繼承、多態和封裝。抽象的概念很抽象,其意思是說抽象出你所需求的屬性和操作,即是所需的東西。它是一種從一般的觀點看事物的方法,焦點應該集中在事物的本質性質上,而不要過分地去追求細節,應該是抽象出一般化的東西。世界是復雜的,但不能因為它復雜就不去理解它,我們可以把它抽象化,其實抽象后世界也不大。
                   繼承:顧名思意就是子類擁有父類的所有的內部狀態和運動規律。公共的東西可以被子類分享,正所謂,子又有孫,孫又有子,子子孫孫無窮潰也。當然不能像這樣來設計。
                   多態:多個形態,同樣的一種動作,在不同的對象進行演繹的時候可能演繹的細節就會不一樣。正所謂大家都喜歡吃,但是男人吃飯跟女人吃飯就不一樣。男的可能吃的快吃的多,女的吃的少吃的慢,但大家都是吃這個動作,換了個對象來吃,就效果不一樣。
                   封裝:舉個例子,人們在看電視時,人們看到的是電視的屏幕,電視的按鈕,至于屏幕為什么上面會有美女,按下按鈕為什么會換臺,人們好象不必去關心其是怎么工作的吧,當然也有閑人喜歡鉆牛角尖。所以電視機就封裝了如何讓屏幕顯示美女的工作。那么電視機的按鈕和屏幕實際上就是電視機給我們這些喜歡看電視的人的接口。我們關心的也只是這些接口。至于這些接口怎么實現的,請交給廠家吧,世界也就是由若干個各司其職的人組成的。
                    重載:說白了就是做同一件事的幾種不同的方案。比方說:在公司加班,正常情況下,默認是吃盒飯,有一天老板歸來,來一句走出去吃飯我請。如果用方法來表示的話就是public void eat(盒飯類 a) public void eat(飯店類a ,老板類b )。
                    消息傳遞:在這個世界里,光有對象是不夠的,那樣人都是行尸走肉。對象之間是要相互協作的。那么相互協作之間是通過相互發送消息的方式。比方說看電視,我們使用遙控器打開電視。那么遙控器對象就向電視機對象發送了一個開機的消息。電視機對象接收了此消息后就打開了。
                    正如世界是一個由若干個對象以及對象之間的若干個錯綜復雜的關系組成的。那么對象與對象之間又會有什么樣的關系呢?打開電視時,我們說是你和電視機之間發了關聯關系。再比方說你暗戀一個女生,你跟她之間形成了一個單向的關聯關系。因為她不知道你暗戀她,當然你暗戀她,她也暗戀你的情況也有可能出現,此處我們不予探討。如果她也暗戀你,那就是一個雙向的關聯關系。對象之間的依賴關系說明是目標對象與源對象之間的依賴關系。依賴就是當目標對象有所變化的時候源對象也相應的發生改變。
                  收集系統需求時,把用戶的業務需求轉換成開發人員能夠理解的需求,并最終把需求轉化為代碼。通過將需求映射為代碼,可以保證代碼滿足這些需求,同時代碼也可以回溯成需求。這樣的過程就稱為建模。建模過程的結果可以跟蹤業務需求,到要求、到模型,到代碼的全過程及其相反的過程,而不會在這個過程中迷路。
                  可視化建模將模型中的信息用標準的圖形元素直觀的表示。這個標準的圖形元素就是本文中提到的UML。它的出現為用戶、開發人員、分析人員、測試人員、管理人員、需求調研人員等相關人員提供了溝通的橋梁。其中很直觀的例子:對于用戶來說,他更關心自己需要在這個系統中操作什么,以及這些操作是否滿足了自己的業務需要,那么利用模型他可以直觀的看到自己與這個系統的交互,根據這樣的交互保證需求的獲取。對于分析人員來說,他需要分析模型的對象之間的交互,以及這樣的交互是否滿足系統的需要,是否可以保證這樣的交互對于業務的解析,解決自己分析時存在的疑惑,同時也可以根據模型交互的結果向需求調研人員提出問題。對于開發人員來說,他要考慮開發的對象以及這些開發對象需要完成的工作。對于測試人員來說,他們根據模型看到對象間的交互并且根據這些交互以及交互的產出準備測試用例。在RUP中就可以同步地進行測試了,而不是像瀑布模型那樣最后才準備測試。對于項目管理人員來說,他需要看到系統中各個部分或者子系統之間的交互,在項目的實施過程根據計劃看到各個系統模型完成的情況及相應的進度。對于公司的主管人員來說可能只需要看到更高層的模型,看到各個子系統運行情況結果??梢暬慕4_實帶來了系統的可控。通過先建模再編寫代碼,從一開始就保證了系統的結構合理。利用模型可以更方便地捕獲設計缺陷,從而以較低的成本修正這些缺陷。
                  Rational Rose是分析和設計面向對象軟件系統的強大的可視化工具,可以用來先建模系統再編寫代碼,支持業務模型,幫助了解系統的業務,有助于系統分析,可以先設計使用案例和Use Case框圖,顯示系統的功能。也可以用Interaction框圖顯示對象之間如何配合,提供所需的功能。Calss框圖可以顯示系統中對象及其相互關系。Component框圖可以演示類如何映射到實現組件。最后Deployment框圖可以顯示系統的網絡結構。Rose模型的四個社圖是:Use Case視圖、Logical視圖、Component視圖和Deployment視圖。每個視圖針對不同對象,具有不同的用途。
                  Use Case視圖包括系統中的所有角色、使用案例和Use Case框圖,還包括一些Sequence或Collaboration框圖。該視圖是系統中與實現無關的視圖。該視圖關注系統功能的高層形狀,而不關注系統具體的實現方法。項目開始時,開發小組可以選擇使用Use Case視圖中生成業務模型,完成了業務模型后便是使用案例模型。客戶、分析人員和項目經理利用使用案例、Use Case框圖和使用案例文檔來確定系統的高層視圖。隨著項目的進行,開發小組的成員也可以通過Use Case視圖了解正在建立的系統的使用案例文檔,通過使用案例描述事件流程。利用Use Case視圖,測試人員開始編寫測試腳本,技術人員開始編寫文檔。一旦用戶同意了角色和使用案例,就確定了系統的范圍。然后可以在Logical視圖中繼續開發,關注系統如何實現使用案例中提出的功能。
                  Logical視圖,關注系統如何實現使用案例中提出的功能。提供系統的詳細圖形,描述組件間如何關聯,還包括特定的類、Class框圖和StateChart框圖,利用這些元素,開發人員可以構造出系統的詳細設計。該視圖關注的是系統的邏輯結構,在這個視圖中,要標識系統組件,檢查系統的信息和功能,檢查組件之間的關系。
                  Component視圖,包括模型代碼庫,可執行文件,運行庫和其他組件的信息。系統的Component視圖可以顯示代碼模塊間的關系。詳細包括:組件,代碼的實際模塊;Component框圖,顯示組件及其相互關系;包,相關組件的組。該視圖的主要用戶是控制代碼和編譯部署應用程序的人。有些組件是代碼庫,有些是運行組件。
                  Deployment視.圖,關注于系統的實際部署。還包括容錯,網絡帶寬,故障恢復和響應時間等。詳細包括:進程,是在自己的內存空間執行的線程;處理器,任何有處理功能的機器;設備,包括任何沒有處理功能的機器,如打印機。
                  下面討論UML以及UML的可視化工具給我們帶來了什么樣的好處。rose建立的業務模型關注系統針對的業務。業務模型包括:業務角色、業務用例、業務工人。業務模型研究的是業務的機構以及機構的角色。在建立業務模型的過程中,檢查機構的結構和機構中的角色以及它們之間的相互關系,還需要介紹機構的工作流,公司中的主要過程,以及這些過程如何的工作,效率如何,是否有任何的瓶頸。簡要的說就是要弄清楚業務的內部和外部,以及內外部如何進行通信。那么這些信息都將被記錄在業務模型中。業務模型中框圖有助于外部世界和機構的關系,以及機構如何完成這些目標。業務模型的主要工具之一是工作流框圖。這些框圖描述機構中的特定過程流程;顯示這個過程中參與的人員,這個過程的步驟和參與這個過程的業務實體。業務過程建模人員首先用工作流框圖建模當前過程,然后可以分析這些框圖,尋找工作流中的缺陷和其他問題。完成業務模型的好處在于開始規劃系統工作之前就完全了解了業務過程,這樣就可以事先確定最需要自動化的工作流領域和系統中最有助于機構開發的部分從而建立對公司或者機構最有利的系統。
                  實體類:實體類是要永久保存的信息。實體類通常在事件流和Interaction框圖中,是對用戶最有意義的類,通常用業務域術語來命名。邊界類:邊界類位于系統與外界的交界處,包括所以窗體、報表、打印機和掃描儀等硬件的接口以及與其他系統的接口。要尋找和定義邊界類,可以檢查Use Case框圖。每個角色/用例 交互至少要有一個邊界類??刂祁悾嚎刂祁愗撠焻f調其它類的工作。每個用例通常都有一個控制類,控制用例中的事件的順序。在Interaction框圖中,控制類具有協調責任。
                 
           



















                  
                 
          posted @ 2008-07-29 22:51 周大俠 閱讀(178) | 評論 (0)編輯 收藏

          2008年7月28日 #

          SpringapplicationContext.xml中配置映射文件的方法:
          1。減少配置文件里配置信息的數量
          配置applicationContext.xml或者分布在其它的xml文件中的bean時,設置bean與bean之間的相互依賴關系是一件痛苦且容易出錯的事。autowire屬性的出現減輕了配置文件的容量。
          <bean>的autowire屬性有6個值。分別為:

          No:即不啟用自動裝配。Autowire默認的值。

          byName:通過屬性的名字的方式查找JavaBean依賴的對象并為其注入。
          byType:通過屬性的類型查找JavaBean依賴的對象并為其注入。
          constructor:通byType一樣,也是通過類型查找依賴對象。
          autodetect:在byTypeconstructor之間自動的選擇注入方式。
          default:由上級標簽<beans>default-autowire屬性確定。
          在<beans default-autowire="byName">可以為本xml文件設置默認的自動裝配的類型例如byName,當然在設置具體的<bean id="***" class="***" autowire="byType">時,會自動改變默認的byName為byType。
          2。在web.xml中通過配置如下參數

              <context-param>
                  <param-name>contextConfigLocation</param-name>
                  <param-value>classpath*:spring/*.xml</param-value>
              </context-param>   
          會自動把WEB-INF/classes/sring目錄下的所有以.xml結尾的文件加載spring容器進行管理,而不必手動編寫每個applicationContex.xml,accessContext.xml等配置文件。
          3。利用屬性為mappingDirectoryLocation來配置相關的目錄位置,從而避免為該目錄下的所有文件名進行配置
          <property name="mappingDirectoryLocation">
          <list>
          <value>classpath:/package1/<value>
          </list>
          </property>
          如:
          <!-- 設置Hibernate3的SessionFactory -->
              <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
                  <property name="dataSource">
                      <ref bean="dataSource"/>
                  </property>
                  <property name="hibernateProperties">
                      <props>
                          <prop key="hibernate.dialect">net.sf.hibernate.dialect.SQLServerDialect</prop>
                          <prop key="hibernate.show_sql">true</prop>
                          <prop key="hibernate.generate_statistics">true</prop>
                          <prop key="hibernate.connection.release_mode">auto</prop>
                          <prop key="hibernate.autoReconnect">true</prop>
                      </props>
                  </property>
                  <property name="mappingDirectoryLocations">       
                      <list>      
                         <value>classpath:com/apache/model</value>      
                      </list>
                  </property>   

              </bean>
          4。消除ProxyFactoryBean的繁重配置
          a.通過繼承于parent ProxyFactoryBean
          b.使用aop自動代理的方式
          在Spring中進行事務的管理均是基于aop的方式,為每個需要事務管理的bean均設定相應的ProxyFactoryBean又是一件非常繁重的工作。使用自動代理可以消除這樣的重復的工作。方法如下,聲明DefaultAdvisorAutoProxyCreator為所有的advisor作為代理,在context上下文中查找所有的advisor,然后自動代理那些被在pointcut加入了切面的bean。針對事務使用spring中的事務的advisor,TransactionAttributeSourceAdvisor。
          該advisor有兩種方式進行注入,一種是setter方式,如下:
              <!-- 配置自動代理事務 -->
              <bean id="transactionAdvisor" class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
                  <property name="transactionInterceptor" ref="transactionInterceptor"/>
              </bean>
          另一種是constructor方式,如下:
              <!-- 配置自動代理事務 -->
              <bean id="transactionAdvisor" class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
               <constructor-arg>
                  <ref bean="transactionInterceptor"/>
               </constructor-arg>        
              </bean>
          建議以constructor方式進行注入。

          posted @ 2008-07-28 23:04 周大俠 閱讀(216) | 評論 (0)編輯 收藏

           

          系統實現規范:以面向接口的方式進行編程。
          下圖為三層邏輯結構的簡易關系圖

           

           

          以上是簡易的系統邏輯結構,
          ***Action繼承于xworkSupportAction,通過Spring來進行管理,在整個Spring的容器中,Spring負責管理整個系統的所有Bean,并負責初始化Bean之間的依賴關系。***Action中注入了服務層對象***ServiceImpl,ServiceImpl又注入了***DaoImpl對象。下面會逐步細化上面的關系圖。

          先看下面的web.xml配置

          web.xml

              <display-name>Struts Blank</display-name>

              <context-param>

                  <param-name>webAppRootKey</param-name>

                  <param-value>wxy.root</param-value>

              </context-param>

              <!-- spring xml文件配置目錄在class目錄下的spring目錄中WEB-INF/classes/spring -->

              <context-param>

                  <param-name>contextConfigLocation</param-name>

                  <param-value>classpath*:spring/*.xml</param-value>

              </context-param>

              <!-- 配置log4j的日志信息WEB-INF/classes/config/log4j.properties -->

              <context-param>

                  <param-name>log4jConfigLocation</param-name>

                  <param-value>classpath*:config/log4j.properties</param-value>

              </context-param>

              <!-- 配置Character Encoding Filter -->

              <filter>

                  <filter-name>encodingFilter</filter-name>

                  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

                  <init-param>

                      <param-name>encoding</param-name>

                      <param-value>UTF-8</param-value>

                  </init-param>

              </filter>

              <!-- 配置Struts2 -->

              <filter>

                  <filter-name>struts2</filter-name>

                  <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>

              </filter>

              <filter-mapping>

                  <filter-name>encodingFilter</filter-name>

                  <url-pattern>/*</url-pattern>

              </filter-mapping>

              <filter-mapping>

                  <filter-name>struts2</filter-name>

                  <url-pattern>/*</url-pattern>

              </filter-mapping>

             

              <welcome-file-list>

                  <welcome-file>index.html</welcome-file>

              </welcome-file-list>

              <!-- 載入Spring ApplicationContext -->

              <listener>

                  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

              </listener>

              <!-- Spring 刷新Introspector防止內存泄漏 -->

              <listener>

                  <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>

              </listener>
          未完待續.

           
          posted @ 2008-07-28 22:15 周大俠 閱讀(223) | 評論 (0)編輯 收藏

          2008年6月18日 #

                  一個軟件的開發是一個極其復雜的過程,其中設計分析,設計、編碼、測試、維護等,而系統分析卻往往是一個軟件成敗的關鍵。
                  如何進行系統分析,以及如何傳遞分析的的結果文檔等,又是系統分析師的首要任務。系統分析對于任何人來說都不是容易 ,它沒有規則的限定,它需要系統分析師的應變,雖然有相應的指導,但指導往往是教課書般,沒有一個項目一塵不變地去原用教課書上的東西,更多的是經驗。
                  系統分析的成品即軟件需求分析說明書,此書到底需要包括什么內容,到底是什么。這個問題很難回答,也許有很多人不加思索地可以答出,但我認為這個問題很難。這個由不同公司不同項目的具體情況決定的。從我的角度來看我覺得這個文檔中的內容要走夠設計師們看懂并可以作出設計。既然是為設計作打算,那么設計需要什么內容呢,這又涉及到設計方面的東西。
                  需求來源于用戶的一些“需要”,這些“需要”被分析,確認后形成完整的文檔,該文檔詳細地說明了產品必須或應當做什么。如果只有一些零碎的對話、資料或郵件,就認為掌握了需求,那就是自欺欺人。需求是一個產品的源頭,它的好壞對產品的影響最大,就像一條河流,如果源頭被污染了,那么整條河流就被污染了。“用戶”是一種泛稱,可分為“客戶”,最終用戶或間接用戶。需求分為兩類,一類屬于需求開發,另一類屬于需求管理。需求開發分為需求調查、需求分析和需求定義。需求管理分為需求確認、需求跟蹤和需求變更控制。需求開發的目的是通過調查與分析,獲取用戶需求并定義產品需求。需求調查的目的是通過各種途徑獲取用戶的需求信息,產生《用戶需求說明書》。需求分析的目的是對各種需求信息進行分析,消除錯誤,刻畫細節等,常見的需求分析方法有“問答分析法”和“建模分析法”等。需求定義的目的是根據需求調查和需求分析的結果進一步定義準確無誤的產品需求,產生《產品需求規格說明書》,系統設計人員依據《產品需求規格說明書》開展系統設計工作。需求管理的目的是在客戶與開發方之間建立對需求的共同理解,維護需求與其它工作成果的一致性,并控制需求的變更。需求確認是指在開發方和客戶共同對需求文檔進行評審,雙方對需求達成共識后作出書面承諾,使需求文檔具有商業合同效果。需求跟蹤是指通過比較需求文檔和后續工作之間的對應關系,建立與維護“需求跟蹤矩陣”,確保產品依據需求文檔進行開發。需求變更控制是指依據“變更申請—審批—更改—重新確認”的流程處理需求的變更,防止需求變更失去控制而導致項目發生混亂。
                   如何進行需求分析是需求調研中最重要的一步。需求分析是指在需求開發過程中,對所獲取的需求信息進行分析,及時排除錯誤和彌補不足,確保需求文檔正確的反映用戶的真實意圖。分析方法大體有兩類:“問答分析法”和“建模分析法”。問答分析法:刨根究底地問,如果問題都被解答了,那么需求也就分析清楚了。建模分析法是指用圖形符號來表示、刻畫需求。
                   在系統分析中,用例的重要性不用多說。真正理解了用例,懂得利用用例來驅動項目的開發,才能真正把握住需求的精髓。每個用例是一組場景的集合,而每個場景又是一個步驟序列。用例圖通常是供客戶和開發組參考的設計文檔的一部分。用例之間可以以兩種方式相互關聯,一種方式是包含,即在一個用例中重用另一個用例中的步驟。另一種方式叫擴展,允許通過對已有用例增加步驟創建一個新的用例。用例之間的另外兩種關系是泛化和分組。泛化是指一個用例繼承了另一個用例。分組是一組用例的簡單組織方式。 
                 用例可以解釋為某個參與者要做的一件事。也可以解釋為一系列完成一個特定目標的“功能”的組合。這一件事可以解釋為:1.這件事是相對獨立的。它不需要與其他用例交互而獨自完成參與者的目的。2.這件事的執行結果對于參與者來說是可觀測的和有意義的。3.這件事必須由一個參與者發起,不存在沒有參與者的用例。4這件事是以短賓短語出現。即這件事必須有一個動作和動作的受體。用例的背后是一種需求方法論。用例的核心是以參與者為核心,從參與者的角度描述他的日常工作,并分析這些日常工作是如何交互的。用例的首要目的不是要弄清楚某項業務是如何一步步完成的,而是要弄清楚有多少參與者?每個參與者都做什么?
                   需求分析需要經過業務建模、用例分析和系統建模三部分組成。1.業務建模的目標是通過用例模型的建立來描述用戶需求,需求規格說明書通常在這個階段產生。2.用例分析是分析員用OO的方法來分析業務用例的過程,這個階段稱為概念模型階段,這個階段通常使用無類型的用例。3.系統建模是將用戶的業務需求轉化為計算機實現的過程,這個階段通常使用無類型的用例和用例實現兩種類型。系統范圍、項目計劃和系統架構通常在這個階段形成雛形。業務用例(business usecase),是用來描述用戶原始需求的,它的含義是站在用戶的角度,使用用戶的業務術語來描述用戶在其領域所做的事。業務用例命名,描述都必須采用純業務語言,不能出現計算機術語。業務模型是系統分析員和用戶討論需求,達到一致理解的基礎。只有完成下面的工作,才能算是業務模型已經建立完成。1.發現和定義
                 
          posted @ 2008-06-18 11:35 周大俠 閱讀(397) | 評論 (0)編輯 收藏

          2008年6月15日 #

          1.使用@AspectJ標簽
             在AspectJ5中增加了對Java5注解的完全支持,可以使用Java注解來取代專門的AOP語法,把普通的Java類(POJO)聲明為切面模塊。使用<aop:aspectj-autoproxy/>來開啟在POJO中通過注解來標識切面模塊的識別功能。但目前Spring只支持其中部分標簽,包括@Before,@AfterReturning,@AfterThrowing,@After,@Around等幾種。
          2.基于Schema模式配置Spring AOP
          通過Spring配置文件中通過AspectJ切入點語言表達式來定義切入點,并配置相關的增強Advice實現方法
          <aop:config>
              <aop:pointcut id="somePointcut" ../>
              <aop:advisor id="someAdvisor" ../>
              <aop:aspect id="someAspect" ref="someBean">
                  <aop:adviceType id="someAdvice" ../>
              </aop:aspect>
          </aop:config>
          3.基于Spring API的配置文件
          包括如下內容:
          1.0個或多個切入點定義Bean,必須實現Pointcut接口
          2.1個或多個通知實現Bean,必須實現Advice接口
          3.0個或多個引介Bean,實現IntroductionInfo接口
          4.1個或多個切面封裝Bean,必須實現Advisor接口
          5.1個或多個真實業務Bean
          6.1個或多個代理Bean
          posted @ 2008-06-15 16:53 周大俠 閱讀(3551) | 評論 (0)編輯 收藏

          僅列出標題  下一頁
          主站蜘蛛池模板: 阿拉善左旗| 全州县| 曲麻莱县| 正阳县| 松溪县| 邵武市| 博罗县| 武安市| 萨嘎县| 内黄县| 宾阳县| 吉隆县| 宁蒗| 乐平市| 定陶县| 高唐县| 衡南县| 淮阳县| 新宁县| 大安市| 灵石县| 安平县| 贺兰县| 钦州市| 砀山县| 阿合奇县| 白银市| 天峨县| 呼伦贝尔市| 柘城县| 葵青区| 成武县| 微博| 福鼎市| 贵南县| 道真| 保定市| 襄樊市| 邛崃市| 定结县| 伽师县|