OA系統(tǒng)項目及項目及項目開發(fā)_第1頁
OA系統(tǒng)項目及項目及項目開發(fā)_第2頁
OA系統(tǒng)項目及項目及項目開發(fā)_第3頁
OA系統(tǒng)項目及項目及項目開發(fā)_第4頁
OA系統(tǒng)項目及項目及項目開發(fā)_第5頁
已閱讀5頁,還剩45頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

OA系統(tǒng)項目開發(fā)UML小結(jié)以及基于領(lǐng)域模型的系統(tǒng)設(shè)計初步UML不是OOA/D也不是方法,它僅僅是一種圖形表示法。其目的就是讓人能看懂你的東西。每一種圖,都相當(dāng)于一種角度。不同的圖就是從不同角度來觀察系統(tǒng)。比如交通圖和行政區(qū)劃圖,從不同角度觀察中國。必要性是畫圖的原則,雖然有這種關(guān)系,但不一定要畫出來,如果非要畫出來,則應(yīng)考慮不要影響圖形的美觀。活動圖活動圖表示的是一種流程。例子:順序圖順序圖的目的是為對象分配職責(zé),而不是步驟的羅列。上圖中,ActionServlet是沒有必要畫出來的,它是一個很穩(wěn)定,也不是我們自己提供的,沒有必要來說明它的對象職責(zé)。插在這里顯然多余.如下圖這樣就可以了:用例和用例圖用例的定義:文本形式的情節(jié)描述。用例用于需求的發(fā)現(xiàn)和記錄,它會影響后續(xù)的OOA/D工作用例不是用例圖。用例圖不重要,用例描述很重要。用例盡量不要用名詞命名,盡量以動詞開頭,比如:管理商品。用例一般是用于功能性的需求而非性能性需求。編寫用例時,在基本路徑(即主成功路徑)中,只書寫主要的成功事件,而可能出現(xiàn)的其他情況(如找不到用戶)應(yīng)該寫在擴(kuò)展點(diǎn)中。用例粒度:比如:是把管理用戶當(dāng)做用例還是把添加用戶和刪除用戶分別當(dāng)做兩個用例。確定用例的粒度時,應(yīng)該考慮描述這個用例的基本路徑需要幾個步驟。十步以內(nèi),七八步比較合適。一個典型的用例描述一個典型用例圖其中銷售經(jīng)理和收銀員之關(guān)系是泛化關(guān)系,即經(jīng)理擁有收銀員所擁有的一切用例。另外還有其獨(dú)有的用例。類圖類圖允許我們標(biāo)記靜態(tài)內(nèi)容及類之間的關(guān)系,它是UML中最重要的圖形,可以在任何時候嘗試使用類圖。不要使用類圖描述所有的細(xì)節(jié),保持類圖的簡單。UML中主要有三種類:邊界類、控制類和實體類邊界類位于系統(tǒng)與外界的交界處,例如窗體、報表、以及表示通訊協(xié)議的類、直接與外部設(shè)備交互的類、直接與外部系統(tǒng)交互的類等。通過用例圖可以確定需要的邊界類,每個Actor/UseCase對至少要一個邊界類,但并非每個Actor/UseCase對要唯一的邊界類。實體類可以通過事件流和交互圖發(fā)現(xiàn)。通常每個實體類在數(shù)據(jù)庫中有相應(yīng)的表,實體類中的屬性對應(yīng)數(shù)據(jù)庫表中的字段??刂祁愂强刂破渌惞ぷ鞯念???刂祁惪梢员欢鄠€用例共用。其他類并不向控制類發(fā)送很多消息,而是由控制類發(fā)出很多消息。類圖中,要畫出類之間的關(guān)系UML中繼承、實現(xiàn)、依賴、關(guān)聯(lián)、聚合、組合的聯(lián)系與區(qū)別繼承(也叫泛化)指的是一個類(稱為子類、子接口)繼承另外的一個類(稱為父類、父接口)的功能,并可以增加它自己的新功能的能力,繼承是類與類或者接口與接口之間最常見的關(guān)系;在Java中此類關(guān)系通過關(guān)鍵字extends明確標(biāo)識,在設(shè)計時一般沒有爭議性;實現(xiàn)指的是一個class類實現(xiàn)interface接口(可以是多個)的功能;實現(xiàn)是類與接口之間最常見的關(guān)系;在Java中此類關(guān)系通過關(guān)鍵字implements明確標(biāo)識,在設(shè)計時一般沒有爭議性;依賴可以簡單的理解,就是一個類A使用到了另一個類B,而這種使用關(guān)系是具有偶然性的、臨時性的、非常弱的,但是B類的變化會影響到A;比如某人要過河,需要借用一條船,此時人與船之間的關(guān)系就是依賴;表現(xiàn)在代碼層面,為類B作為參數(shù)被類A在某個method方法中使用;關(guān)聯(lián)他體現(xiàn)的是兩個類、或者類與接口之間語義級別的一種強(qiáng)依賴關(guān)系,比如我和我的朋友;這種關(guān)系比依賴更強(qiáng)、不存在依賴關(guān)系的偶然性、關(guān)系也不是臨時性的,一般是長期性的,而且雙方的關(guān)系一般是平等的、關(guān)聯(lián)可以是單向、雙向的;表現(xiàn)在代碼層面,為被關(guān)聯(lián)類B以類屬性的形式出現(xiàn)在關(guān)聯(lián)類A中,也可能是關(guān)聯(lián)類A引用了一個類型為被關(guān)聯(lián)類B的全局變量;聚合聚合是關(guān)聯(lián)關(guān)系的一種特例,他體現(xiàn)的是整體與部分、擁有的關(guān)系,即has-a的關(guān)系,此時整體與部分之間是可分離的,他們可以具有各自的生命周期,部分可以屬于多個整體對象,也可以為多個整體對象共享;比如計算機(jī)與CPU、公司與員工的關(guān)系等;表現(xiàn)在代碼層面,和關(guān)聯(lián)關(guān)系是一致的,只能從語義級別來區(qū)分;組合組合也是關(guān)聯(lián)關(guān)系的一種特例,他體現(xiàn)的是一種contains-a的關(guān)系,這種關(guān)系比聚合更強(qiáng),也稱為強(qiáng)聚合;他同樣體現(xiàn)整體與部分間的關(guān)系,但此時整體與部分是不可分的,整體的生命周期結(jié)束也就意味著部分的生命周期結(jié)束;比如你和你的大腦;表現(xiàn)在代碼層面,和關(guān)聯(lián)關(guān)系是一致的,只能從語義級別來區(qū)分;總結(jié):繼承、實現(xiàn)體現(xiàn)的是類與類、或者類與接口間的縱向關(guān)系,不易混淆;其他的四者關(guān)系則體現(xiàn)的是類與類、或者類與接口間的引用、橫向關(guān)系,這幾種關(guān)系都是語義級別的,所以從代碼層面并不能完全區(qū)分開來;例如在關(guān)心汽車的領(lǐng)域里,輪胎是一定要組合在汽車類中的,因為它離開了汽車就沒有意義了。但是在賣輪胎的店鋪業(yè)務(wù)里,就算輪胎離開了汽車,它也是有意義的,這就可以用聚合了??偟膩碚f,后幾種關(guān)系所表現(xiàn)的強(qiáng)弱程度依次為:組合>聚合>關(guān)聯(lián)>依賴示例一關(guān)聯(lián)之特殊示例,下圖表示一種樹形結(jié)構(gòu)類圖,可以用如下代碼實現(xiàn)PublicClassNode{PublicID;PrivateNodeparent;PrivateSet<Node>children;}示例二:已經(jīng)在關(guān)聯(lián)中表明了Document具有一個User類型的字段Creator,故不必在Document中再寫出Creator了。示例三:由于User是另一個復(fù)雜的概念,所以要建立關(guān)聯(lián),而不是把User也作為一個簡單的屬性(如name那樣)不要把復(fù)雜的領(lǐng)域概念建模為屬性。示例四:Student與class之間是雙向關(guān)聯(lián)關(guān)系,當(dāng)然也可以說成是student依賴class,因為沒有class,student是不能編譯通過的。但畫圖并不是所有存在的東西都要畫出來,這里表示成關(guān)聯(lián)關(guān)系更為貼切些。另外,關(guān)聯(lián)指的是關(guān)心對方的結(jié)構(gòu),如果對象A只是用一用對象B的某個方法,比如(),這顯然是依賴而非關(guān)聯(lián)?;陬I(lǐng)域模型的系統(tǒng)設(shè)計初步設(shè)計時重要原則:低耦合,高內(nèi)聚.盡量降低對不穩(wěn)定對象的依賴。對于非常穩(wěn)定的東西,比如JDK的核心類庫,盡可以隨便依賴它。不要依賴于正向工程和逆向工程,如果你要讓其從圖形生成代碼,則你不得不在圖形中注意各種細(xì)節(jié),那不如你自己寫代碼。圖形是為了抽象出邏輯主干,方便人理解,它不能替代詳細(xì)完整的文字描述。系統(tǒng)的核心價值領(lǐng)域模型的價值不在于它的設(shè)計優(yōu)美(它只是一些對象﹐最重要的也就是對象之間的關(guān)系)﹐而在于它體現(xiàn)了系統(tǒng)的核心價值。什么是系統(tǒng)的核心價值呢我想我們的圖書館系統(tǒng)和華爾街的一個商業(yè)系統(tǒng)本質(zhì)的區(qū)別不在于系統(tǒng)用了什么語言、用了什么數(shù)據(jù)庫、用的是OO還是過程,而在于系統(tǒng)能為使用者提供什么服務(wù),以及提供的質(zhì)量。這些通過系統(tǒng)的運(yùn)行方式﹐系統(tǒng)的運(yùn)行過程﹐系統(tǒng)的業(yè)務(wù)邏輯來體現(xiàn)。用例的價值系統(tǒng)分析員在接手一個系統(tǒng)后﹐首先要做到的事情就是得出系統(tǒng)的服務(wù)和服務(wù)場景。也就是我們經(jīng)常所講的用例(usecase)很多人不清楚清晰的用例的價值,只是因為看別人有漂亮的圖形,所以自己也畫一個,其實自己都不去看它。這樣的用例分析只能糊弄一下老板,給別人show一下Demo﹐而不會對系統(tǒng)開發(fā)什么實質(zhì)作用。用例表示的是使用系統(tǒng)的一個場景﹐其本質(zhì)在于詳細(xì)描述了系統(tǒng)用戶(actor)與系統(tǒng)是如何交互的﹐以及交互的后果是什么﹐詳細(xì)而完善的用例將指導(dǎo)您進(jìn)行系統(tǒng)開發(fā)的全過程低耦合的設(shè)計系統(tǒng)對象除了與領(lǐng)域模型、用戶打交道以外﹐它還會與系統(tǒng)的其它模塊交互。如持久化系統(tǒng)、日志系統(tǒng)、信息通知系統(tǒng)(您不能因為用戶要求由郵件通知改為短信通知就修改領(lǐng)域模型吧),當(dāng)然還有UI,這些屬于系統(tǒng)核心(領(lǐng)域模型)以外的東西。這些模塊不該參雜進(jìn)業(yè)務(wù)邏輯中。應(yīng)該在邊界與這些模塊進(jìn)行接觸。例子:Publicvoid借閱(){借閱處理者處理者=new借閱處理者(當(dāng)前書籍﹐當(dāng)前登錄人姓名);Boolsuccessful=處理者.借閱()dd(當(dāng)前書籍);日志系統(tǒng).add日志(當(dāng)前當(dāng)籍,”借閱”)郵件系統(tǒng).發(fā)送郵件(當(dāng)前書籍.當(dāng)前借書人姓名)}}dd(書籍當(dāng)前書籍){借閱關(guān)系Bbb=new借閱關(guān)系=產(chǎn)生ID()Bbb.圖書ID=當(dāng)前書籍.id;Bbb.借閱人=當(dāng)前書籍.借閱記錄.借閱人姓名Bbb.借閱時間=當(dāng)前書籍.借閱記錄.借閱時間();}在現(xiàn)實系統(tǒng)中﹐我在if(successful)這里作了一些純軟件設(shè)計﹐如利用C#具有Event特性﹐將借閱方法后公開出一個事件﹐這樣我在再要添加什么外圍模聲時﹐只要響應(yīng)事件就可以了﹐不需要再來動這個方法。其它模塊處理過程類似。業(yè)務(wù)過程是系統(tǒng)的核心,其他模塊都依賴于它而存在。一個系統(tǒng)要變更業(yè)務(wù)邏輯﹐我們只要針對領(lǐng)域模型作變化即可﹐再也不需要抱怨變化了OA_6_利用Rose創(chuàng)建各種組織機(jī)構(gòu)的uml圖形

OA6:利用Rose創(chuàng)建各種組織機(jī)構(gòu)的uml圖形(.mdl)。根據(jù)需求建立模型職能型組織機(jī)構(gòu)包括樹形和直線型(集權(quán)型)抽象出Party,可以復(fù)用一些公共的屬性將樹形結(jié)構(gòu)關(guān)聯(lián)轉(zhuǎn)移到Party,可以同時支持Person和Orgnization的樹形結(jié)構(gòu)

混合型組織機(jī)構(gòu)矩陣型組織機(jī)構(gòu)(網(wǎng)狀組織機(jī)構(gòu))

在需求分析中這幾種關(guān)系最重要OA項目屬于職能型(一)組織機(jī)構(gòu)管理(struts)Action與頁面要注意的細(xì)節(jié)頁面所需要的信息,參數(shù),必須要在Acion里面定義好,否則頁面取不出數(shù)據(jù),Action主要負(fù)責(zé)頁面數(shù)據(jù)的搜集publicclassOrgActionextendsActionSupport{ /** * */ privatestaticfinallongserialVersionUID=1L; privateOrgManagerorgManager; privateListorgs; privateintparentId;ut("orgs",orgs); return"index"; } publicStringaddInput(){ return"add_input"; } publicStringadd(){ return"add_success"; } publicStringdel(){ return"del_success"; } }要注意當(dāng)查詢頂級機(jī)構(gòu)下的,數(shù)據(jù)存的的pid=null;必須進(jìn)行下面的控制,否則會查不出來Stringhql="selectofromOrganazationowhere"+parentId; if(parentId==0){ hql="selectofromOrganazationowhereisnull"; }Action里面的最核心的方法,這要一轉(zhuǎn)到Action就會調(diào)用此方法,此方法里面的參數(shù)parentId也會改變publicStringexecute()throwsException{ ut("orgs",orgs); return"index"; }頁面向下導(dǎo)航顯示父機(jī)構(gòu)下的所有的子機(jī)構(gòu)只需要在頁面要導(dǎo)航的地方加超鏈接,跟上要傳的參數(shù)<tdalign="center"vAlign="center"><s:propertyvalue="id"/></td> <tdalign="center"vAlign="center"><ahref="parentId=<s:propertyvalue="id"/>"><s:propertyvalue="name"/></a>  </td>ERRORLazyInitializationException 懶加載異常出現(xiàn)錯誤的地方頁面<tdalign="center"vAlign="center"><s:propertyvalue="#"/></td>無法顯示由于hibernate中SessionFactory是線程安全的,而其創(chuàng)建出來的session非線程安全,不能獲取線程安全的懶加載類解決辦法:配置session過濾器 <filter> <filter-name>OpenSessionInViewFilter</filter-name> <filter-class> </filter> <filter-mapping> <filter-name>OpenSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>注意配置的位置:配置的位置要先于Struts的filter配置文件,否則要受到struts過濾器的影響,Session的過濾器則會無效頁面的參數(shù)以及提交問題<ahref="#"onclick="openWin('org!parentId=<s:propertyvalue="parentId"/>','addOrg',600,200);"><s:formaction="org!"method="post">在Action方法中搜集不到參數(shù)parentId,哪個方法的actiion傳參數(shù),Action中的對應(yīng)的方法才能收到相應(yīng)的參數(shù),所以在開發(fā)中要注意哪些參數(shù)能在方法中取得,要注意表單提交要完全成功,Action里面才能搜集到數(shù)據(jù)頁面出現(xiàn)亂碼的解決在配置文件中配置不管用Spring過濾器不管用 <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class> <init-param> <param-name>encoding</param-name> <param-value>GBK</param-value> </init-param></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>只有配置Struts的字符過濾器才管用 <constantname=""value="GBK"></constant>分頁框架需要引入分頁框架當(dāng)點(diǎn)擊頁面跳轉(zhuǎn)的時候,地址欄會自動傳參數(shù),但是Action中要定義與之一樣的接收參數(shù)的屬性否則拿不到參數(shù)offsetPersonAction。JavapublicclassPersonActionextendsActionSupport{ /** * */ privatestaticfinallongserialVersionUID=1L; privatePersonManagerpersonManger; privatePageModelpager; privatePersonperson1; publicPersongetPerson1(){ returnperson1; } publicvoidsetPerson1(Personperson1){ =person1; } @Override publicStringexecute()throwsException{ ut("pm",pager); return"index"; } publicStringaddInput(){ return"add_input"; } publicStringadd(){ return"pub_add_success"; } publicStringdel(){ return"pub_del_success"; } publicStringselectFlag(){ return"selectFlag"; } publicPersonManagergetPersonManger(){ returnpersonManger; } publicvoidsetPersonManger(PersonManagerpersonManger){ =personManger; } publicPageModelgetPager(){ returnpager; } publicvoidsetPager(PageModelpager){ =pager; } }專用的分頁<%@tagliburi="tags/navigation/pager"prefix="pg"%><%@pagelanguage="java"contentType="text/html;charset=GB18030"pageEncoding="GB18030"%><%@taglibprefix="s"uri="/struts-tags"%><%@taglibprefix="c"uri=""%><!DOCTYPEhtmlPUBLIC"-etId(); } }異常處理首先定義好一個異常類,讓其繼承RunnableException,讓后定義好一個錯頁面頁面如下<%@pagelanguage="java"contentType="text/html;charset=GB18030"pageEncoding="GB18030"%><!DOCTYPEhtmlPUBLIC"-主型訪問控制方法。目前在我國的大多數(shù)的信息系統(tǒng)中的訪問控制模塊中基本是借助于自主型訪問控制方法中的訪問控制列表(ACLs)。

2.強(qiáng)制型訪問控制方法。用于多層次安全級別的軍事應(yīng)用。

3.基于角色的訪問控制方法(RBAC)。是目前公認(rèn)的解決大型企業(yè)的統(tǒng)一資源訪問控制的有效方法。其顯著的兩大特征是:1.減小授權(quán)管理的復(fù)雜性,降低管理開銷。2.靈活地支持企業(yè)的安全策略,并對企業(yè)的變化有很大的伸縮性。

名詞:

粗粒度:表示類別級,即僅考慮對象的類別(thetypeofobject),不考慮對象的某個特

定實例。比如,用戶管理中,創(chuàng)建、刪除,對所有的用戶都一視同仁,并不區(qū)分操作的具體對象實例。

細(xì)粒度:表示實例級,即需要考慮具體對象的實例(theinstanceofobject),當(dāng)然,細(xì)

粒度是在考慮粗粒度的對象類別之后才再考慮特定實例。比如,合同管理中,列表、刪除,需要區(qū)分該合同實例是否為當(dāng)前用戶所創(chuàng)建。

原則:

權(quán)限邏輯配合業(yè)務(wù)邏輯。即權(quán)限系統(tǒng)以為業(yè)務(wù)邏輯提供服務(wù)為目標(biāo)。相當(dāng)多細(xì)粒度的權(quán)限問題因其極其獨(dú)特而不具通用意義,它們也能被理解為是“業(yè)務(wù)邏輯”的一部分。比如,要求:“合同資源只能被它的創(chuàng)建者刪除,與創(chuàng)建者同組的用戶可以修改,所有的用戶能夠瀏覽”。這既可以認(rèn)為是一個細(xì)粒度的權(quán)限問題,也可以認(rèn)為是一個業(yè)務(wù)邏輯問題。在這里它是業(yè)務(wù)邏輯問題,在整個權(quán)限系統(tǒng)的架構(gòu)設(shè)計之中不予過多考慮。當(dāng)然,權(quán)限系統(tǒng)的架構(gòu)也必須要能支持這樣的控制判斷。或者說,系統(tǒng)提供足夠多但不是完全的控制能力。即,設(shè)計原則歸結(jié)為:“系統(tǒng)只提供粗粒度的權(quán)限,細(xì)粒度的權(quán)限被認(rèn)為是業(yè)務(wù)邏輯的職責(zé)”。

需要再次強(qiáng)調(diào)的是,這里表述的權(quán)限系統(tǒng)僅是一個“不完全”的權(quán)限系統(tǒng),即,它不提供所有關(guān)于權(quán)限的問題的解決方法。它提供一個基礎(chǔ),并解決那些具有“共性”的(或者說粗粒度的)部分。在這個基礎(chǔ)之上,根據(jù)“業(yè)務(wù)邏輯”的獨(dú)特權(quán)限需求,編碼實現(xiàn)剩余部分(或者說細(xì)粒度的)部分,才算完整?;氐綑?quán)限的問題公式,通用的設(shè)計僅解決了Who+What+How的問題,其他的權(quán)限問題留給業(yè)務(wù)邏輯解決。

概念:

Who:權(quán)限的擁用者或主體(Principal、User、Group、Role、Actor等等)

What:權(quán)限針對的對象或資源(Resource、Class)。

How:具體的權(quán)限(Privilege,正向授權(quán)與負(fù)向授權(quán))。

Role:是角色,擁有一定數(shù)量的權(quán)限。

Operator:操作。表明對What的How操作。

說明:

User:與Role相關(guān),用戶僅僅是純粹的用戶,權(quán)限是被分離出去了的。User是不能與Privilege直接相關(guān)的,User要擁有對某種資源的權(quán)限,必須通過Role去關(guān)聯(lián)。解決Who的問題。

Resource:就是系統(tǒng)的資源,比如部門新聞,文檔等各種可以被提供給用戶訪問的對象。資源可以反向包含自身,即樹狀結(jié)構(gòu),每一個資源節(jié)點(diǎn)可以與若干指定權(quán)限類別相關(guān)可定義是否將其權(quán)限應(yīng)用于子節(jié)點(diǎn)。

Privilege:是ResourceRelated的權(quán)限。就是指,這個權(quán)限是綁定在特定的資源實例上的。比如說部門新聞的發(fā)布權(quán)限,叫做"部門新聞發(fā)布權(quán)限"。這就表明,該P(yáng)rivilege是一個發(fā)布權(quán)限,而且是針對部門新聞這種資源的一種發(fā)布權(quán)限。Privilege是由Creator在做開發(fā)時就確定的。權(quán)限,包括系統(tǒng)定義權(quán)限和用戶自定義權(quán)限用戶自定義權(quán)限之間可以指定排斥和包含關(guān)系(如:讀取,修改,管理三個權(quán)限,管理權(quán)限包含前兩種權(quán)限)。Privilege如"刪除"是一個抽象的名詞,當(dāng)它不與任何具體的Object或Resource綁定在一起時是沒有任何意義的。拿新聞發(fā)布來說,發(fā)布是一種權(quán)限,但是只說發(fā)布它是毫無意義的。因為不知道發(fā)布可以操作的對象是什么。只有當(dāng)發(fā)布與新聞結(jié)合在一起時,才會產(chǎn)生真正的Privilege。這就是PrivilegeInstance。權(quán)限系統(tǒng)根據(jù)需求的不同可以延伸生很多不同的版本。

Role:是粗粒度和細(xì)粒度(業(yè)務(wù)邏輯)的接口,一個基于粗粒度控制的權(quán)限框架軟件,對外的接口應(yīng)該是Role,具體業(yè)務(wù)實現(xiàn)可以直接繼承或拓展豐富Role的內(nèi)容,Role不是如同User或Group的具體實體,它是接口概念,抽象的通稱。

Group:用戶組,權(quán)限分配的單位與載體。權(quán)限不考慮分配給特定的用戶。組可以包括組(以實現(xiàn)權(quán)限的繼承)。組可以包含用戶,組內(nèi)用戶繼承組的權(quán)限。Group要實現(xiàn)繼承。即在創(chuàng)建時必須要指定該Group的Parent是什么Group。在粗粒度控制上,可以認(rèn)為,只要某用戶直接或者間接的屬于某個Group那么它就具備這個Group的所有操作許可。細(xì)粒度控制上,在業(yè)務(wù)邏輯的判斷中,User僅應(yīng)關(guān)注其直接屬于的Group,用來判斷是否“同組”。Group是可繼承的,對于一個分級的權(quán)限實現(xiàn),某個Group通過“繼承”就已經(jīng)直接獲得了其父Group所擁有的所有“權(quán)限集合”,對這個Group而言,需要與權(quán)限建立直接關(guān)聯(lián)的,僅是它比起其父Group需要“擴(kuò)展”的那部分權(quán)限。子組繼承父組的所有權(quán)限,規(guī)則來得更簡單,同時意味著管理更容易。為了更進(jìn)一步實現(xiàn)權(quán)限的繼承,最直接的就是在Group上引入“父子關(guān)系”。

User與Group是多對多的關(guān)系。即一個User可以屬于多個Group之中,一個Group可以包括多個User。子Group與父Group是多對一的關(guān)系。Operator某種意義上類似于Resource+Privilege概念,但這里的Resource僅包括ResourceType不表示ResourceInstance。Group可以直接映射組織結(jié)構(gòu),Role可以直接映射組織結(jié)構(gòu)中的業(yè)務(wù)角色,比較直觀,而且也足夠靈活。Role對系統(tǒng)的貢獻(xiàn)實質(zhì)上就是提供了一個比較粗顆粒的分配單位。

Group與Operator是多對多的關(guān)系。各概念的關(guān)系圖示如下:

解釋:

Operator的定義包括了ResourceType和Method概念。即,What和How的概念。之所以將What和How綁定在一起作為一個Operator概念而不是分開建模再建立關(guān)聯(lián),這是因為很多的How對于某What才有意義。比如,發(fā)布操作對新聞對象才有意義,對用戶對象則沒有意義。

How本身的意義也有所不同,具體來說,對于每一個What可以定義N種操作。比如,對于合同這類對象,可以定義創(chuàng)建操作、提交操作、檢查沖突操作等??梢哉J(rèn)為,How概念對應(yīng)于每一個商業(yè)方法。其中,與具體用戶身份相關(guān)的操作既可以定義在操作的業(yè)務(wù)邏輯之中,也可以定義在操作級別。比如,創(chuàng)建者的瀏覽視圖與普通用戶的瀏覽視圖要求內(nèi)容不同。既可以在外部定義兩個操作方法,也可以在一個操作方法的內(nèi)部根據(jù)具體邏輯進(jìn)行處理。具體應(yīng)用哪一種方式應(yīng)依據(jù)實際情況進(jìn)行處理。

這樣的架構(gòu),應(yīng)能在易于理解和管理的情況下,滿足絕大部分粗粒度權(quán)限控制的功能需要。但是除了粗粒度權(quán)限,系統(tǒng)中必然還會包括無數(shù)對具體Instance的細(xì)粒度權(quán)限。這些問題,被留給業(yè)務(wù)邏輯來解決,這樣的考慮基于以下兩點(diǎn):

一方面,細(xì)粒度的權(quán)限判斷必須要在資源上建模權(quán)限分配的支持信息才可能得以實現(xiàn)。比如,如果要求創(chuàng)建者和普通用戶看到不同的信息內(nèi)容,那么,資源本身應(yīng)該有其創(chuàng)建者的信息。另一方面,細(xì)粒度的權(quán)限常常具有相當(dāng)大的業(yè)務(wù)邏輯相關(guān)性。對不同的業(yè)務(wù)邏輯,常常意味著完全不同的權(quán)限判定原則和策略。相比之下,粗粒度的權(quán)限更具通用性,將其實現(xiàn)為一個架構(gòu),更有重用價值;而將細(xì)粒度的權(quán)限判斷實現(xiàn)為一個架構(gòu)級別的東西就顯得繁瑣,而且不是那么的有必要,用定制的代碼來實現(xiàn)就更簡潔,更靈活。

所以細(xì)粒度控制應(yīng)該在底層解決,Resource在實例化的時候,必需指定Owner和GroupPrivilege在對Resource進(jìn)行操作時也必然會確定約束類型:究竟是OwnerOK還是GroupOK還是AllOK。Group應(yīng)和Role嚴(yán)格分離User和Group是多對多的關(guān)系,Group只用于對用戶分類,不包含任何Role的意義;Role只授予User,而不是Group。如果用戶需要還沒有的多種Privilege的組合,必須新增Role。Privilege必須能夠訪問Resource,同時帶User參數(shù),這樣權(quán)限控制就完備了。

思想:

權(quán)限系統(tǒng)的核心由以下三部分構(gòu)成:1.創(chuàng)造權(quán)限,2.分配權(quán)限,3.使用權(quán)限,然后,系統(tǒng)各部分的主要參與者對照如下:1.創(chuàng)造權(quán)限-Creator創(chuàng)造,2.分配權(quán)限-Administrator分配,3.使用權(quán)限-User:

1.Creator創(chuàng)造Privilege,Creator在設(shè)計和實現(xiàn)系統(tǒng)時會劃分,一個子系統(tǒng)或稱為模塊,應(yīng)該有哪些權(quán)限。這里完成的是Privilege與Resource的對象聲明,并沒有真正將Privilege與具體Resource實例聯(lián)系在一起,形成Operator。

2.Administrator指定Privilege與ResourceInstance的關(guān)聯(lián)。在這一步,權(quán)限真正與資源實例聯(lián)系到了一起,產(chǎn)生了Operator(PrivilegeInstance)。Administrator利用Operator這個基本元素,來創(chuàng)造他理想中的權(quán)限模型。如,創(chuàng)建角色,創(chuàng)建用戶組,給用戶組分配用戶,將用戶組與角色關(guān)聯(lián)等等...這些操作都是由Administrator來完成的。

3.User使用Administrator分配給的權(quán)限去使用各個子系統(tǒng)。Administrator是用戶,在他的心目中有一個比較適合他管理和維護(hù)的權(quán)限模型。于是,程序員只要回答一個問題,就是什么權(quán)限可以訪問什么資源,也就是前面說的Operator。程序員提供Operator就意味著給系統(tǒng)穿上了盔甲。Administrator就可以按照他的意愿來建立他所希望的權(quán)限框架可以自行增加,刪除,管理Resource和Privilege之間關(guān)系??梢宰孕性O(shè)定用戶User和角色Role的對應(yīng)關(guān)系。(如果將Creator看作是Basic的發(fā)明者,Administrator就是Basic的使用者,他可以做一些腳本式的編程)Operator是這個系統(tǒng)中最關(guān)鍵的部分,它是一個紐帶,一個系在Programmer,Administrator,User之間的紐帶。

用一個功能模塊來舉例子。

一.建立角色功能并做分配:

1.如果現(xiàn)在要做一個員工管理的模塊(即Resources),這個模塊有三個功能,分別是:增加,修改,刪除。給這三個功能各自分配一個ID,這個ID叫做功能代號:

Emp_addEmp,Emp_deleteEmp,Emp_updateEmp。

2.建立一個角色(Role),把上面的功能代碼加到這個角色擁有的權(quán)限中,并保存到數(shù)據(jù)庫中。角色包括系統(tǒng)管理員,測試人員等。

3.建立一個員工的賬號,并把一種或幾種角色賦給這個員工。比如說這個員工既可以是公司管理人員,也可以是測試人員等。這樣他登錄到系統(tǒng)中將會只看到他擁有權(quán)限的那些模塊。

二.把身份信息加到Session中。

登錄時,先到數(shù)據(jù)庫中查找是否存在這個員工,如果存在,再根據(jù)員工的sn查找員工的權(quán)限信息,把員工所有的權(quán)限信息都入到一個Hashmap中,比如就把上面的Emp_addEmp等放到這個Hashmap中。然后把Hashmap保存在一個UserInfoBean中。最后把這個UserInfoBean放到Session中,這樣在整個程序的運(yùn)行過程中,系統(tǒng)隨時都可以取得這個用戶的身份信息。

三.根據(jù)用戶的權(quán)限做出不同的顯示。

可以對比當(dāng)前員工的權(quán)限和給這個菜單分配的“功能ID”判斷當(dāng)前用戶是否有打開這個菜單的權(quán)限。例如:如果保存員工權(quán)限的Hashmap中沒有這三個ID的任何一個,那這個菜單就不會顯示,如果員工的Hashmap中有任何一個ID,那這個菜單都會顯示。

對于一個新聞系統(tǒng)(Resouce),假設(shè)它有這樣的功能(Privilege):查看,發(fā)布,刪除,修改;假設(shè)對于刪除,有"新聞系統(tǒng)管理者只能刪除一月前發(fā)布的,而超級管理員可刪除所有的這樣的限制,這屬于業(yè)務(wù)邏輯(Businesslogic),而不屬于用戶權(quán)限范圍。也就是說權(quán)限負(fù)責(zé)有沒有刪除的Permission,至于能刪除哪些內(nèi)容應(yīng)該根據(jù)UserRoleorUserGroup來決定(當(dāng)然給UserRoleorUserGroup分配權(quán)限時就應(yīng)該包含上面兩條業(yè)務(wù)邏輯)。

一個用戶可以擁有多種角色,但同一時刻用戶只能用一種角色進(jìn)入系統(tǒng)。角色的劃分方法可以根據(jù)實際情況劃分,按部門或機(jī)構(gòu)進(jìn)行劃分的,至于角色擁有多少權(quán)限,這就看系統(tǒng)管理員賦給他多少的權(quán)限了。用戶—角色—權(quán)限的關(guān)鍵是角色。用戶登錄時是以用戶和角色兩種屬性進(jìn)行登錄的(因為一個用戶可以擁有多種角色,但同一時刻只能扮演一種角色),根據(jù)角色得到用戶的權(quán)限,登錄后進(jìn)行初始化。這其中的技巧是同一時刻某一用戶只能用一種角色進(jìn)行登錄。

針對不同的“角色”動態(tài)的建立不同的組,每個項目建立一個單獨(dú)的Group,對于新的項目,建立新的Group即可。在權(quán)限判斷部分,應(yīng)在商業(yè)方法上予以控制。比如:不同用戶的“操作能力”是不同的(粗粒度的控制應(yīng)能滿足要求),不同用戶的“可視區(qū)域”是不同的(體現(xiàn)在對被操作的對象的權(quán)限數(shù)據(jù),是否允許當(dāng)前用戶訪問,這需要對業(yè)務(wù)數(shù)據(jù)建模的時候考慮權(quán)限控制需要)。

擴(kuò)展性:

有了用戶/權(quán)限管理的基本框架,Who(User/Group)的概念是不會經(jīng)常需要擴(kuò)展的。變化的可能是系統(tǒng)中引入新的What(新的Resource類型)或者新的How(新的操作方式)。那在三個基本概念中,僅在Permission上進(jìn)行擴(kuò)展是不夠的。這樣的設(shè)計中Permission實質(zhì)上解決了How的問題,即表示了“怎樣”的操作。那么這個“怎樣”是在哪一個層次上的定義呢將Permission定義在“商業(yè)方法”級別比較合適。比如,發(fā)布、購買、取消。每一個商業(yè)方法可以意味著用戶進(jìn)行的一個“動作”。定義在商業(yè)邏輯的層次上,一方面保證了數(shù)據(jù)訪問代碼的“純潔性”,另一方面在功能上也是“足夠”的。也就是說,對更低層次,能自由的訪問數(shù)據(jù),對更高層次,也能比較精細(xì)的控制權(quán)限。

確定了Permission定義的合適層次,更進(jìn)一步,能夠發(fā)現(xiàn)Permission實際上還隱含了What的概念。也就是說,對于What的How操作才會是一個完整的Operator。比如,“發(fā)布”操作,隱含了“信息”的“發(fā)布”概念,而對于“商品”而言發(fā)布操作是沒有意義的。同樣的,“購買”操作,隱含了“商品”的“購買”概念。這里的綁定還體現(xiàn)在大量通用的同名的操作上,比如,需要區(qū)分“商品的刪除”與“信息的刪除”這兩個同名為“刪除”的不同操作。

提供權(quán)限系統(tǒng)的擴(kuò)展能力是在Operator(Resource+Permission)的概念上進(jìn)行擴(kuò)展。Proxy模式是一個非常合適的實現(xiàn)方式。實現(xiàn)大致如下:在業(yè)務(wù)邏輯層(EJBSessionFacade[StatefulSessionBean]中),取得該商業(yè)方法的Methodname,再根據(jù)Classname和Methodname檢索Operator數(shù)據(jù),然后依據(jù)這個Operator信息和Stateful中保存的User信息判斷當(dāng)前用戶是否具備該方法的操作權(quán)限。

應(yīng)用在EJB模式下,可以定義一個很明確的Business層次,而一個Business可能意味著不同的視圖,當(dāng)多個視圖都對應(yīng)于一個業(yè)務(wù)邏輯的時候,比如,SwingClient以及JspClient訪問的是同一個EJB實現(xiàn)的Business。在Business層上應(yīng)用權(quán)限較能提供集中的控制能力。實際上,如果權(quán)限系統(tǒng)提供了查詢能力,那么會發(fā)現(xiàn),在視圖層次已經(jīng)可以不去理解權(quán)限,它只需要根據(jù)查詢結(jié)果控制界面就可以了。

靈活性:

Group和Role,只是一種輔助實現(xiàn)的手段,不是必需的。如果系統(tǒng)的Role很多,逐個授權(quán)違背了“簡單,方便”的目的,那就引入Group,將權(quán)限相同的Role組成一個Group進(jìn)行集中授權(quán)。Role也一樣,是某一類Operator的集合,是為了簡化針對多個Operator的操作。

Role把具體的用戶和組從權(quán)限中解放出來。一個用戶可以承擔(dān)不同的角色,從而實現(xiàn)授權(quán)的靈活性。當(dāng)然,Group也可以實現(xiàn)類似的功能。但實際業(yè)務(wù)中,Group劃分多以行政組織結(jié)構(gòu)或業(yè)務(wù)功能劃分;如果為了權(quán)限管理強(qiáng)行將一個用戶加入不同的組,會導(dǎo)致管理的復(fù)雜性。

Domain的應(yīng)用。為了授權(quán)更靈活,可以將Where或者Scope抽象出來,稱之為Domain,真正的授權(quán)是在Domain的范圍內(nèi)進(jìn)行,具體的Resource將分屬于不同的Domain。比如:一個新聞機(jī)構(gòu)有國內(nèi)與國外兩大分支,兩大分支內(nèi)又都有不同的資源(體育類、生活類、時事政治類)。假如所有國內(nèi)新聞的權(quán)限規(guī)則都是一樣的,所有國外新聞的權(quán)限規(guī)則也相同。則可以建立兩個域,分別授權(quán),然后只要將各類新聞與不同的域關(guān)聯(lián),受域上的權(quán)限控制,從而使之簡化。

權(quán)限系統(tǒng)還應(yīng)該考慮將功能性的授權(quán)與資源性的授權(quán)分開。很多系統(tǒng)都只有對系統(tǒng)中的數(shù)據(jù)(資源)的維護(hù)有權(quán)限控制,但沒有對系統(tǒng)功能的權(quán)限控制。

權(quán)限系統(tǒng)最好是可以分層管理而不是集中管理。大多客戶希望不同的部門能且僅能管理其部門內(nèi)部的事務(wù),而不是什么都需要一個集中的Administrator或Administrators組來管理。雖然你可以將不同部門的人都加入Administrators組,但他們的權(quán)限過大,可以管理整個系統(tǒng)資源而不是該部門資源。

正向授權(quán)與負(fù)向授權(quán):正向授權(quán)在開始時假定主體沒有任何權(quán)限,然后根據(jù)需要授予權(quán)限,適合于權(quán)限要求嚴(yán)格的系統(tǒng)。負(fù)向授權(quán)在開始時假定主體有所有權(quán)限,然后將某些特殊權(quán)限收回。

權(quán)限計算策略:系統(tǒng)中User,Group,Role都可以授權(quán),權(quán)限可以有正負(fù)向之分,在計算用戶的凈權(quán)限時定義一套策略。

系統(tǒng)中應(yīng)該有一個集中管理權(quán)限的AccessService,負(fù)責(zé)權(quán)限的維護(hù)(業(yè)務(wù)管理員、安全管理模塊)與使用(最終用戶、各功能模塊),該AccessService在實現(xiàn)時要同時考慮一般權(quán)限與特殊權(quán)限。雖然在具體實現(xiàn)上可以有很多,比如用Proxy模式,但應(yīng)該使這些Proxy依賴于AccessService。各模塊功能中調(diào)用AccessService來檢查是否有相應(yīng)的權(quán)限。所以說,權(quán)限管理不是安全管理模塊自己一個人的事情,而是與系統(tǒng)各功能模塊都有關(guān)系。每個功能模塊的開發(fā)人員都應(yīng)該熟悉安全管理模塊,當(dāng)然,也要從業(yè)務(wù)上熟悉本模塊的安全規(guī)則。

技術(shù)實現(xiàn):

1.表單式認(rèn)證,這是常用的,但用戶到達(dá)一個不被授權(quán)訪問的資源時,Web容器就發(fā)

出一個html頁面,要求輸入用戶名和密碼。

2.一個基于ServletSignin/Signout來集中處理所有的Request,缺點(diǎn)是必須由應(yīng)用程序自己來處理。

3.用Filter防止用戶訪問一些未被授權(quán)的資源,F(xiàn)ilter會截取所有Request/Response,

然后放置一個驗證通過的標(biāo)識在用戶的Session中,然后Filter每次依靠這個標(biāo)識來決定是否放行Response。

這個模式分為:

Gatekeeper:采取Filter或統(tǒng)一Servlet的方式。

Authenticator:在Web中使用JAAS自己來實現(xiàn)。

用戶資格存儲LDAP或數(shù)據(jù)庫:

1.Gatekeeper攔截檢查每個到達(dá)受保護(hù)的資源。首先檢查這個用戶是否有已經(jīng)創(chuàng)建

好的LoginSession,如果沒有,Gatekeeper檢查是否有一個全局的和Authenticator相關(guān)的session?

2.如果沒有全局的session,這個用戶被導(dǎo)向到Authenticator的Sign-on頁面,

要求提供用戶名和密碼。

3.Authenticator接受用戶名和密碼,通過用戶的資格系統(tǒng)驗證用戶。

4.如果驗證成功,Authenticator將創(chuàng)建一個全局Loginsession,并且導(dǎo)向Gatekeeper

來為這個用戶在他的web應(yīng)用中創(chuàng)建一個LoginSession。

5.Authenticator和Gatekeepers聯(lián)合分享Cookie,或者使用Tokens在Query字符里權(quán)限管理模塊注意:再添加用戶的時候,其中的Person來自組織管理模塊,所以添加用戶的時候直接從數(shù)據(jù)中根據(jù)personId加載過來就行,而不是從頁面去拿一個Person對象,這樣效率低,而且麻煩,不可行,不要管UserRoles這張表添加用戶的模塊 publicvoidaddUser(Useruser){ getHibernateTemplate().save(user); UserRolesuserRoles=newUserRoles(); (user); getHibernateTemplate().save(userRoles); }這樣的代碼顯然不行,publicvoidaddPerson(Personperson,intorgId){ if(orgId!=0){ Organizationorg=(Organization)getHibernateTemplate().load,orgId); (org); } getHibernateTemplate().save(person); }所以再添加每個對象的時候,要把其被依賴的對象的id傳過來,然和從數(shù)據(jù)庫中加載其被依賴的對象設(shè)置進(jìn)去,因為對象的一連竄的依賴關(guān)系,所必須一級一級的保存好,這樣各模塊之間才會有聯(lián)系,查詢的時候才會發(fā)生一系列的先關(guān)聯(lián)的結(jié)果被依賴的對象不要再頁面去下來,二是從后臺Hibernate層直接加載 publicvoidaddUser(Useruser,intpersonId){ if(personId==0){ thrownewSystemException("不能給空用戶分配帳號"); }oad,personId)); (newDate()); ave(user); }其他的添加也是同樣的道理,不要犯傻,但是刪除的時候,要先刪除依賴的Userroles,要從userRoles中查出要刪的User例 publicvoiddelUser(intuserId){ Stringhql="selectfromUsersRolesurwhere"; ListroleIds=getHibernateTemplate().find(hql,userId); if()!=0){ for(Iteratoriterator=();();){ IntegerroleId=(Integer)(); delUserRole(userId,roleId); } } getHibernateTemplate().delete(findUser(userId)); } publicUserfindUser(intuserId){ return(User)getHibernateTemplate().load,userId); } 再增刪改查中,要注意,只有添加新增加或修改相應(yīng)的的對象時,才從頁面取相應(yīng)的對象,其他的操作(例,授權(quán)),只需從前臺頁面相應(yīng)的id,再到后臺進(jìn)行數(shù)據(jù)交互publicvoidaddRolesForUser(intuserId,introleId,intorderNo){ }Hibernate中g(shù)etSession與getHibernateTemplate查詢的區(qū)別當(dāng)sql查詢的時候使用getSession,getHibernateTemplate查詢對象UserRoleUserRoles三者之間的刪除操作

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論