django:胖模型和瘦控制器? [英] django: Fat models and skinny controllers?

查看:140
本文介绍了django:胖模型和瘦控制器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个通用的体系结构问题.我在许多地方读到,在MVC框架中,(1)模型应该很胖,而控制器应该很瘦.但是我也读到(2)细节取决于您正在开发的框架.那么,如果您正在使用django开发,该怎么办?

我对django的经验是,很多逻辑最终都被放到了视图和表单中.不是业务逻辑",而是处理请求,会话等的细节.就代码行而言,这些细节通常超过处理模型对象的业务逻辑.我是在做错什么,还是django是这样工作的?

解决方案

MVC不是通用解决方案,大多数情况下,它做错了并且不能兑现承诺:实际上,修改模型需要在控制器中进行修改同样,因为做错了.如果您真的想在Model与Controller之间建立松散的耦合,那么-人们通常会忽略它-您必须使用

我要感谢Django没有做错MVC,这与99%的PHP MVC实现不同.

另一方面,Django是唯一允许在应用程序之间适当隔离的框架.每个应用程序可以具有:

  • 模型
  • 观看次数
  • 模板
  • 网址
  • 静态文件
  • 测试
  • 表格
  • 可选插件(管理员,用于ajax选择的过滤器,django-authority的权限,django-notifications的通知等)

因此,即使将模型/视图/模板捆绑在一起,您的项目也可以相应地划分为小型(也称为:易于维护)和松散耦合的应用程序.只有与相关的模型/视图/模板/材料被捆绑在一起.在Django中,不需要具有较大的胖视图和url脚本的胖模型脚本.例如,您不希望像Article和FootballMatch这样的两个模型类一起生活,而是想要制作一个可以独立生活的"articles"/"blog"应用程序和"sport"应用程序.当然,有时必须将它们捆绑在一起,在这种情况下,它在项目级别的90%的情况下是可行的(如果您碰巧需要捆绑模型或模板标签,则可以制作另一个应用程序,"blog_sport").

例如,在Model类中定义get_absolute_url()方法是一种超常规的做法.是的,您的模型类在理论上只必须包含业务逻辑,现在与您的url定义相关联.实际上这有多糟糕?好吧,实际上它很出色,因为添加此方法需要两秒钟,然后您可以在使用模型的任何地方使用它:在视图或模板中使用它.另外,其他应用程序(即django.contrib.admin)也将使用它.

Django光辉的另一个稍微复杂一点的示例是,查询是惰性计算的.这意味着,您的视图函数/类将定义一个查询,例如blog_list = Blog.objects.all(),但如果该查询实际上是在模板中执行的,则该查询将在{{blog_list%}中的{%for blog_list}}中调用.因此,在这种情况下,如果在呈现模板之前发生了某些故障,则模板中会发生业务逻辑:您保存了一个查询.但这还不是全部,如果您的模板仅显示一个计数{{blog_list.count}},那么将根本不会产生 select 查询 ,而只会显示一个count查询被执行. 一般视图"决定了需要什么业务逻辑.这与MVC的承诺相去甚远,但说实话:那有多实际?

我的观点是,您可以错误地应用理论,正确地做理论(这将您的选择减少到喜欢5种 web 框架(包括所有语言)),或者只是简单而优雅地讲到这一点.务实的方式立即完成Zen方式:这是Django的选择.

This is a general architecture question. I read in many places that in an MVC framework, (1) models ought to be fat, and controllers ought to be skinny. But I also read that (2) the details depend on the framework you're developing in. So, what if you're developing in django?

My experience with django is that a lot of the logic ends up getting put into views and forms. Not the "business logic," but the details of handling requests, sessions, etc. In terms of lines of code, these details often outweigh the business logic of manipulating model objects. Am I doing something wrong, or is this how django works?

解决方案

MVC is not a universal solution and most of the time it's done wrong and can't keep its promises: in practice modifying a model will require modifications in the controller as well, because it's done wrong. If you really want loose coupling between Model and Controller then - and people usually ignore that - you have to use a service pattern (open as image). Which almost nobody actually does.

Instead of blindly adhering to the MVC fuss/pseudo-pattern in the PHP world, Django takes a pragmatic approach. Because in the common reality of software development, the developer programs things for the user to see. Then the user (your boss, client, customers ...) will "see" your work, and eventually give his opinion about how he wants to "see" it in the end. By using Django, the developer can take a more "view oriented" development pattern and guess what: it makes deadlines easier to respect and users more satisfied. If you think about it, it has its "nosql-ish" idea that the view (general view, not django view) should be the boss of what's going on behind the scenes.

I'd like to thank Django for not doing MVC wrong, unlike 99% of the PHP MVC implementations out there.

On the other hand, Django is the only framework that allows proper isolation between applications. Each application can have:

  • models
  • views
  • templates
  • urls
  • static files
  • tests
  • forms
  • optional addons (admins, filters for ajax-selects, permissions for django-authority, notifications for django-notifications, etc, etc)

So even if your models/views/templates will be tied, your project can be relevantly divided in small (also reads: easy to maintain) and loosely coupled applications. Only related models/views/templates/stuff are tied together. A big fat models script with a big fat views and urls script is not what you want in Django. For example, you don't want two model classes like Article and FootballMatch to live together, you want to make an "articles"/"blog" app and a "sport" app which can live independently. Of course sometimes they must be tied, in that case it's doable at the project level in 90% of the cases (you'd make another app, "blog_sport" if you happened to need to tie in models or templatetags).

For example, it's a super common practice to define a get_absolute_url() method in the Model class. Yes, your model class which in theory has to contain only business logic, is now tied with your urls definition. How bad is this in practice ?!! Well actually it's brilliant because it takes two seconds to add this method and you can then use it anywhere you use a model: be it in views or templates. Also, other applications (ie. django.contrib.admin) will use it.

Another slightly more complicated example of Django brilliance is that queries are lazily evaluated. Which means, your view function/class will define a query like blog_list = Blog.objects.all(), but the query will actually be executed in the template if it calls like {% for blog in blog_list %}. So business logic happens in the template in that case, and if something fails before the rendering of the template: you saved a query. But that's not all, if your template just displays a count {{ blog_list.count }}, the select query will not be spawned at all and just a count query will be executed. The "general view" decides what business logic is needed. That's far from the promises of MVC but be honest: how practical is that ?

My point is that you can apply theory the wrong way, do it right (which reduces your choice to like 5 web frameworks all languages included), or just get to the point in an elegant and pragmatic way to get your job done the Zen way in no time: that's Django's choice.

这篇关于django:胖模型和瘦控制器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆