• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            我生如山

            一個小型CRM系統(tǒng)的設(shè)計(未完成版本)

            Core-Man System Design Document Version 1.0 9/29/2009 Contents 簡介 4 系統(tǒng)總體架構(gòu)介紹 4 系統(tǒng)具體設(shè)計 6 后記 6 簡介 本文檔用來描述Core-Man這個用來為汽配行業(yè)做貨物、訂單、客戶關(guān)系管理的系統(tǒng)功能和設(shè)計。本文檔基于該系統(tǒng)的需求分析和前期市場調(diào)研,關(guān)于需求分析和市場調(diào)研的結(jié)果,可以查看文檔XXXX. 1. 系統(tǒng)設(shè)計目標(biāo) 為了使得系統(tǒng)能最大程度的滿足用戶的需求,盡可能的減少以后再定制維護(hù)過程中的代價,Core-Man系統(tǒng)應(yīng)該達(dá)到以下幾個目標(biāo): ? 可定制性:雖然本系統(tǒng)是為了汽配行業(yè)的客戶管理而設(shè)計的,但是本系統(tǒng)需要達(dá)到在特定的需求下經(jīng)過適當(dāng)?shù)呐渲茫〝?shù)據(jù)庫配置,配置文件更改)而達(dá)到滿足其他行業(yè)需求的目的。 ? 可維護(hù)性:本系統(tǒng)的設(shè)計應(yīng)該達(dá)到可維護(hù)的目的,因?yàn)橛脩舻男枨罂赡軙兓ㄆ髽I(yè)規(guī)模擴(kuò)大,經(jīng)營業(yè)務(wù)增多)。在用戶變化需求的時候,我們的系統(tǒng)就需要升級,那么在升級的過程,至少需要滿足兩方面的可重用,一是數(shù)據(jù)上的可重用。客戶在一定的經(jīng)營過程中積累了一定數(shù)目的用戶資源和經(jīng)營經(jīng)驗(yàn)數(shù)據(jù),這部分?jǐn)?shù)據(jù)對于客戶以后繼續(xù)經(jīng)營,擴(kuò)大業(yè)務(wù)規(guī)模都是有重要作用的。在我們的系統(tǒng)升級的過程,應(yīng)該使得客戶可以重用這部分?jǐn)?shù)據(jù),即使得升級后的系統(tǒng)能夠識別維護(hù)舊的數(shù)據(jù)。另一方面的可重用性是指代碼上的可重用性,系統(tǒng)的升級不能使推到系統(tǒng)重來。新系統(tǒng)應(yīng)該基于舊系統(tǒng)已有的代碼,這樣可以最大程度上的節(jié)省成本。 ? 安全性:雖然在系統(tǒng)初期,客戶對于安全性上的要求不會很高,但是隨著企業(yè)業(yè)務(wù)規(guī)模的擴(kuò)大,必然涉及到很多的商業(yè)保密信息。企業(yè)的客戶數(shù)據(jù),訂單數(shù)據(jù),管理模式都有很重要的商業(yè)價值,此時對于我們系統(tǒng)的安全性就提出了要求。Core-Man系統(tǒng)的安全性主要體現(xiàn)在一下幾個方面: ? 用戶認(rèn)證:系統(tǒng)應(yīng)該區(qū)分登錄的會話中用戶的身份,以此來判斷用戶可訪問哪些數(shù)據(jù),可更改哪些數(shù)據(jù),這個對于一個中大型企業(yè)里面,各個管理層面(老板,總經(jīng)理,經(jīng)理,員工)應(yīng)用同一個系統(tǒng)式很重要的。 ? 權(quán)限管理:驗(yàn)證用戶后,需要判斷已驗(yàn)證用戶是否被允許訪問其所請求的數(shù)據(jù),在判斷通過的情況下,系統(tǒng)返回正確的響應(yīng);否則,系統(tǒng)告知客戶端無權(quán)訪問。 ? 數(shù)據(jù)加密:企業(yè)的客戶數(shù)據(jù),員工數(shù)據(jù),訂單數(shù)據(jù)都涉及到商業(yè)秘密。這些數(shù)據(jù)都需要經(jīng)過加密后存儲在系統(tǒng)的文件系統(tǒng)或者數(shù)據(jù)庫中。 系統(tǒng)總體架構(gòu)介紹 很明顯的Core-Man系統(tǒng)是一個以數(shù)據(jù)庫為中心,以多終端進(jìn)行數(shù)據(jù)處理維護(hù)的分布式系統(tǒng),一個Core-Man系統(tǒng)的典型的應(yīng)用場景可以用下圖來描述: 在上面的應(yīng)用場景中,各個角色的分工如下: ? 中心數(shù)據(jù)庫:負(fù)責(zé)提供整個系統(tǒng)的數(shù)據(jù)的存貯,這里包含兩部分內(nèi)容 ? 由數(shù)據(jù)庫管理系統(tǒng)托管的數(shù)據(jù)庫表,視圖,存儲過程,數(shù)據(jù)等信息。 ? 由文件系統(tǒng)托管的圖片,文件等信息。 ? 請求監(jiān)聽/代理服務(wù)器:負(fù)責(zé)作為終端用戶和數(shù)據(jù)庫之間通信的一個代理人的角色。所有客戶端的操作如果涉及到數(shù)據(jù)庫查詢/更改請求,由請求監(jiān)聽/代理服務(wù)器將其轉(zhuǎn)換為對相應(yīng)數(shù)據(jù)庫項目的查詢/更新操作。這樣的設(shè)計能使得終端用戶和數(shù)據(jù)庫的耦合性降到最低,使得在需要更換數(shù)據(jù)庫的時候,我們只需要更新請求監(jiān)聽/代理服務(wù)器里面與數(shù)據(jù)庫交互的那部分代碼。同時,加進(jìn)一層請求監(jiān)聽/代理服務(wù)器,可以讓我們的系統(tǒng)在這一層進(jìn)行安全性上的檢查更改等操作,比如,在這一層做終端用戶身份的鑒別,只有終端用戶是授權(quán)用戶的時候,我們才允許客戶端進(jìn)行后續(xù)操作。 ? 超級管理終端:這個終端有最大的管理權(quán)限,用于進(jìn)行數(shù)據(jù)的備份,緊急模式下的更改等操作。 ? 分布式終端1:本系統(tǒng)眾多分布式終端的其中一個,用戶為普通用戶(經(jīng)理,員工,客戶)提供訪問我們系統(tǒng)的功能。每一個分布式終端在發(fā)起連接請求監(jiān)聽/代理服務(wù)器的時候,都需要提供用戶身份的信息,請求監(jiān)聽/代理服務(wù)器用這些信息來判斷發(fā)起連接的用戶是否是一個經(jīng)過授權(quán)的用戶。 下圖描述了我們的數(shù)據(jù)庫設(shè)計的基本輪廓: 下圖描述了我們的請求監(jiān)聽/代理服務(wù)器的設(shè)計模塊以及模塊之間的聯(lián)系: 自上至下,三個大的模塊分別是: ? 請求監(jiān)聽層:負(fù)責(zé)監(jiān)聽客戶端的操作請求,檢查客戶端的身份,以及客戶端的權(quán)限。如果客戶端是經(jīng)授權(quán)的用戶并且其請求操作被策略允許,請求監(jiān)聽層會將該請求放進(jìn)該層維護(hù)的請求隊列中。放進(jìn)請求隊列中的請求包含請求的客戶端信息,請求的優(yōu)先級,請求所要進(jìn)行的具體操作等等。請求監(jiān)聽層會有一個請求分發(fā)線程,從請求隊列中按照一定的策略找出一個請求,將該請求送往邏輯處理層。 ? 邏輯處理層:邏輯處理層的主要功能是維護(hù)抽象的數(shù)據(jù)模型,使得請求層不必與具體的數(shù)據(jù)庫訪問器接口方法做交互。邏輯處理層將請求監(jiān)聽層分發(fā)過來的請求轉(zhuǎn)換為對特定抽象數(shù)據(jù)的操作,這就使得在這一層能盡最大可能地應(yīng)用面向?qū)ο笤O(shè)計的好處,為以后的升級,定制提供方便。邏輯處理層由請求監(jiān)聽模塊,邏輯處理模塊和邏輯對象管理器組成。請求監(jiān)聽模塊將請求監(jiān)聽層分發(fā)過來的請求轉(zhuǎn)換為對特定邏輯對象的操作。邏輯處理模塊是一個特定的線程,負(fù)責(zé)調(diào)用邏輯對象管理器的方法來進(jìn)行邏輯多項生命周期的維護(hù)。邏輯對象管理器負(fù)責(zé)提供邏輯對象的管理接口,比如邏輯對象的創(chuàng)建,刪除等操作。 ? 數(shù)據(jù)庫訪問層:數(shù)據(jù)庫訪問層主要由數(shù)據(jù)庫訪問器接口和數(shù)據(jù)庫訪問器實(shí)現(xiàn)來組成。這一層提供具體的數(shù)據(jù)訪問操作給邏輯處理層使用。數(shù)據(jù)庫訪問器接口和數(shù)據(jù)庫訪問器實(shí)現(xiàn)分屬于不同的程序集,這樣就使得數(shù)據(jù)庫訪問器實(shí)現(xiàn)能很方便的被替換,使系統(tǒng)能遷移到使用新的數(shù)據(jù)庫系統(tǒng),只要我們提供新數(shù)據(jù)庫系統(tǒng)的數(shù)據(jù)庫訪問器實(shí)現(xiàn),并且更改數(shù)據(jù)庫訪問層的程序配置文件指向新的數(shù)據(jù)庫訪問器實(shí)現(xiàn)。 系統(tǒng)具體設(shè)計 本章節(jié)按照“系統(tǒng)總體架構(gòu)介紹”里面描述的模塊順序逐個介紹這些模塊的具體實(shí)現(xiàn)策略。 請求監(jiān)聽層: 請求監(jiān)聽模塊: 設(shè)計請求監(jiān)聽模塊涉及到設(shè)計我們所使用的具體的網(wǎng)絡(luò)協(xié)議的格式,在初步的設(shè)計里面,我們使用 .Net對于 WinSocket的封裝來實(shí)現(xiàn)網(wǎng)絡(luò)數(shù)據(jù)的傳輸,使用TCP/IP協(xié)議。在TCP的payload里面?zhèn)鬏斘覀兊恼埱笙⒑晚憫?yīng)消息。消息格式如下: 其中各個字段的含義如下: Command Value: 用于指示操作碼,如果系統(tǒng)最高位是0,表明這是系統(tǒng)定義的操作碼;如果最高位是1,則表明是用戶定義的操作碼。對于每一個特定的操作碼,系統(tǒng)應(yīng)該提供一個該操作碼下的Request Data的解析函數(shù);所以,如果用戶需要定義自己的操作碼,那么他也應(yīng)該提供該操作碼下的Request Data的解析函數(shù)實(shí)現(xiàn)。解析函數(shù)有特定的格式如下: public Dictionary RequestDataParser(ushort commandValue, ushort flags, Guid sessionId, byte[] requestData); 其輸入為一個完整的包結(jié)構(gòu),輸出為解析出來的Request Data中包含的有意義的字段對應(yīng)C#中的數(shù)據(jù)類型,以及這些數(shù)據(jù)的值。這樣子就是得我們能在我們的請求監(jiān)聽層初始化的時候根據(jù)配置文件中的解析函數(shù)配置注冊合適的解析函數(shù),在運(yùn)行中能夠調(diào)用注冊好的配置函數(shù)解析對應(yīng)的網(wǎng)絡(luò)數(shù)據(jù)將其轉(zhuǎn)換為有意義的邏輯數(shù)據(jù)。 在這種設(shè)計之下,用戶如果需要定義自己的Command Value,假設(shè)其值為0xF000,那么用戶提供一個叫做CustomeRequestDataParser.dll的程序集,其中包含了對于Command Value0xF0000下的Request Data的解析函數(shù)實(shí)現(xiàn),其實(shí)現(xiàn)如下: public class CustomeRequestDataParser { public Dictionary RequestDataParser(ushort commandValue, ushort flags, Guid sessionId, byte[] requestData) { Dictionary result = new Dictionary(); if (requestData.Length != 8) { throw new ArgumentException("Invalid network data received."); } byte[] field1 = new byte[4]; byte[] field2 = new byte[4]; Array.Copy(requestData, field1, 4); Array.Copy(requestData, field2, 4, 4); result.Add( typeof(uint), BitConverter.ToUInt32(field1, 0)); result.Add(typeof(uint), BitConverter.ToUInt32(field2, 0)); return result; } } 在我們的請求監(jiān)聽層的程序配置文件中存在這么一項: 在我們的請求監(jiān)聽層的初始化代碼中存在這么幾行代碼: public void RegisterRequestDataParsers() { System.Collections.Specialized.NameObjectCollectionBase.KeysCollection keysCOllection = ConfigurationSettings.AppSettings.Keys; List requestDataParserKeys = new List(); foreach (string keyValue in keysCOllection) { if (keyValue.Contains("CommandValueParser")) { requestDataParserKeys.Add(keyValue); } } foreach (string keyValue in requestDataParserKeys) { string assemblyPath = GetAssemblyPath(ConfigurationSettings.AppSettings[keyValue]); if (!IsAssemblyLoaded(assemblyPath)) { AppDomain.CurrentDomain.Load(assemblyPath); } string typeName = GetTypeName(ConfigurationSettings.AppSettings[keyValue]); ushort commandValue=GetCommandValue(ConfigurationSettings.AppSettings[keyValue]); if (!registeredRequestDataParsers.ContainsKey(commandValue)) { registeredRequestDataParsers.Add(commandValue, Type.GetType(GetTypeFullName(typeName))); } } } 當(dāng)請求監(jiān)聽模塊收到一個請求之后,它會將其轉(zhuǎn)換為一個事件,將其放進(jìn)事件隊列中,一個事件應(yīng)該包含以下信息: public class Event { private DateTime timeStamp; private ushort commandValue; private ushort flags; private Guid sessionId; Dictionary requestData; } 一個時間隊列的可能定義如下: public class EventQueue { private List eventPool; private uint eventCount; private Event mostPrioritizedEvent; } 請求調(diào)度模塊不斷的查詢事件隊列中的時間,按照特定的調(diào)度策略找出一個合適的事件交給邏輯層處理: public abstract class EventSelectionPolicy { } public class EventQueueProcessor { private EventQueue eventQueue; private EventSelectionPolicy eventSelectionPolicy; public void RegisterEventQueue(EventQueue queue) { if (this.eventQueue != null) { throw new ArgumentException("Unable to register another event queue when a queue is still in processing."); } this.eventQueue = queue; } public EventQueue UnregisterEventQueue() { if (this.eventQueue == null) { throw new InvalidOperationException("Unable to unregister an event queue when the queue is not intialized."); } EventQueue queue = this.eventQueue; this.eventQueue = null; return queue; } public void RegisterEventSelectionPolicy(EventSelectionPolicy policy) { this.eventSelectionPolicy = policy; } public Event SelectEvent() { // //return ...; } } EventQueueProcessor調(diào)用SelectEvent方法按照注冊過的調(diào)度策略選擇一個event交給邏輯處理層處理。 后記

            posted on 2009-11-06 13:26 悟山 閱讀(218) 評論(0)  編輯 收藏 引用


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            国产—久久香蕉国产线看观看| 久久久久久久99精品免费观看| 伊人久久精品影院| 亚洲精品无码久久久久去q| 久久777国产线看观看精品| 久久久久久A亚洲欧洲AV冫| 少妇人妻88久久中文字幕| 国产精品久久久久一区二区三区| 久久精品aⅴ无码中文字字幕不卡| 久久久无码精品亚洲日韩按摩 | 久久精品一本到99热免费| 久久这里只精品国产99热| 一本大道久久东京热无码AV| 国产三级久久久精品麻豆三级| 欧美午夜A∨大片久久| 9久久9久久精品| 久久婷婷国产剧情内射白浆| 99久久无码一区人妻| 久久久噜噜噜久久熟女AA片 | 中文字幕日本人妻久久久免费 | 亚洲国产精品久久电影欧美| 久久精品三级视频| 大蕉久久伊人中文字幕| 国产三级久久久精品麻豆三级| 久久天天躁狠狠躁夜夜avapp| 久久久久国产精品三级网| 91精品国产91久久| 久久久久夜夜夜精品国产| 国产∨亚洲V天堂无码久久久| 少妇内射兰兰久久| 久久精品亚洲精品国产色婷| 麻豆av久久av盛宴av| 久久午夜免费视频| 精品伊人久久久| 国产成人精品综合久久久久| 四虎久久影院| 国产精品99久久久久久宅男小说| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 久久夜色精品国产| 欧美久久一区二区三区| 亚洲v国产v天堂a无码久久|