自己在项目设计和开发的一些总结
系統(tǒng)架構(gòu)設(shè)計
用最簡單易懂的代碼組織業(yè)務(wù)邏輯和實現(xiàn)系統(tǒng)功能。
在一個程序員的成長過程中,會出現(xiàn)寫的代碼先簡單,后復(fù)雜,最后又簡單的一個過程。在最開始寫的簡單的時候,是因為能力達不到,只能寫一些簡單的代碼,考慮不到那么多的擴展。例如在彈出對話框的時候,直接按鈕點擊彈出對話框即可。當工作了一定的年限后,特別是3年左右,此時了解了一些設(shè)計模式和架構(gòu)方法,我們做出的系統(tǒng)設(shè)計開始復(fù)雜起來,考慮的擴展和變化也越來越多,導(dǎo)致代碼就越來越復(fù)雜。因為每個人對系統(tǒng)設(shè)計的理解深度和方式也不一樣,自己設(shè)計出來的東西別人并不一定看得懂。所以一般接手3-5年程序員寫的代碼是很麻煩的。因為他可能用了自己用的比較熟悉的第三方庫,或者自己熟悉甚至發(fā)明出來的一些設(shè)計方法,這都會讓后來接手的人不易看懂。但如果一個程序員或設(shè)計師經(jīng)驗再服務(wù)一些,或者經(jīng)歷過這種事情的話,他在設(shè)計的時候就會為以后有人接手考慮。并且他也會考慮到哪些才是變化點,或者直接就不考慮變化點。例如以前一些在設(shè)計時要考慮對多個數(shù)據(jù)庫的支持以及對UI變化的支持。對數(shù)據(jù)庫的支持使用抽象工廠模式,對UI變化支持和為了封裝業(yè)務(wù)邏輯而使用的MVC模式,至少在我們做的一般的應(yīng)用項目中都是不必使用的。這樣就能保證剛進入項目組的經(jīng)驗較缺乏的程序員也能很快的看懂代碼。
例如我們在實現(xiàn)用戶信息修改這個功能時,我們要得到要修改信息的用戶編碼或者用戶對象,得到后傳入用戶編輯對話框,在對話框中讀取該用戶的最新信息并判斷用戶還是否存在,把讀取到的用戶信息賦值給各個信息輸入框。當用戶修改完這些信息后,系統(tǒng)要驗證數(shù)據(jù)的合法性,如果不合法就彈出提示對話框。用戶信息合法性驗證代碼要寫在用戶類中。最后更新到數(shù)據(jù)庫中。
系統(tǒng)操作越簡單越好,不要給用戶太多選擇。
一般情況下,用戶經(jīng)常用到的功能只是一個系統(tǒng)20%的功能。所以如何讓用戶在用這20%的功能時簡單方便是系統(tǒng)設(shè)計和開發(fā)人員需要考慮的問題。
有以下幾種方式:
?
系統(tǒng)分層
系統(tǒng)分為領(lǐng)域模型層、數(shù)據(jù)訪問層、系統(tǒng)邏輯層以及UI層。如下如所示:
?
Domains是系統(tǒng)的核心業(yè)務(wù)類,定義了業(yè)務(wù)模型,業(yè)務(wù)動作和一些流程。
DALs是訪問數(shù)據(jù)庫的類庫,和數(shù)據(jù)庫打交道的代碼都會定義到此處。
BLLs我們稱之為系統(tǒng)邏輯類,在系統(tǒng)中一些全局的管理信息類、系統(tǒng)狀態(tài)存儲和狀態(tài)改變時的系統(tǒng)事件觸發(fā)都定義到該類庫中。
UIs是我們的系統(tǒng)界面類庫。
?
系統(tǒng)分層不是固定死的,一般的業(yè)務(wù)系統(tǒng)分3-4層為宜,層次太多了,會增加系統(tǒng)的復(fù)雜程度。
創(chuàng)建程序集
對于一個CS系統(tǒng),我們在創(chuàng)建程序集的時候會創(chuàng)建下面程序集。
?
Domains,定義核心業(yè)務(wù)的程序集
DALs,訪問數(shù)據(jù)庫的程序集
BLLs,定義系統(tǒng)全局狀態(tài)控制相關(guān)類的程序集
UIs,定義UI的程序集
Commands,為主應(yīng)用程序提供功能單元的程序集。
App,主應(yīng)用程序
?
系統(tǒng)的核心業(yè)務(wù)如何定義
業(yè)務(wù)核心類直接用最簡單的C#代碼定義,一些比較明顯的包含關(guān)系,需要在代碼中定義出來。例如用戶類屬于一個角色,一個角色包含多個權(quán)限類。
那么在User類中就可以定義Role的一個屬性,在Role中定義List<Limite>屬性。如果為了獲取一個用戶是否有某個權(quán)限,在User類中可以定義 bool HasLimite(string pLimiteKey)函數(shù)。
如何訪問數(shù)據(jù)庫
訪問數(shù)據(jù)庫最好是使用一個第三方的對象持久化庫,這樣訪問數(shù)據(jù)庫會簡單一些,代碼量也少一些。Nhibnate,自己寫的BM.DBMapping。
如果表是有一定的業(yè)務(wù)邏輯的,必須為每個表單獨寫一個DAL類,在該類中定義該表的增、刪、查操作。但執(zhí)行操作的Session需要從外面?zhèn)鬟M來,這樣方便上層來組織事務(wù)邏輯。
如何控制數(shù)據(jù)庫訪問的事務(wù)問題
數(shù)據(jù)庫事務(wù)如何控制,在什么地方控制數(shù)據(jù)庫事務(wù)。當我們做一些添加操作時,有可能同時操作多張數(shù)據(jù)表,當所有的數(shù)據(jù)表都修改成功,任務(wù)才算執(zhí)行成功。如果有一個出現(xiàn)異常,其他已經(jīng)執(zhí)行的操作都要回滾。
事務(wù)控制放在系統(tǒng)的哪一層?是放在DAL層還是放在DAL之上的層?
我的建議是放在DAL上面的層。DAL層只提供簡單的針對該表的增、刪、改或者相關(guān)表的關(guān)聯(lián)查詢,當系統(tǒng)執(zhí)行某項操作,在寫該操作的業(yè)務(wù)邏輯的地方,打開事務(wù),然后調(diào)用多個DAL類對各個表進行操作,最后提交事務(wù),如果遇到錯誤,則回滾。
DAL層要寫一些什么代碼
理論上每個DAL類都是對一個表進行操作的。該類應(yīng)該包括對該表的增、刪、改操作。另外一些查詢,為了提高效率使用了關(guān)聯(lián)查詢,可能會涉及到其他的表。
每個DAL函數(shù)都要把自己所使用的連接傳進來,因為很多系統(tǒng)的功能都是由多個DAL類在一起完成的。
?
如何組織UI
UI分為兩種,一是和系統(tǒng)狀態(tài)相關(guān)的、另一種是無關(guān)的。
和狀態(tài)有關(guān)的需要把系統(tǒng)的Application類或者其包含的全局對象傳進去。從全局對象中獲取要顯示的信息,并把操作的結(jié)果傳回給系統(tǒng)的全局對象。
和狀態(tài)無關(guān)的是一種相對比較通用的UI對象。這種UI在系統(tǒng)中功能比較單一、或者可能會被重復(fù)使用。使用這種類另一個好處可以減少耦合,把該類和系統(tǒng)關(guān)聯(lián)的部分單獨建一個類,這個類作用就是關(guān)聯(lián)UI和全局信息。
?
我們使用WPF或Silverlight的第三方庫都是使用的DEV,在使用的時候,我們盡量保持DEV控件的原始樣式,這樣當更改系統(tǒng)皮膚的時候,樣式可以統(tǒng)一變換。
?
如何控制系統(tǒng)的狀態(tài)
對整個系統(tǒng)狀態(tài)的控制關(guān)系到系統(tǒng)代碼的清晰程度。當系統(tǒng)啟動的之后,該模塊實際上就成了系統(tǒng)的運營中心。系統(tǒng)中存儲的全局數(shù)據(jù)、配置信息以及狀態(tài)信息都會存儲在該模塊中。一般來說該模塊需要定義一個Application類作為該模塊的根類。定義的其他狀態(tài)控制器、全局信息等都掛接到Application類中,這些信息會跟著Application對象傳遞給每個需要的UI。
Application的作用,全局數(shù)據(jù)、配置信息、狀態(tài)信息。
全局數(shù)據(jù),例如我們要管理一些數(shù)據(jù),這些數(shù)據(jù)的目錄需要系統(tǒng)啟動的時候就讀到內(nèi)存中,直到系統(tǒng)關(guān)閉。
配置信息,系統(tǒng)連接數(shù)據(jù)庫的信息、FTP的鏈接信息等。
狀態(tài)數(shù)據(jù)。這個是Application最重要的部分。當UI A執(zhí)行了一個操作,需要通知給UI B做一個響應(yīng)。這該如何實現(xiàn)?是要把UI B的實例作為參數(shù)傳遞給A嗎?肯定不是的,這樣會造成UIA和UIB的耦合。實際上UIA和UIB并不需要知道對方的存在,只要Application知道UIA和UIB都存在就可以了。
UIA執(zhí)行操作后,會觸發(fā)Application或者Application上掛接的一個對象的一個事件,當我們初始化UIB的時候,是需要把Application或者掛接的對象傳進來的,并注冊了這個事件,那么UIA操作后,UIB通過事件觸發(fā)自然得到了通知,并改變自己的狀態(tài)或執(zhí)行其他的操作。
總結(jié)一下,也就是Application認識UIA和UIB,UIA和UIB也認識Application,但UIA和UIB是互不認識的。這就是低耦合。
?
?
如何布局主窗體
在主窗體上,布局主要是菜單欄,狀態(tài)欄和主顯示區(qū)。
菜單欄是有一個個命令按鈕組成的,在最初的系統(tǒng)開發(fā)中,我們經(jīng)常在菜單欄上加上按鈕后,直接雙擊,VS會為程序員在后臺代碼中創(chuàng)建一個函數(shù),然后我們就在該函數(shù)中寫代碼。但隨著系統(tǒng)功能的增加,這么做會導(dǎo)致主窗體的代碼越來越多(或者也可以簡單的分離一下,但這解決不了我們面臨的本質(zhì)問題)。特別是當系統(tǒng)狀態(tài)發(fā)生變化,菜單里面的按鈕的可用狀態(tài)等需要調(diào)整,那么實現(xiàn)這些的代碼就成了程序員的噩夢。
怎么解決這個問題,那就為每個菜單按鈕項寫一個類吧。
當然我們會實現(xiàn)一個基類,在基類中就把Application傳進去了,這樣在每個菜單按鈕的實現(xiàn)代碼中,可以得到整個系統(tǒng)的狀態(tài)和數(shù)據(jù),什么時候自己需要改變狀態(tài),那就注冊相應(yīng)的事件吧。自己控制自己的狀態(tài)時耦合最低的。各個菜單按鈕項都不知道彼此的存在,大家都把狀態(tài)統(tǒng)一交給Application管理,并響應(yīng)Application的指揮,這就足夠了。
那么主界面的后臺代碼所要做的工作,就是把這些按鈕類加到菜單上就可以了。
GIS相關(guān)的數(shù)據(jù)如何存儲
GIS數(shù)據(jù)我們認為是業(yè)務(wù)數(shù)據(jù)的一種形式,空間數(shù)據(jù)和其關(guān)聯(lián)的數(shù)據(jù)通過SDE存儲在數(shù)據(jù)庫中。(參考ESRI為石油輸油管線管理做的方案)
如果是CS系統(tǒng),我們需要配置好Mxd文件,設(shè)置好每個圖層顯示的信息,包括渲染信息。當系統(tǒng)啟動時,需要讀取到系統(tǒng)配置的連接空間數(shù)據(jù)的信息,打開連接(Workspace),循環(huán)每個FeatureLayer或者RasterLayer,根據(jù)名稱去Workspace中讀取想對應(yīng)的FeatureClass或RasterDataset。相當于重新設(shè)置一下數(shù)據(jù)源,主要解決因數(shù)據(jù)庫連接改變而取不到數(shù)據(jù)的問題。第二也是為了安全,這樣Mxd里面不用存儲實際的空間數(shù)據(jù)連接參數(shù),即使Mxd文件被別人拷貝走,也連不上真正的數(shù)據(jù),保證了數(shù)據(jù)的安全性。
如果是BS(Silverlight)系統(tǒng),也需要配置好Mxd文件,但此時的Mxd文件需要提前關(guān)聯(lián)好對空間數(shù)據(jù)庫的連接。然后通過ArcServer發(fā)布出來。BS系統(tǒng)在客戶端通過ArcServer服務(wù)讀取空間數(shù)據(jù)的信息。其實這和自己寫WebServer讀取類似。
?
在做需求時,盡量不要許諾用戶自己去上傳空間數(shù)據(jù)和發(fā)布地圖服務(wù),即使用戶想自己上傳和發(fā)布,我們要教給用戶管理員如何使用ArcGIS桌面工具,不要自己開發(fā)工具。因為這個功能在日常使用頻率是非常低的,但開發(fā)一個好用的卻很費力氣。
如何展示設(shè)備的當前數(shù)據(jù)
設(shè)備要顯示的數(shù)據(jù)根據(jù)設(shè)備的不同,處理的過程也不一樣。例如含水率設(shè)備,在系統(tǒng)中顯示時就顯示設(shè)備傳來的最新的一條數(shù)據(jù)值。但雨量計可能是每0.5毫米降雨就回傳一次,但在界面上顯示的并不是0.5,需要是一定時間段的累加值。
所以我們要每種設(shè)備建一個實時數(shù)據(jù)表,需要記錄設(shè)備的編號、值、以及更新時間。在服務(wù)器端運行一個服務(wù),在采集或整理設(shè)備的數(shù)據(jù),寫到這些表里面。這樣空間數(shù)據(jù)可以建立連接關(guān)聯(lián)每個表即可。
?
附件如何存儲
系統(tǒng)一般都會有附件,附件要以文件的形式存儲到文件服務(wù)器上的磁盤上,文件按照上傳的日期進行文件夾劃分,這樣可以避免一個文件夾下面出現(xiàn)太多的文件,也便于人工查找。文件上傳時要給文件使用GUID重命名,避免一個文件夾下面出現(xiàn)重復(fù)名稱的文件。
在數(shù)據(jù)庫創(chuàng)建多媒體文件數(shù)據(jù)表,字段包括(唯一編碼、名稱、文件真實名稱、上傳時間、文件擴展名、文件大小、歸屬的記錄編碼)。
上傳的文件夾在服務(wù)器上會在IIS里面發(fā)布出來,這樣客戶端就可以瀏覽了。
?
CS上傳需要使用FTP上傳的方式或者調(diào)用WebService。建議使用FTP吧。
我們做的系統(tǒng)一般BS系統(tǒng)服務(wù)器和文件服務(wù)器都是在一臺機器上,但也有可能是兩臺。
如果是一臺:
BS系統(tǒng)直接調(diào)用自己寫的WCF寫到本地即可。
如果是兩臺機器:
就需要在BS系統(tǒng)的WCF上把文件上傳到FTP中。
?
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/xzbluemap/p/3715717.html
總結(jié)
以上是生活随笔為你收集整理的自己在项目设计和开发的一些总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python快速学习09: 函数的参数
- 下一篇: 基于HBASE的并行计算架构之rowke