Shao Fan

          關(guān)于JAVA與軟件工程
          posts - 31, comments - 71, trackbacks - 0, articles - 4
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          2007年6月3日

          目前開(kāi)發(fā)人員對(duì)系統(tǒng)開(kāi)發(fā)的一個(gè)共識(shí)是使用三層架構(gòu),分為表示層,業(yè)務(wù)層,和持久層。而這三層之間的依賴關(guān)系如何?比較常見(jiàn)的一種看法是

          表示層 --> 業(yè)務(wù)層 --> 持久層

          這表明了層與層之間的調(diào)用關(guān)系,表示層通過(guò)調(diào)用業(yè)務(wù)層來(lái)完成任務(wù),而業(yè)務(wù)層則調(diào)用持久層。從另一個(gè)角度來(lái)看,一種依賴關(guān)系是

          表示層 --> 領(lǐng)域模型(Domain Model) <-- 持久層

          表示層和持久層都應(yīng)該理解(recognize)領(lǐng)域模型。而領(lǐng)域模型則是業(yè)務(wù)層的一部分。業(yè)務(wù)層正是系統(tǒng)的價(jià)值所在。雖說(shuō)表示和持久也很重要,在某些系統(tǒng)中可以說(shuō)是很關(guān)鍵,但是它們的最終目的都是為業(yè)務(wù)服務(wù),所以業(yè)務(wù)層應(yīng)該是系統(tǒng)的核心

          基于以上的認(rèn)識(shí),在系統(tǒng)設(shè)計(jì)的時(shí)應(yīng)首先分析需求得到領(lǐng)域模型,找出系統(tǒng)中的實(shí)體、對(duì)象(靜態(tài)的一面),并明確大致的業(yè)務(wù)流程(動(dòng)態(tài)的一面)。 而另兩層應(yīng)盡最大努力為業(yè)務(wù)層服務(wù),且盡量減少業(yè)務(wù)層受另兩層的限制。


          各層的職責(zé):

          表示層:負(fù)責(zé)顯示信息,及從系統(tǒng)外部得到輸入。表示層的設(shè)計(jì)決定系統(tǒng)界面的可用性,及信息輸入和展示的可靠性。表示層只知道如何展示信息,及收集用戶輸入,并不知道該如何對(duì)這些輸入進(jìn)行處理來(lái)完成業(yè)務(wù)。

          業(yè)務(wù)層:完成業(yè)務(wù)邏輯。業(yè)務(wù)層設(shè)計(jì)決定客戶價(jià)值是否能夠得到實(shí)現(xiàn)。這是系統(tǒng)的關(guān)鍵。外在的表現(xiàn)是功能性。業(yè)務(wù)層設(shè)計(jì)和實(shí)現(xiàn)的失誤表現(xiàn)在用戶端即功能缺失,功能不可靠等。如果需要對(duì)業(yè)務(wù)層的業(yè)務(wù)規(guī)則進(jìn)行解耦,則可以使用規(guī)則引擎如Drools,把業(yè)務(wù)規(guī)則分離出來(lái)。但分離后的業(yè)務(wù)規(guī)則仍屬于業(yè)務(wù)層。業(yè)務(wù)層知道如何對(duì)用戶輸入進(jìn)行處理,能夠應(yīng)用業(yè)務(wù)規(guī)則完成用戶所需的業(yè)務(wù),但它不知道數(shù)據(jù)如何讀取和保存。

          持久層:負(fù)責(zé)用戶信息的持久化。持久層的失誤表現(xiàn)在外即數(shù)據(jù)處理(儲(chǔ)存,展示等)不可靠。持久層完全不知道業(yè)務(wù),只專(zhuān)注于數(shù)據(jù)存儲(chǔ)和讀取。所謂持久化并不一定是指數(shù)據(jù)庫(kù),任何方式的持久化(通過(guò)文件,網(wǎng)絡(luò)的持久化等)都應(yīng)由持久層完成。

          各層的設(shè)計(jì)都會(huì)直接影響系統(tǒng)性能。

          三層的體積大小和復(fù)雜度在不同的系統(tǒng)中可能會(huì)有很大的不同。比如說(shuō)GOOGLE的搜索引擎,它的界面很簡(jiǎn)單,可以想像表示層是比較容易實(shí)現(xiàn)的,而它的業(yè)務(wù)層,關(guān)系到處理關(guān)鍵字,分析搜索結(jié)果,決定排名等,而持久層則要負(fù)責(zé)處理超大量的數(shù)據(jù)。業(yè)務(wù)層和持久層則相當(dāng)復(fù)雜。而有的系統(tǒng)持久層會(huì)很小,比如殺毒軟件,媒體播放軟件等。業(yè)務(wù)層小而另兩層大的例子暫時(shí)還沒(méi)有想到:)


          posted @ 2007-09-08 19:45 shaofan 閱讀(5136) | 評(píng)論 (2)編輯 收藏

          help是一個(gè)內(nèi)置函數(shù),所謂內(nèi)置函數(shù),就是在Python中被自動(dòng)加載的函數(shù),任何時(shí)候都可以用。參數(shù)分兩種:

          • 如果傳一個(gè)字符串做參數(shù)的話,它會(huì)自動(dòng)搜索以這個(gè)字符串命名的模塊,方法,等。
          • 如果傳入的是一個(gè)對(duì)象,就會(huì)顯示這個(gè)對(duì)象的類(lèi)型的幫助。

          比如輸入help(’print’),它就會(huì)尋找以’print’為名的模塊,類(lèi),等,找不到就會(huì)看到提示信息。而print在python里是一個(gè)保留字,和pass,return同等,而非對(duì)象,所以help(print)也會(huì)出錯(cuò)((kkkkkkk))。

          舉個(gè)例子:

          1 help(’sys’) #會(huì)列出sys模塊的幫助
          2 = [1,2,3]
          3 help(a) #會(huì)顯示list的幫助
          4 help(a.append) #會(huì)顯示list的append方法的幫助

          python安裝自帶的library reference,2.1節(jié)是關(guān)于內(nèi)置函數(shù)的。

          Reference Manual的6.6節(jié)可以找到關(guān)于print的東東。

          posted @ 2007-06-05 06:28 shaofan 閱讀(2779) | 評(píng)論 (0)編輯 收藏

          Struts2默認(rèn)theme是xhtml,它用表格來(lái)對(duì)表單中的控件進(jìn)行排版。它也提供一個(gè)客戶端的js驗(yàn)證功能,但是它的js腳本卻有些問(wèn)題,在某些情況下,前次驗(yàn)證的提示信息無(wú)法被清除,提示信息會(huì)不斷的累積顯示在屏幕上。而按照設(shè)計(jì),每次提交表單時(shí)應(yīng)只顯示每次驗(yàn)證的出錯(cuò)信息。

          它的客戶端驗(yàn)證的流程大概是這樣,用戶提交表單時(shí),對(duì)各個(gè)控件的輸入按預(yù)先設(shè)置的規(guī)則進(jìn)行驗(yàn)證,如果有問(wèn)題,則清除表單里原有的出錯(cuò)提示信息,并寫(xiě)入新的提示。其設(shè)計(jì)的功能是把出錯(cuò)信息寫(xiě)表格里出錯(cuò)控件的上方,以便用戶看得更加清楚。問(wèn)題就出在其用來(lái)清除原出錯(cuò)信息的函數(shù),其代碼是這樣的(在struts.jar的template/xhtml目錄下可以找到):

           1 function clearErrorMessages(form) {
           2 
           3     var table = form.childNodes[1];
           4     iftypeof table == "undefined" ) {
           5         table = form.childNodes[0];
           6     }
           7 
           8     // clear out any rows with an "errorFor" attribute
           9     var rows = table.rows;
          10     var rowsToDelete = new Array();
          11     if (rows == null){
          12         return;
          13     }
          14 
          15     for(var i = 0; i < rows.length; i++) {
          16         var r = rows[i];
          17         if (r.getAttribute("errorFor")) {
          18             rowsToDelete.push(r);
          19         }
          20     }
          21 
          22     // now delete the rows
          23     for (var i = 0; i < rowsToDelete.length; i++) {
          24         var r = rowsToDelete[i];
          25         table.deleteRow(r.rowIndex);
          26         //table.removeChild(rowsToDelete[i]);
          27     }
          28 }


          看這個(gè)函數(shù)的前三行,它試圖取得form的第1個(gè)或第2個(gè)子節(jié)點(diǎn),并把它作為table來(lái)處理(看接下來(lái)的幾行)。要想清除表格里的錯(cuò)誤信息,首先要取得表格本身,這沒(méi)錯(cuò),但是如果第1個(gè)或第2個(gè)子節(jié)點(diǎn)不是table的話,腳本就會(huì)出錯(cuò),造成原出錯(cuò)信息無(wú)法清除,這樣每次提交后的提示信息就會(huì)累積在屏幕上。

          要解決這個(gè)問(wèn)題有兩個(gè)辦法:
          • 寫(xiě)代碼時(shí)要小心,保證form的第1或2個(gè)子節(jié)點(diǎn)是table,不要在生成table前加其他代碼。
          • 或,修改xhtml的validation.js,使它總能獲得正確的table元素,重新打包到struts.jar。
          剛看了一下Struts的JIRA,已經(jīng)有人報(bào)告了這個(gè)問(wèn)題(id WW-1802),而且這個(gè)bug在2.1版本中已經(jīng)解決了。

          posted @ 2007-06-03 17:56 shaofan 閱讀(2547) | 評(píng)論 (3)編輯 收藏

          主站蜘蛛池模板: 正镶白旗| 大竹县| 嘉祥县| 永川市| 北辰区| 昭通市| 赞皇县| 友谊县| 韶关市| 彰化市| 金坛市| 华安县| 嘉禾县| 南雄市| 高台县| 格尔木市| 中超| 兰坪| 应用必备| 道真| 武山县| 开平市| 达拉特旗| 彰武县| 仁寿县| 宜昌市| 通辽市| 陆河县| 罗城| 巨野县| 青铜峡市| 大悟县| 沙湾县| 兴城市| 揭阳市| 潮安县| 墨竹工卡县| 尚义县| 翁牛特旗| 漠河县| 乌拉特中旗|