最近公司要開發新系統,基本決定使用ORM(高層還在猶豫,擔心效率問題)。既然使用了ORM,那么自然而然的就想到了用面向對象的思想來設計數據庫
本篇文章旨在討論如何抽象(以用戶作為抽象的例子),並提出一些解耦的思路
我也是第一次在實際項目中使用面向對象的思想來設計數據庫,寫下這篇博客,也是希望與大家多多交流
正文開始
首先來需求分析
我們的系統有前台和后台,前台用戶有:Man,Woman,SuperMan,SpiderMan與IronMan。后台用戶為Administrator
前台用戶都要填寫聯系方式與地址,然后SuperMan,SpiderMan與IronMan都有Ability
需求很簡單。那么按照這個需求,我們來隨手畫一個繼承關系圖。其中V代表抽象類(應該是abstract,畫圖的時候腦抽想着是virtual就用V開頭了,懶得改圖了大家湊合着看吧),I代表Interface。如下圖:

從圖中可以看出,由抽象類Person派生出Administration與抽象類User。類Man與類Womam實現了接口Address與接口Contact,Inhumans則實現了Ability接口
然后抽象類代碼:
View Code
public abstract class Person { public string Username { get; set; } public string Password { get; set; } } public abstract class User : Person { public string Name { get; set; } }
接口代碼:
View Code
public interface IAddress { string Address { get; set; } } public interface IContact { string Email{get;set;} string WorkPhone { get; set; } string MobilePhone { get; set; } string Fax { get; set; } }
最后是Man類和Woman類:
View Code
public class Man : User, IContact, IAddress { public string Address { get; set; } public string Email { get; set; } public string WorkPhone { get; set; } public string MobilePhone { get; set; } public string Fax { get; set; } public bool HasCar { get; set; } //如果這三項都為false的話 public bool HasHouse { get; set; } //這輩子就甭想結婚了 public bool HasMoney { get; set; } //T T我淚涌 }
View Code
class Woman : User, IAddress, IContact { public string Address { get; set; } public string Email { get; set; } public string WorkPhone { get; set; } public string MobilePhone { get; set; } public string Fax { get; set; } public bool IsBeauty { get; set; } //這個為true,一輩子不愁吃喝 }
代碼非常簡單。其他幾個類限於篇幅就不說那么細了
那么按照這個model,使用EF Model First來建立數據庫,得到的Woman表如下:

那么接下來就是重點了:為什么不把Contact和Address分表儲存。這樣與Man表、Woman表寫在一起的話,出現改動(如新增一種聯系方式),會不會非常痛苦
如果不是使用ORM,那么這個改動的確是很痛苦;但是如果使用了(這里默認使用的ORM可以從Model生成/改動數據庫),那么這個改動是沒什么大不了的了,只需要修改一下接口定義,然后根據報錯去改就好了。至於數據庫的變動,就交給ORM去做就OK了
這樣有一個好處,可以在有限的范圍內實現解耦,部分減少了關系——若將Contact和Address分表的話,取Woman要Join兩次,這看起來沒什么大不了的,但是如果放大了看,如果是join十次呢?這樣弄出來的東西很難去維護(現在公司老系統就是這樣,動不動就join十次二十次的,改動起來十分費力)
具體怎么去解耦,這個問題相當相當的深奧,就不敢在這班門弄斧了
就此擱筆
PS:上篇寫RDLC的發首頁被砍了,祈禱這篇不被砍
再PS:我們該如何設計數據庫(一)
