如何設計數據庫(二)

本篇文章旨在討論如何抽象(以用戶作爲抽象的例子),並提出一些解耦的思路。

正文開始

首先來需求分析

我們的系統有前臺和後臺,前臺用戶有: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十次二十次的,改動起來十分費力)

具體怎麼去解耦,這個問題相當相當的深奧,就不敢在這班門弄斧了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章