2012-04-12 28 views
2

我正在使用ZF的MVC應用程序,並大量混淆我的代碼應該如何構造。ZF MVC - 對象和映射器

我有一個程序性應用程序,它基本上是一個巨大的長文件,具有我希望我的應用程序執行的所有操作的功能....就像getUsername($ id)等等。所以現在我正在重建整個事物在ZF中,因爲我當前的代碼庫不可行,垃圾並且很難調試。

我是新來的MVC和大量混淆應該如何佈局,什麼應該談什麼等等。所以我知道關於模板和控制器需要瘦,以及你應該有胖模型但我很困惑邏輯的需要。

我正在做一個遊戲,平時有喜歡的對象....用戶,村,軍隊,MapSquares,資源等

如果我完全想它理論,我只想說: 1用戶對象包含許多村莊,每個村莊屬於一個廣場,並且包含軍隊(其中包含許多單位)。

所以我認爲我的模型不應該包含任何邏輯,只是獲取和設置函數列表來檢索數據,處理邏輯,問問題應該在Mapper內部完成......例如:

$villageMapper = new VillageMapper(); 
// Get village from database using mapper 
$village = $villageMapper->getVillage($id, new Village()); 

當我想確定說兩個村莊相互攻擊的結果時,在哪裏做?我會做類似的事情嗎?

$outcome = $villageMapper->determineAttackOutcome($village1, $village2); 

或者我會說......戰術物體裏面有一些邏輯嗎?

$battle = new Battle(); 
// Add participants 
$battle->addAttacker($village1)->addDefender($village2); 
$outcome = $battle->performAttack(); 
// Save village changes cause of battle 
$villageMapper->save($battle->getAttacker()); 
$villageMapper->save($battle->getDefender()); 

我有一大堆的DBTABLE PHP文件,我想所有的數據庫代碼住在...所以我的問題是:如果我映射對象只有真正使用的東西像,獲取並保存到數據庫?

感謝,大教堂

+1

映射器充當數據庫表和對象之間的接口。所以你的戰鬥應該可以在你的mapper之外進行。 – Config 2012-04-12 20:23:51

回答

5

有MVC的許多不同的解釋,但是這是我的理解是:

模型:包含幾乎所有與特定項目有關的邏輯。每一個必須建模的東西(在你的情況下,用戶,villiages等)都有一個模型。該模型具有獲取數據並將數據放入(i。即獲得者和制定者)。該模型也做錯誤檢查等,並確保沒有衝突輸入英寸

查看:沒有任何邏輯。在一個Web應用程序中,這實際上只是表示將內容放在頁面上的東西。在某些框架中,您爲視圖提供了一個模型(即ASP.NET MVC3),但在其他框架(如Savant3 for php)中,它可以提供任何東西。控制器通常會提供視圖,但是如果視圖被賦予一個模型,它只會從模型中讀取並且不會寫入該模型。

控制器:控制用戶和模型之間的交互。當用戶做某事時,控制器將其轉換爲模型必須做的事情。例如,如果你對節目「請將我的角色向北移動6個空間」說,控制器會說:「有什麼東西跑到北面的6個空間嗎?」如果它看到這個地方很清楚,它會告訴人物模型「向北移動6個空間」。這樣做之後,它會將數據發送到視圖,以顯示作爲結果顯示的內容。控制器中實現的大多數實際邏輯應該是用戶模型而不是模型模型。模型之間的交互可以通過單個模型中的方法或封裝某種行爲或交互的其他模型來處理。

因此,在您的實現:

我會做一個戰鬥的對象(這是一個模型),它的構造函數有兩個村莊或任何戰鬥。它會有一個叫做execute或doBattle的方法或控制器會調用的某個方法,然後戰鬥對象將執行其邏輯來決定結果並更新戰鬥員的狀態(即降低HP,給予經驗等)。它會向控制器返回結果,以便控制器知道該做什麼(即,如果控制器因爲死亡而需要忘記模型,它會告訴它)。這個返回值也可能是發送給視圖來說明戰鬥結果的東西。

您的一些模型(如用戶,村莊等)將被保存在數據庫中,因此模型會知道如何將自己映射到該數據庫(或者它會與另一個知道如何映射它的圖層進行對話),並且要注意更新數據庫和東西的確切實現(控制器會調用實際的方法來「保存」,但模型將是唯一知道幕後發生的事情)。其他模型(如戰鬥)不需要存在於數據庫中,因爲它們只是邏輯封裝了一些交互。

+0

我不同意你對控制器的描述。如果你對程序說'把我的角色移到北方6',那麼控制器不應該檢查任何東西,它應該把請求交給模型。然後,模型會執行所需的任何檢查/移動操作,並將新位置報告給控制器。 – vascowhite 2012-04-13 13:37:20

1

有一個脂肪模式意味着然後幾乎所有的邏輯模型中存在。

一些sugesstions ...

如果你正在做的領域驅動設計(http://en.wikipedia.org/wiki/Domain-driven_design)你的村莊對象可以是管理業務邏輯的聚合根那個村莊。

一場戰鬥也可能是一個由兩個(或多個)村莊對象組成的聚合根,或者是一個服務,它接收兩個村莊對象並返回一個「結果」對象。你也可以按照$ village-> attack($ anotherVillage)的方法做一些事情,這樣可以返回一個戰鬥對象,然後你可以繼續。

我建議以下領域驅動設計和庫模式,當談到創建和堅持這些業務對象http://msdn.microsoft.com/en-us/library/ff649690.aspx

1

Datamapper只能用於存儲和檢索數據庫中的數據並將該數據映射到您的域對象(用戶,村莊,軍隊,MapSquares)。

您可以將您的邏輯放入您的域對象中,但我喜歡使用服務層。

在你的控制你會做這樣的事情:

function attackAction() { 
    $gameService->doVillageBattle($villageId1,$villageId2); 
} 

GameService會是什麼樣子:

doVillageBattle($villageId1,$villageId2) { 
    $village1 = villageService->getById($villageId1); 
    $village2 = villageService->getById($villageId2); 

    if ($village1->getStrength() > $village2->getStrength()) { 
     $village1->winBattle(); 
     $village2->looseBattle(); 
     $villageService->save($village1); 
     $villageService->save($village2); 
    } 

} 

最後VillageService將有:

function save($village) { 
    villageMapper->save($village); 
} 

所以控制器跟服務只有和服務彼此對話或與邏輯上與t相關的數據加載程序進行通信下襬。服務承載了大部分「業務邏輯」,並且獨立於數據庫。 Datamappers是獨立於服務控制器的服務&。