第3章 資料和對象

來源:互聯網
上載者:User
第二部分應用服務層的設計第3章 資料和對象 3.1資料的形態

在應用軟體系統中,首先要處理的對一個對象就是資料。應用軟體系統,主要目標就是採集資料、處理資料、分析資料、察看資料。對於軟體,誠如有一句名言所說:“軟體,就是資料結構加演算法”。

在軟體中,資料有多種表現形態。

首先,在程式中,資料總是以某種資料結構的方式被表示出來,這種表示,通常被編譯成二進位檔案存在於硬碟上,並且在運行時刻在記憶體中被執行個體化。

這種資料結構有多種表達的方式,簡單的情況下,他可能只是一個數字,或者一個字串,用某個變數來描述。例如,為了表述某種商品的價格,可能使用如下的申明來表述這個資料:

double price = 100 ;

現實中要處理的資料總是比較複雜的,為了描述一個完整的資訊,通常要組合多項簡單的資料,例如,為了描述某種商品的資訊,通常需要描述他的名稱、價格、重量等。在傳統的C語言中,可以使用結構來描述:

struct product

{

    char* name;

    double price;

    double weight;

}

在物件導向的語言裡,類似的資料結構,可以使用類來表述。上面的代碼可以用Java語言表述如下:

public class Product

{

    public String name;

    public double price;

    public double weight;

}

可以看出來,實際上兩者的差別是非常小的。

對於更加複雜的資料結構,一個類可能引用到其它的類,例如,上面的Product,可能有一個Size屬性,而這個Size屬性,也有height和width構成,那麼,整體的資料結構就可以描述如下:

public class Product

{

    public String name;

    public double price;

    public double weight;

    public Size size;

}

public class Size

{

    public int height;

    public int width;

}

資料的另外一種表現形態,就是永久化儲存的形態。上面描述的資料的形態,是一種“瞬時”的資料,只有在程式啟動並執行時候才存在於記憶體中,一旦程式結束,或者資料處理結束,資料就從記憶體中清楚。在很多情況下,需要把處理的資料儲存到磁碟上,這時候,資料就進入永久化儲存狀態。

可以有多種儲存資料的格式。可以把資料儲存為普通文字檔存放在磁碟上,或者,也可把資料儲存在XML檔案中。在Java和C#中,也都提供了這樣一種能力,就是可以把對象序列化後儲存到磁碟上,然後,在需要的時候,可以還原序列化成對象。

雖然有多種持久化儲存資料的方案,然而其中使用關係型資料庫來儲存資料,無疑是最常用的辦法和最可靠的辦法。這就引伸出一個在物件導向的系統設計中的常見問題:對象/關係型映射(O/R Mapping)。

在考慮O/R Mapping的時候,有兩個概念是經常會接觸的,那就是VO和PO

所謂的VO,就是Value Object,這種對象,只包含了對象的資料,而沒有狀態,或者說,處於瞬時狀態。VO可以用來在層之間傳遞資料

所謂PO,就是Persistent Object,就是持久化儲存的對象,這種對象,一般是有狀態的。O/R Mapping架構需要根據PO的狀態,來執行相應的同資料庫的互動。關於PO的狀態,我們在後面再討論

3.2對象/關係型映射

對象關係型映射,最核心的要完成兩個功能:對象和關係型之間的映射規則,以及兩者之間的相互轉換。

除了這兩個基本的功能,一般的O/R Mapping產品還會加上一些額外的特性和功能,以加強產品的功能,為軟體開發提供更多的方便和提高效能。一些常見的功能,例如緩衝。

現在有一些典型的O/R Mapping架構可以參考和使用,比較著名的有EJB中的Entity Bean,JDO,Hibernate等,這些方案都是基於Java的。在Microsoft.Net平台下,相對來說可供選擇的方案比較少,其中有一個開放原始碼的方案Websharp,可以從 www.websharp.org 下載。

我們在實際開發中,可以選擇使用已有的解決方案和產品,也可以自己設計自己的O/R Mapping架構。當然,無論採用何種方式,都需要我們對O/R Mapping的基本原理和方法有一個基本的瞭解。

在支援OO的語言中,繼承是語言的基本特徵。O/R Mapping的架構,也需要對繼承做出相應的支援。一般說來,有三種繼承模式:ONE_INHERITANCE_TREE_ONE_TABLE、ONE_INHERITANCE_PATH_ONE_TABLE和ONE_CLASS_ONE_TABLE。

ONE_INHERITANCE_TREE_ONE_TABLE:

一個繼承樹映射到一個表,即將具有相同父類的所有類都映射到一個資料庫表中,這些類屬性對應的集合組成這個表的列,在這種模式下,只需要對最底層的類進行映射。

如下面一個類結構:

 

在這個類結構中,父類Parent有兩個子類Child1和Child2,父類有屬性Property1和Property2,Child1新增了一個屬性Property3,而Child2新增了另外一個屬性Property4,當採用ONE_INHERITANCE_TREE_ONE_TABLE映射模式的時候,資料庫中只有一張表,結構如下:

 

其中,Column1和Column2欄位分別對應Parent類的Property1和Property2屬性,Column3欄位對應Child1的Property3屬性,而Column4欄位對應Child2的Property4屬性。Column3對於Child2和Column4對於Child1是沒有意義的。

採用這種映射模式,優點是比較簡單,缺點是資料的冗餘比較大。這個表要容納所有的子類的欄位,很多欄位只是對某個類有意義,而對於其他類則沒有意義,是純粹多餘的,並且,在繼承樹中新增一個繼承節點的時候,往往導致表的欄位的重新設計,這是一件非常麻煩的事情。

ONE_INHERITANCE_PATH_ONE_TABLE:

一個繼承路徑映射到一個表,即將一個類映射到一個資料庫表中,這個類的所有屬性(包括從父類繼承來的)映射的集合組成這個表的列。

在這種模式下,對於上面的類結構,資料庫的結構就是:

 

其中,表Child1和Child2分別對應於類Child1和Child2。

這種模式是非常常用的,也沒有資料冗餘,缺點是在搜尋的時候比較麻煩。例如,當我要搜尋符合某個條件的Parent對象的時候,需要同時搜尋Child1和Child2表,並且,當在繼承樹中新增一個繼承節點的時候,需要新增一個表,搜尋的範圍也必須擴大,原來的程式可能不得不重新設計。

ONE_CLASS_ONE_TABLE:

一個類映射到一個表,即將每個類映射到對應的一個表,這個類的屬性(不包括從父類繼承來的非主鍵屬性)映射組成這個表的列,在這種模式下,具有繼承關係的類被映射到不同的表中,表之間通過主鍵關聯。

在這種模式下,對於上面的類結構,資料庫的結構就是:

 

表Parent作為Child1和Child2的父表,父子表之間通過主鍵Colimn1關聯。

這種模式是非常容易理解的,因為和類圖非常相像,缺點是在查詢的時候,由於設計到表的關聯,SQL語句會比較複雜,效率也會比較低。這個情況當繼承數的深度增加的時候,會體現的比較明顯。

如果一個類沒有子類和父類,那麼採用三種模式中的哪一種都是一樣的效果。

3.3對象的狀態

為了很好的控制對象,以及在同後台儲存互動時的行為,通常O/R Mapping架構需要維護PO對象的狀態。在不同的架構中,對對象狀態的定義不盡相同,不過,也都有一些共同點,某些方面可能只是名稱的不同。通常的O/R Mapping架構都需要以各種方式來直接或間接的處理PO的這些狀態。下面列出的一些狀態是一些基本的,比較共通的一些狀態

? Transient

? Persistent-new

? Persistent-dirty

? Persistent-clean

? Persistent-deleted

Transient

在這種狀態下,對象處於一種“瞬時”的狀態,還沒有同任何資料庫的資料相關聯,對象也不受O/R Mapping架構的運行時控制,對象的表現就是一個普通的類的執行個體。

比較典型的,在JDO裡面,對於Transient的狀態的說明如下:

JDO instances created by using a developer-written or compiler-generated constructor that do not involve the persistence environment behave exactly like instances of the unenhanced class.

There is no JDO identity associated with a transient instance.

There is no intermediation to support fetching or storing values for fields. There is no support for demarcation of transaction boundaries. Indeed, there is no transactional behavior of these instances, unless they are referenced by transactional instances at commit time.

When a persistent instance is committed to the datastore, instances referenced by persistent fields of the flushed instance become persistent. This behavior propagates to all instances in the closure of instances through persistent fields. This behavior is called persistence by reachability.

No methods of transient instances throw exceptions except those defined by the class developer.

A transient instance transitions to persistent-new if it is the parameter of makePersistent, or if it is referenced by a persistent field of a persistent instance when that instance is committed or made persistent.

意思是說,

 Persistent-new

這種狀態,表示一個新的可持久化對象,該對象還沒有被儲存到儲存介質中。在這種狀態下,當事務結束被提交的時候,架構會執行一個插入的操作,將對象儲存到存放裝置中。

Persistent-dirty

這種狀態,表示一個對象是可持久化的對象,已經對應於資料庫中的某表記錄,但是,在程式中,該對象已經被編輯過,與資料庫中的資料並不同步。在這種情況下,當事務被被提交的時候,架構會執行一個更新的操作,將對象和資料庫同步。

Persistent-clean

這種狀態,表示一個對象是可持久化的對象,並且與資料庫中的資料是同步的。

Persistent-deleted

這種狀態,表示一個對象是可持久化的對象,並且該對象已經被刪除。在這種情況下,當事務被被提交的時候,架構會執行一個刪除的操作,將資料從資料庫中刪除。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.