簡體   English   中英

如何以正確的方式設計模型:面向對象或“包”為導向?

[英]How to design Models the correct way: Object-oriented or “Package”-oriented?

我知道在OOP中你希望每個對象(來自一個類)都是一個“東西”,例如。 用戶,驗證器等

我知道MVC的基礎知識,它們不同的部分如何相互作用。

但是,我想知道MVC中的模型是否應該根據傳統的OOP設計來設計,也就是說,每個模型應該是數據庫/表/行(解決方案2)嗎?

或者更傾向於收集影響同一個表或一堆相關表的方法(解決方案1)。

CodeIgniter中的地址簿模塊的示例,其中我希望能夠“CRUD”聯系人並將其添加到可從CRUD聯系的組或從其中刪除。

模型解決方案1:將所有相關方法聚集在一起(不是真實對象,而是“包”)

class Contacts extends Model {

     function create_contact() {)
     function read_contact() {}
     function update_contact() {}
     function delete_contact() {}

     function add_contact_to_group() {}
     function delete_contact_from_group() {}

     function create_group() {}
     function read_group() {}
     function update_group() {}
     function delete_group() {}

}

模型解決方案2:OOP方式(每個文件一個類)

class Contact extends Model {
     private $name = '';
     private $id = '';

     function create_contact() {)
     function read_contact() {}
     function update_contact() {}
     function delete_contact() {}

}

class ContactGroup extends Model {
     private $name = '';
     private $id = '';

     function add_contact_to_group() {}
     function delete_contact_from_group() {}

     function create_group() {}
     function read_group() {}
     function update_group() {}
     function delete_group() {}

}

當我想創建模型時,我不知道如何思考。 以上示例是我創建地址簿的真正任務。 我應該把所有功能集中在一個類中。 然后該類包含不同的邏輯(聯系人和組),因此它不能保存特定於其中任何一個的屬性。

解決方案2根據OOP工作。 但我不知道為什么我應該這樣划分。 例如,有一個Contact對象會帶來什么好處。 它肯定不是User對象,那么為什么Contact應該“擁有”自己的狀態(屬性和方法)。 因為我傾向於這樣思考:如果某些東西需要一個狀態,那么我創建一個OOP類,以便這些方法可以根據狀態影響狀態或其他事物。

模特也應該是“有狀態的”嗎? 如果它們不需要狀態,我為什么要根據OOP模式創建它。 那么我可以像“包”解決方案一樣將它們全部捆綁在一起。

你是OOP / MVC的經驗豐富的人,請詳細說明在這個非常具體的任務中應該如何思考(通常在創建模型時)

編輯:來考慮MVC中的控制器。 它們是根據“包”解決方案創建的。 這讓我想知道...

我不知道是否有最好的方法 ,但我會分享我這樣做的方式......

我有一個表網關,例如ContactTableGateway,它包含用於處理聯系人的所有sql。 我喜歡所有sql在一個地方。

class ContactTableGateway extends Model {

    function saveContact( Contact $contact )
    function getContact ( $contact_id )
    function createContact ( Contact $contact )

}

然后我有一個聯系人類,基本上只有getter和setter(或公共屬性)。 此類的對象用作表網關的保存/創建參數

class Contact extends Model {

    function getName()
    function getAddress()
    function getEmail()
    ....

}

下面是一個簡化的例子

if ( isset( $_POST ) ) {

    // some validation here
    $contact = new Contact;
    $contact->name = $_POST['name'];
    $contact->email = $_POST['email']
    $contactTableGateway = new ContactTableGateway;

    if ( $contactTableGateway->createContact( $contact ) ) {
        echo "YAY";
    }
}

每個模型應該是數據庫/表/行(解決方案2)嗎?

不。不要將模型的定義與其持久性方法聯系起來。 雖然對於簡單的應用程序,您可以從數據庫行對象擴展模型,但您應該至少在心理上將它們分開。

模型只是您域中實體的表示,因此必要時它們具有狀態。 在談論Contact模型時,您實際上是在談論映射器或網關,即從數據存儲中檢索模型的對象。 令人遺憾的是,如此多的Active Record臨時實施已經在這方面陷入困境。

Mappers可以作為靜態函數的集合或作為對象實現 - 但是,如果您因任何原因(例如模擬單元測試)而需要擴展或更改行為,則集合的靈活性會降低。

模型本身應該只是一個數據集合,可以存儲為公共屬性,也可以存儲適當的 setter和getter(請不要只為每個變量定義一個get / set函數對,或者你也可以將它們公開),以及對數據進行操作的其他方法。 它應該沒有數據存儲的概念或依賴於數據存儲。 映射器負責通過其接口實例化和初始化模型。 這樣做可以靈活地創建和保存模型。 您可以從數據庫,XML文件,代碼內,通過網絡發送的序列化流中執行此操作,無論您的船是什么漂浮,都可以通過替換不同的映射器,並且模型仍然完全不知道。

我認為您的解決方案#2更優越,因為它更具分子/模塊性,因此更容易理解,更靈活和可擴展(在OOP域中)。 它也更加資源友好,因為它可以讓你只需要在不需要聯系人組功能時加載Contact類,反之亦然。 這是分裂的好處。

如果模型不需要狀態,那么這並不意味着OOP / MVC不適用。 表模型可能在一個設計中沒有狀態,但這就是為什么我們有靜態方法/成員,即Contact :: read($ id)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM