如果你在这里应用一些 DDD 逻辑,与 MVC 中的“M”互补,UI 的状态(注册进度)属于应用层,它可以直接与域和基础设施层对话(四层:UI 、应用程序、领域和基础设施)。 DDD的概念让你先“思考”如何在代码中解决方案。让我们一步一步来...
这是进度条
您要在此处保持的状态是注册的步骤或进度。所以,我的第一步是记录进度或“步骤”。例如,第 1 步:获取用户名/密码,第 2 步:获取电子邮件。在这种情况下,我将应用逻辑将模型“移动”到下一步。最有可能使用 RegistrationService (RegistrationService.NextStep()) 上的 NextStep() 方法。
啊,不过属于App层
我将在应用层创建一个名为 RegistrationService 的服务。我会在这里放置一个名为 NextStep() 的方法。但请记住,域不会在这里保存模型的状态。在这种情况下,您希望将状态集中在应用程序层。所以在这种情况下,NextStep() 不会作用于模型对象(因为它不是域责任的一部分),而是作用于 UI。因此,您需要一些东西来保留注册过程的状态。
远离领域模型,ViewModel 怎么样?
所以现在我们知道我们必须在 UI 中保留某些东西的状态。 MVC 允许一个称为 ViewModels 的概念(在 ASP.NET MVC 中,不确定 RoR 叫什么)。 ViewModel 表示将由视图和/或部分视图显示的模型。
ViewModel 将是保存此对象状态的绝佳场所。让我们称之为 RegistrationProgressViewModel() 并在其上粘贴 NextStep() 方法。当然,这意味着应用层必须保留 RegistrationProgressViewModel 的位置,而应用层将根据 NextStep 操作更改其内部结构。如果它很复杂,您可能需要在应用层创建一个 RegistrationProgressService() 并将 NextStep() 放在其中以抽象您的逻辑。
如何传递 ViewModel?
最后一点是如何跟踪该对象的状态。由于 Web 应用程序是无状态的,因此您必须通过应用程序以外的其他方式保留控制权。在这种情况下,我将恢复为:1)将 ViewModel 序列化到客户端并让客户端来回传递它,或者 2)保留 ViewModel 的服务器端副本,并来回传递某种类型的标识符到客户并返回。
这是一个值得思考的好例子,因为我自己还没有这样做过。对于#2,保存此 ViewModel 状态的最安全和最保险的方法是将其持久化到基础设施层(是的,APP 层可以直接与基础设施层对话)。这对我来说似乎有很多工作,因为有些东西可能会消失,我的数据库中会有部分注册。
但是,#2 会将用户的私人信息(用户名、密码、电子邮件、CC # 等)全部保存在服务器端,而不是来回传递。
终于有答案了!
所以,经过它,我们想出了:
- 在应用层创建 RegistrationProgressViewModel()。
- 在应用层中使用 NextStep(ViewModel vm) 方法创建一个 RegistrationProgressService()。
- 执行 NextStep() 时,通过 Infrastructure 层将 ViewModel 持久化到数据库中。
这样,您无需跟踪视图或 UI 本身上的“step?id=2”,因为随着您的前进,ViewModel 会不断更新和更新(经过身份验证、验证、持久化到数据库)。
因此,您的下一个问题是在 UI 中“前进”。这可以通过 1 个控制器轻松完成,使用步骤或命名步骤。
抱歉,我在下面编写 C# 代码,因为那是我的语言。
public class RegistrationController : Controller
{
// http://domain.com/register
public ActionResult Index()
{
return View(new RegistrationProgressViewModel);
}
// http://domain.com/register
// And this posts back to itself. Note the setting
// of "CurrentStep" property on the model below.
//
public ActionResult Index(
RegistrationProgressViewModel model)
{
// The logic in NextStep() here checks the
// business rules around the ViewModel, verifies its
// authenticity, if valid it increases the
// ViewModel's "CurrentStep", and finally persists
// the viewmodel to the DB through the Infrastructure
// layer.
//
RegistrationProgressService.NextStep(model);
switch (model.CurrentStep)
{
case 2:
// wire up the View for Step2 here.
...
return View(model);
case 3:
// wire up the View for Step3 here.
...
return View(model);
case 4:
// wire up the View for Step4 here.
...
return View(model);
default:
// return to first page
...
return View(model);
}
}
}
您会注意到,这将验证模型内部状态的“业务逻辑”抽象到了 RegistrationProcessService.NextStep() 方法中。
很好的锻炼。 :)
最后,您的“RESTful”网址是一个漂亮而干净的 POST 到:/register,它需要一个具有特定属性的 ViewModel。如果 ViewModel 无效,/register 不会进入下一步。