[英]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.