【问题标题】:MVC model design / inheritanceMVC模型设计/继承
【发布时间】:2010-09-12 20:35:51
【问题描述】:
请原谅这个模糊的标题,我不知道如何描述它。
如果您有一个通用模型“存档”,您如何根据用户选择的“类型”显示不同的视图/表单?
例如,用户创建一个新的“存档”,然后选择视频、书籍、音频等。从那里他们根据存档类型获得不同的形式。
或者将它们分成不同的模型会更好 - 视频、书籍、音频?
或者模型可以继承(如视频扩展存档)。我想这是基本的 OOP / 类,但不知道如何在这里应用。
欢迎来自任何 MVC 框架的示例!
【问题讨论】:
标签:
model-view-controller
oop
class
inheritance
model
【解决方案1】:
似乎您不想让类型从存档继承。
“总是倾向于封装/包含而不是继承”。
为什么不创建一个名为 Archive 的类并给它一个 type 属性。该类型可以使用继承来专门用于音频、视频等。
您似乎会根据其他一些标准专门化存档。 “FileSystemArchivce”、“XMLArchive”、“SQLArchive”和类型不会改变。但是我的敏捷主义者说,一开始这可能不是必需的,你以后可以随时重构设计......
就控制器而言,通过在视图中封装每种类型的表示差异,您可能会获得最大的收益。所以只有视图会根据类型而变化。每个类型的语义和规则可能都相同,您不需要为每种类型设置单独的控制器。每种类型的视图都不同,因为它具有不同的属性。
【解决方案2】:
在任何 MVC 框架中实际显示不同的视图应该很容易。例如,在 Microsoft ASP.NET MVC 中,您不会只从控制器返回视图,如下所示:
return View();
但实际上会将视图的名称作为参数声明:
return View("VideoArchive");
然后将显示来自 Views/Archive/VideoArchive.aspx 的视图
【解决方案3】:
您的模型 Video、Book 和 Audio 可以从 Archive 继承。
每个模型都会有一个控制器。
http://yourserver/Books/Edit/11
在创建相应模型之前,您必须让用户选择他们想要的存档类型。
编辑(回应评论)
在 ASP.NET MVC 中,您的模型将是一个类。
public class Video : Archive
{
public int Id {get;set}
public string Name {get;set;}
...
}
您还将拥有一个控制器
public class VideoController : Controller
{
public object Edit(int id)
{
Video myVideo = GetVideo(id);
return View("Edit", myVideo);
}
...
}
您将在 Views 目录中有一个视图,例如,包含该页面的页面
public class Edit : View<Video>
{
...
}
因此,如果您的 URL 是
,则可以调用它
http://localhost/Video/Edit/11
这一切都是凭记忆完成的,因此可能会有一些错误,但带回家的信息是您在模型中指定了继承。模型只是一个类。在您的情况下,您想从存档继承。完成后,模型将正常传递。
【解决方案4】:
Single Responsibility Principle (PDF) 声明:
改变课程的理由不应该不止一个。
您的 Archive 类通过处理多种不同类型的档案违反了这一原则。例如,如果您需要更新视频存档,那么您也在修改处理书籍和音频存档的类。
处理此问题的适当方法是为每种不同类型的存档创建单独的类。这些类型应该实现一个公共接口(或继承一个公共基类),以便它们可以被只关心档案而不是特定档案类型的代码互换(多态)处理。
一旦你有了类层次结构,你只需要一个控制器和每个模型类的视图。
对于加分点,单一职责原则甚至可以证明使用工厂方法或抽象工厂来创建模型、视图和控制器对象(而不是内联新建它们)是合理的。毕竟,创建对象和使用该对象是不同的职责,可能出于不同的原因需要对其进行更改。