1. 程式人生 > 其它 >面向物件最重要的是“抽象”,三層最重要的也是“抽象”,沒有抽象就不是真正的面向物件、三層。

面向物件最重要的是“抽象”,三層最重要的也是“抽象”,沒有抽象就不是真正的面向物件、三層。

  只用class的,那叫做“基於物件”,比如當初的vb6.0;只是分了三個專案,把以前寫在一起的程式碼分成了三份,所謂的業務邏輯層就是一個傳聲筒,這一類自稱三層的,在我看來都是“模仿三層”,甚至是“偽三層”。

  面向物件,就是要先考慮“物件”,考慮物件的時候完全不用去考慮資料庫結構是什麼樣子的,這個對吧?ORM講究的是現有O後有R,然後再去對映。

程式碼   寫到這裡,突然想到一個觀點:其實O和R是同時有的,他們都是根據專案需求來分別設計的,互不影響!都設計好了之後再去考慮如何對映。   您可能會說,都分別設計,那麼設計之後還能對應上嗎?關於這個問題,本來物件和關係型資料庫的思路就是完全相反的。   面向物件,考慮的是物件,抽象,個體。要把眾多的物件抽象出來,要把眾多的屬性、方法整合起來,要把各個類找到適合的關係。   關係型資料庫,考慮的是劃分,做到資料儘量沒有冗餘,那麼多的正規化要達到的效果是什麼?就是要儘量的分表,分成多個表,每個表只表達一種意思,然後在“關係”(關聯)在一起,以達到避免資料冗餘的目的。   面向物件是根本就不去考慮資料冗餘的問題的,他考慮的是“一”。一個物件的結構,和其他物件的關係(繼承、介面、委託、組合、聚合等)。他不會考慮一萬個例項會如何,至少不會把這個當成重點來考慮。   關係型資料庫考慮的是“多”,多條資料,一萬、十萬、百萬條記錄,要如何處理。多條資料如何處理的問題。

  好像有點跑題了,趕緊回來。

  上一篇,寫的那種“分開”方式,為了三層而三層的做法,我覺得就是偽三層,所以請注意,我說的是偽三層不好,為了三層而三層是不對的。我覺得我上一篇寫程式碼的方式根本就不是真正的三層,所以請大家不要誤會,我並沒有說真正的三層不好,我也不是反對面向物件。

  這一篇我就是想說一下,我使用面向物件的方式。也許我的思路和您的理解不大一致,不過沒關係嘛,拿出來大家一起討論嘛。

  網站,從業務方面(就是客戶的需求)可能的分類形式,比如部落格園

  一開始部落格園並沒有這麼多的模組,後來慢慢加上去了。那麼我們是不是要按照這些分類來設計類呢?一個模組一個類或者若干個類?如果簡單的這麼做的話,那麼就是類爆炸!而且沒有進行抽象。(我不知道部落格園是怎麼做的,這裡只是猜測,從技術角度上的猜測。我只是那大家熟悉的來舉個例子,請不要聯想,謝謝。)

  我作網站的話,會從另一個角度來思考 —— 從頁面的角度來分類

  可能您看著有點暈,這都什麼呀,亂七八糟的,先不要著急,帶我慢慢道來。

請注意,這裡說的是網頁,不包括後臺管理。後臺管理是另一個單獨的專案,和頁面是完全分離開來的。他們的連繫只是讀取同一個資料庫。

  第一個圖裡面分了那麼多的欄目,但是首頁的隨筆列表、左右兩側的各種列表,新聞裡的新聞列表,小組裡的小組列表、小組話題列表等等。這些都是列表,形式、資料格式(就是類的屬性)也都大同小異,那麼我們是不是可以抽象一下呢?針對這些各式各樣的列表抽象出來一個實體類?

  先看小列表

  首頁裡的欄目導航,左側的連線、專題、部落格排行榜,右側的24小時閱讀排行等,這一類的就是我說的“小列表”。

  欄目導航需要哪些屬性?欄目名稱、連線地址。   連線需要哪些屬性?連線名稱、連結地址。   部落格排行榜需要哪些屬性?部落格名稱、連線地址。   24小時閱讀排行需要哪些屬性?隨筆名稱、連線地址。

  好了其他的就不多說了,以免有湊字數的嫌疑。

  現在我們來抽象一下。

  這麼多的屬性,其實就兩個屬性——名稱、連線地址。

【小列表的類的定義】

程式碼
/// <summary>
    /// 簡單的列表
    /// </summary>
    public struct ListInfo1
    {
        /// <summary>
        /// 記錄的主鍵ID。
        /// 對應欄位名(別名):ID
        /// </summary>
        public string ID;            
        /// <summary>
        /// 連結地址,用於靜態頁或者URL重寫,也可以是動態頁面
        /// 對應欄位名(別名):URL
        /// </summary>
        public string URL;            
        /// <summary>
        /// 標題、名稱等
        /// 對應欄位名(別名):Title
        /// </summary>
        public string Title;        
    }

  這麼做的話,一個類可以用在許多的地方,出現新的需求不必再去定義新的類,避免了類爆炸。然後下一步就是考慮如何映射了。對映的思路也是很簡單的,一個類在不同的地方,和不同的表(欄位)進行對映。

不知道有沒有這樣的規定,不允許一個類的屬性和不同的表的欄位作對應。

  您可能會問了,一個屬性一會和隨筆名稱對應,一會和欄目名稱對應,這不亂嗎?這還怎麼維護,怎麼擴充套件,又亂來了!這個就要看對映規則如何來定義了。

  首先要有文件,這個是必須的,文件裡規定,在某個地方,類的屬性和哪個表的欄位對應。這是第一步。

  第二步就是這個對映如何實現了。其實相當簡單,相當的不容易亂。

  我估計好些人都是面向物件習慣了,ORM給慣壞了,把SQL語句都給忘記了。

Select col0 as ID, col1 as Title ,col2 as URL from table1

  不知道大家看到這個SQL語句,有沒有想到我要如何對映。對就是用欄位別名來對映。這麼對映,您還覺得會對映亂嗎?會不好維護嗎?

  因為實體類的結構固定了,那麼給實體類賦值的程式碼(函式)也就固定了,只有SQL語句是變化的。當然了,在頁面裡如何顯示也是變化的。

  這樣的話,程式碼量就會幾何級減少,而且不需要用程式碼生成器,用的話也就是生成個SQL語句了。

  欄位名有變化,只需要修改SQL語句即可,實體類本來就是固定的,不用改。給實體類賦值的程式碼也是固定的,還是不用改。大大的降低了資料庫結構的變動給程式碼帶來的影響。

  今天是五一勞動節,祝大家勞動節快樂!

  今天天氣不錯,先寫到這裡,我去出去晒晒太陽。回來再接著寫。