2009-04-24 42 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。好的选择。如果可以,请利用烘焙控制台和脚手架代码生成。它为你做了这么多的工作,并为你留下好的东西。