Tim*_*imo 28 model-view-controller design-patterns
昨天我与我们的一位开发人员就MVC进行了一些讨论,更准确地说是模型组件在MVC中的作用.
在我看来,模型应该只包含属性而几乎没有功能,因此模型类中的方法尽可能少.
我的同事虽然认为模型可以而且应该具有更多功能并提供更多功能.
这是我们争论的一个例子.
例1
假设我们想创建一个博客.博客有文章和标签.每篇文章可以有多个标签,每个标签可以属于多个文章.所以我们在这里有关系.
在伪代码中它可能看起来像这样:
class Article{
public int id;
public String title;
public String content;
public Tag[] tags;
// Constructor
public void Article(id, title, content, tags){
this.id = id;
this.title = title;
this.content = content;
this.tags = tags;
}
}
class Tag{
public int id;
public String name;
// Constructor
public Tag(id, name){
this.id = id;
this.name = name;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,假设我们正在松散耦合这里意味着我们可能会发生一个没有标签的文章实例,所以我们将使用Ajax调用(对于我们的后端,它有一个包含所有信息的数据库)获取属于我们文章的标签.
这是棘手的部分.我相信通过Ajax + JSON获取后端数据应该是控制器的工作,使用专用类,使用解析器处理ajax请求:
class MyController{
private void whatever(articleID){
Article article = (Article) ContentParser.get(articleID, ContentType.ARTICLE);
doSomethingWith(article);
}
}
public abstract class ContentParser{
public static Object get(int id, ContentType type){
String json = AjaxUtil.getContent(id, type.toString()); // Asks the backend to get the article via JSON
Article article = json2Article(json);
// Just in case
Tag[] tags = article.tags;
if (tags == null || tags.length <= 0){
json = AjaxUtil.getContent(article.id, ContentType.TAGS); // Gets all tags for this article from backend via ajax
tags = json2Tags(json);
article.tags = tags;
}
return article;
}
// Does funky magic and parses the JSON string. Then creates a new instance of Article
public static Article json2Article(String json){
/*
...
*/
return new Article(id, title, content, tags);
}
// Does funky magic and parses the JSON string. Then creates a new instance of Tag
public static Tag[] json2Tags(String json){
/*
...
*/
return tags;
}
}
Run Code Online (Sandbox Code Playgroud)
例2
我的同事认为,这打破了MVC的想法,他建议模型应该注意这个:
class Blog{
public int id;
public String title;
public Article[] articles;
// Constructor
public Blog(id, title, articles){
this.id = id;
this.title = title;
this.articles = articles;
}
public void getArticles(){
if (articles == null || articles.length <= 0){
String json = AjaxUtil.getContent(id, ContentType.ARTICLE); // Gets all articles for this blog from backend via ajax
articles = json2Articles(json);
}
return articles;
}
private Article[] json2Articles(String json){
/*
...
*/
return articles;
}
}
class Article{
public int id;
public String title;
public String content;
public Tag[] tags;
// Constructor
public Article(id, title, content, tags){
this.title = title;
this.content = content;
this.tags = tags;
}
public Tag[] getTags(){
if (tags == null || tags.length <= 0){
String json = AjaxUtil.getContent(id, ContentType.TAGS); // Gets all tags for this article from backend via ajax
tags = json2Tags;
}
return tags;
}
// Does funky magic and parses the JSON string. Then creates a new instance of Tag
private Tag[] json2Tags(String json){
/*
...
*/
return tags;
}
}
Run Code Online (Sandbox Code Playgroud)
在模型之外你会做:blog.getArticles();或者article.getTags();在不打扰ajax调用的情况下获取标签.
然而,尽管这可能很方便,但我相信这种方法会破坏MVC,因为在一天结束时,所有模型都会充满各种各样的方法,控制器和助手类几乎什么都不做.
在我对MVC的理解中,模型应该只包含属性和内部最少的"辅助方法".例如,模型"Article"可以提供方法getNumOfTags(),但它不应该自己进行任何Ajax调用.
那么,哪种方法是正确的?
Dan*_*ady 27
一般来说,我也试图在逻辑方面保持控制器的简单性.如果需要业务逻辑,它将进入"服务层"类来处理它.这也节省了重复任何代码/逻辑,如果要改变业务逻辑,最终会使整个项目更易于维护.我只是将模型保持为实体对象.
我认为上面的答案很好地总结了它,很容易根据设计模式对项目进行过度设计:随身携带任何适用于您的工作并且最易于维护/高效.
正确?无论是.他们都编译,不是吗?
方便的技巧很好,为什么不使用它们你可以吗?话虽这么说,正如你所指出的,如果你把各种逻辑放在其中,你可能会得到臃肿的模型.同样地,当你在每个动作中执行大量操作时,你可以得到臃肿的控制器.有两种方法可以抽象出任何元素,如果这也是必要的话.
在一天结束时,所有设计模式都是指导方针.你不应该盲目地遵循任何规则,只因为别人说了.做什么对你有用,你认为提供干净,可扩展的代码,并达到你认为制作好代码的任何指标.
总而言之,对于真正的理想主义MVC,我会说模型不应该有任何外部动作,它们只是数据表示,仅此而已.但随意不同意:-)
您对模块的建议(内部没有任何业务逻辑)听起来更像是在谈论Value Objects.你大学的建议听起来更像是Domain Objects.
在我看来,将要使用的概念取决于所使用的框架(这是实践观点,更具哲学性的观点).如果使用框架,它通常会设置有关如何实现每个组件的规则.例如,我们可以查看不同的MVC框架.在Flex的Cairngorm框架中,我们都有.VO(值对象)主要用于绑定视图,而DO(域对象)保存业务逻辑.如果我们看看ASP.NET的MVC实现,我们有一个模型,它至少包含数据(VO),但也包含一些验证(如果需要).让我们看一下UI MV*框架 - 例如Backbone.js.Backbone的文档说:
模型是任何JavaScript应用程序的核心,包含交互式数据以及围绕它的大部分逻辑:转换,验证,计算属性和访问控制.
如果我们看一下Smalltalk提供的传统MVC,我们会看到:"模型:管理应用程序域的行为和数据",因此我们在其中有一些行为,而不仅仅是普通数据.
让我们想一想,如果模型中没有任何逻辑,我们应该将所有应用程序和业务逻辑放入Controller中.
现在让我们关注一个具体的例子.想象一下,我们有一个图表模型.我们想要找到它中两个节点之间的最短路径.一个好问题是在哪里找到找到最短路径的算法?这是一种商业逻辑,对吧?如果我们看一下MVC(代码重用,DRY等)的主要好处,我们可以看到,如果我们想以最佳方式重用我们的模型,我们应该在其中实现最短路径.最短路径算法通常依赖于图形内部表示(或者至少为了算法的最佳性能),但是这种表示被封装到模型中,遗憾的是我们不能重用矩阵表示的完整最短路径和邻居列表,所以它不是将它放入控制器的好主意.
因此,作为结论,我可以说这取决于您的需求(主要是).传统的MVC目的是在UI中使用(在GoF内部)
模型/视图/控制器(MVC)三元组[首先由Krasner和Pope在1988年描述]用于在Smalltalk-80中构建用户界面.
)
现在我们在不同的领域使用它 - 只有UI,用于Web应用程序等.因此,它不能以纯粹的形式使用它.但无论如何,在我看来,关注点的最佳分离可以通过将业务逻辑隔离到模型中,将应用程序逻辑隔离到Controller中来实现.
| 归档时间: |
|
| 查看次数: |
18639 次 |
| 最近记录: |