2009-04-24 23 views
4

我讀過很多微不足道的MVC計算器和溫度計的例子,但我似乎無法將模式映射到真實世界的應用程序。MVC - 它在現實世界中如何運作?

假設您有更復雜的場景。假設你有一個網站購物車,需要用戶登錄才能加入購物車。首先,用戶看到產品頁面(/ product/detail)並點擊添加項目(/ cart/add/207366)。用戶尚未登錄,因此他們需要訪問登錄頁面(/ user/login),然後對流程進行智能化,將其帶到購物車視圖(/ cart/list)。從那裏,他們可以鏈接回原始產品詳情頁面繼續購物。

假設我們有3個數據庫表:用戶,usercart和產品。這種情況下的模型是什麼?將整個流程封裝到ShoppingCart模型的addProductToCartFlow函數中?這似乎有點混亂,因爲它需要訪問用戶表進行登錄/驗證,並訪問產品表以將產品詳細信息/價格拖入購物車。

相反,你會說ShoppingCart模型是自包含的,只處理添加項目,刪除項目等從購物車?用戶登錄的「邏輯」將在其他地方進行檢查:可能是在控制器本身?這會使控制器非常繁忙,帶有相當多的「業務邏輯」,例如檢查用戶是否已登錄,檢查購物車是否空等,並且該模型只是成爲數據庫表的一個漂亮名稱。

或者,也許登錄或註銷的事實是處理這些功能的UserAuthentication模型的一部分。或者,也許我們需要一個UserPageState模型來告訴我們用戶是否應該在登錄頁面,購物車頁面或產品詳細信息頁面上?

您認爲最適合這種情況的MVC設計是什麼?

+0

謝謝!根據您給我的反饋,我添加了一些示例代碼http://pastebin.com/f203e3d31。 請看看,讓我知道你對設計的看法。基本上,PageModel保存了用戶應該重定向到的頁面的堆棧。這樣,CartModel中的addItem()可以告訴控制器首先登錄,然後返回addItem()。 你覺得呢? – thorie 2009-04-24 17:23:51

回答

0

我將在我的簡單網站中爲每個表格創建一個模型。我可以在我的控制器中使用任意數量的模型。在更復雜的例子中,客戶和購物車沒有分開的地方,我有一個模型,將這些模型與知道兩個表的方法結合在一起。

在視圖中有很多模型,非常纖細的控制器和只有HTML。你的控制器應該有很多從控制器得到結果的「if」語句。你的觀點可以有循環和重複結果的「福斯」,但沒有其他邏輯。沒有任何地方HTML標籤,但在您的意見。

因此,要回答你的問題,你可以有以下型號

  • 用戶[進入用戶表]
  • 車[進入購物車表]
  • 產品表和用戶表]
  • 產品[進入產品表]
  • 訂單[用戶,推車和產品表(作爲基本簡單的例子)]
  • PageState跟蹤你的用戶在你的網站狀態的模型

您有以下控制器

  • 用戶
  • 產品

的控制器可能很長,但每個行動都是一個小的行動,具有特定的工作。我認爲擁有一個擁有10個動作的控制器是可以的,只要這些動作很好並且自己縮短。

這些操作調用的模型可能相當長,並且通常會考慮業務邏輯。我也使用助手類來做非業務邏輯的事情,但仍然至關重要。像安全和驗證一樣思考。

和一個整體意見。購物車的視圖,登錄框,產品摘要,產品詳細信息,結帳的每個階段,收據,HTML格式電子郵件收據的視圖,類別列表,菜單,頁腳的視圖。很多很多的意見。

你會希望有一些ApplicationClass可以讓你所有的控制器都繼承,所以你可以反覆做一些事情。

你提到過php,所以你有構成你的模板的意見,但是如果你做了ASP,你會有一個能夠完成局部視圖的主頁面。我不確切知道你在Ruby或Python中做了什麼,但它是相似的。

3

您的模型本質上是業務對象。您將擁有ShoppingCarts,用戶和物品(在大多數情況下,每個客戶可能只有一個購物車,但是誰說?)。你將擁有控制器來驅動你的流程 -/cart/add/207366的控制器方法將檢查用戶是否被授權,如果沒有,則將它們傳遞給控制器​​以進行/登錄。登錄控制器應該足夠聰明,可以將正確的信息傳遞迴控制器/ cart/add/207366,然後應該將該項目添加到購物車。

控制器會調用Cart.AddItem(),但業務邏輯包含在購物車模型中 - 它可能會查找物品的價格,基於用戶的首選客戶折扣等。不知道或關心這一點。控制器需要知道用戶是否已登錄(如果這對應用程序很重要),因爲這會影響他們的工作(確定要呈現的視圖)。他們不需要知道客戶是首選的,還是信用保留的,或任何其他條件對業務邏輯而言都很重要。這一切都是由模型處理的。

0

我認爲你擔心繁忙的管制員不應該是一個擔心:這是他們的目的。具有添加動作的購物車控制器將依靠用戶控制器或身份驗證助手來查看用戶是否已登錄。上述兩個回覆很好地捕捉到了這一點。

此外,我不會創建另一個頁面模型,而只是使用會話變量或表中的其他字段。另一種模式實際上只會使事情複雜化,而實際上它並不代表你需要自我包容的實體。您什麼時候看到需要訪問一堆頁面?它實際上只是用戶來自登錄表單的url字符串,您可以使用會話變量以更少的代碼和內存密集型方式跟蹤登錄表單。只需要addItem()檢查它是否已經登錄,如果沒有重定向到登錄頁面並存儲當前請求。然後,一旦登錄,檢查是否設置了重定向變量,如果是這樣,去重置它。我不認爲需要比這更復雜的任何事情。

另外,它看起來像你的pastebin代碼是CakePHP。好的選擇。如果可以,請利用烘焙控制檯和腳手架代碼生成。它爲你做了這麼多的工作,併爲你留下好的東西。