在第一篇中,我們已經引出了話題。在經過初步的分析之後,整個team的思路很明確。從業務邏輯入手,兵分兩路,一路向ui開進,一路向database開進。而關鍵的部分就是中間實體類的設計。
1,模型的重構
在第一篇中,我們已經確定了基本的模型。但是,這個模型準確嘛?無論是平民,還是殺手,以及警察,他們只是遊戲中的乙個角色。而這個角色真實的身份,應該是使用者。這樣,先把使用者類抽提出來。如下。大家需要注意的是,這裡的類圖,我是拿or designer畫的。先暫且不管每個property是什麼型別的。這個類包含乙個user最基本的資訊。userid是用來標誌他的唯一編號。其中isonline來儲存這個使用者的狀態。winnum和playnum分別是他贏的次數和玩的次數。
在有了user類後,下乙個沒有爭議的類就該是game了。它的定義如下
gameno是每個遊戲的唯一標誌。這其中還定義了開始時間,結束時間。當然,還定義了誰最終贏得了game,以及平民,殺手,警察的數量。這兩個實體,是本程式中,最基本的實體。也能準確體現現實世界中物件。那麼,針對乙個user,只有把他放在特定的game中,他才能算是乙個玩家。如果,他不加入到game中,那他就不算玩家,而只能算是乙個user。有的user是平民,有的殺手,而又有的是警察。那又該如何體現user在game中的角色呢?思路有這麼兩個,第一,從user繼承,分別寫平民,殺手等類。第二,單獨建立乙個player類。針對第乙個思路,在建立物件的時候,需要new出不同的類,而且在判斷user的身份時,需要呼叫反射,看是什麼類的物件才知道。更麻煩的是,如何把它向資料庫方向推呢?這個思路寫出的**很容易懂,卻也有它的弱點。不知道它弱點的人,就無法使用好它。第二個思路比較簡單,切實可行。player類的定義如下。
這個類裡,定義了userid和gameno,這樣,就很容易和game和user做關聯。isactive用來儲存這個player是否還活著。roleid則是其身份的標誌。deadactivityno是他在那次活動中死去(先不說這個)。這裡,roleid作為乙個property來判斷玩家的身份,避免了不同的類需要反射的問題。更重要的是,這樣的設計很容易推向資料庫。那roleid 的值實際上被限定在某個集合內。這個集合被定義為列舉型別。如下:
public
enum
roleflag :
int這裡為1,2,4是方便後來的位運算。並沒有其他的特殊設定。 這樣,最基本的模型確定了。緊跟著需要做的,就是設計各個class中的property一系列的屬性了。如圖
這是gameno的屬性設定。這裡它被設成主鍵。還有,它在clr中的type為int,在server端的data type 為int not null identity。也就是int的自增型。在這裡,其他的都好設定,唯獨server data type需要設計者對資料庫和dbml格式特別熟悉。這也是為什麼筆者一直帶著大家熟悉dbml。把各個類中的字段的屬性設定後,下一步就是建立關係了。
這個模型也很容易懂。乙個user在不同時間可以加入不同的game,乙個game可以擁有多個user。那這樣,正好用player這個實體類將他們聯絡起來。就是乙個user在不同時間,可以扮演不同角色,乙個game可以擁有多個角色。那針對player中的roleid這個字段,它只有三個值,又該如何在資料庫中體現它呢?大家都知道,資料庫中,對於列舉型的,也只有把它們存在乙個特殊的表裡。然後,把這個錶用相關的字段和另乙個表的相關欄位建裡關係就可以了。這樣,又從roleflag抽像出乙個叫role實體類來。用如下的功能建立關係,右擊game類,選擇add->association,
這裡把各個實體的關係建立起來。選擇合適的字段。需要注意的是,別把parent和child搞反了。這樣,整個模型如下:
2 業務邏輯中的物件抽提
單純從client和server角度講,它們是通過訊息通訊的。在本專案中ui 端的所有的物件,包括平民和殺手,他們之間所有的動作,比如,殺人,發言和投票,其實也都是通過訊息機制發回server端。如果從這個角度來考慮的話,無論是殺人,投票和發言,均可以理解為乙個訊息。只是這個訊息有三種罷了。這樣,就有activity實體類定義了這個訊息體。又定義了列舉
public
enum
activitytypeflag :
int殺人遊戲系列 之二
殺人遊戲系列 之一
其他:linq to sql高階系列 -目錄導航
c# 3.0入門系列-目錄導航
殺人遊戲 約瑟夫問題
沒有查閱資料,硬想的,有點死板的演算法。工具用arraylist 每一次遍歷整個佇列,計算出總共被殺的人的所有位置,將計算出的位置的所有值設為0 然後將值為零的一次性刪除 arraylist.remove 0 直到佇列的長度為1。需要注意的是 只能一次性刪除遍歷整個一輪後的佇列位置,因為arrayl...
殺人遊戲 深搜
輸入格式 輸出格式 樣例輸入 5 4 1 2 1 3 1 4 1 5樣例輸出 0.800000資料範圍與提示 上 void add int x,int y head x tot void dfs int x int main for int i 1 i n s i for int i 1 i n s...
hibernate系列之二
首先先介紹一下持久化 持久化 將程式資料在持久狀態和瞬時狀態間轉換的機制 即將記憶體的資料永久存在關係型資料庫中 持久化類的編寫規則 持久化類需要提供無參構造方法 持久化類的屬性需要私有,對私有的屬性提供get set方法 持久化類的屬性盡量使用包裝類的型別 持久化類要有乙個唯一標識oid與表的主鍵...