`
mike.gao
  • 浏览: 48283 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

瘦controller,富model

阅读更多
----先看这么一段rhtml代码:渲染模板中加入了这么多的逻辑,看起来不伦不类,这么做行是行,但是缺点很多,新手一般有这个毛病。那么这样做,首先是可读性很差,因为在渲染代码中最好都是贴近HTML代码,而这堆代码里把C的内容也加进来了。
<% people = Person.find(
            :conditions => ["added_at > ? and deleted = ?", Time.now.utc, false],
            :order => "last_name, first_name") %>
<% people.reject { |p| p.address.nil? }.each do |person| %>
    <div id="person-<%= person.new_record? ? "new" : person.id %>">
        <span class="name">
            <%= person.last_name %>, <%= person.first_name %>
        </span>
        <span class="age">
            <%= (Date.today - person.birthdate) / 365 %>
        </span>
    </div>
<% end %>

再看看controller和model里的东西:
# app/controllers/people_controller.rb
class PeopleController < ActionController::Base
end

# app/models/person.rb
class Person < ActiveRecord::Base
    has_one :address
end

空荡荡的controller,而在model里仅仅有一句关系声明。这么组合成的MVC显得很别扭,似乎就是一层渲染模板。几乎把C与M都忽略了。

无论如何这在MVC框架里是糟糕透顶的现象,MVC经过这么多年的实践考验,它的优点在于“可读性强”“可维护性好”“模块化”“关注点的分离”等等,我想你用MVC框架也就是想实现这些优点哇?那么首先需要改进的是尽可能的将逻辑内容搬到controller中,controller 的作用就是介于view和model之间,起到一个类似中介的作用。下面来看下这样改动之后的代码:
<!-- app/views/people/index.rhtml -->
<% @people.each do |person| %>
    <div id="person-<%= person.new_record? ? "new" : person.id %>">
        <span class="name">
            <%= person.last_name %>, <%= person.first_name %>
        </span>
        <span class="age">
            <%= (Date.today - person.birthdate) / 365 %>
        </span>
    </div>
<% end %>


# app/controllers/people_controller.rb
class PeopleController < ActionController::Base
    def index
        @people = Person.find(
            :conditions => ["added_at > ? and deleted = ?", Time.now.utc, false],
            :order => "last_name, first_name")
        @people = @people.reject { |p| p.address.nil? }
    end
end

这样看起来就好多了,模板中的代码更像是HTML的结构,而且你粗略的看一下controller里的代码就能知道在这个action渲染的模板中会显示什么数据。

还可以更进一步做的事情就是将现在模板代码中关于一部分数据的处理挪到Model中来:
# app/models/person.rb
class Person < ActiveRecord::Base
    # ...

    def name
        "#{last_name}, #{first_name}"
    end

    def age
        (Date.today - person.birthdate) / 365
    end

    def pseudo_id
        new_record? ? "new" : id
    end
end

<!-- app/views/people/index.rhtml -->
<% @people.each do |person| %>
    <div id="person-<%= person.pseudo_id %>">
        <span class="name"><%= person.name %></span>
        <span class="age"><%= person.age %></span>
    </div>
<% end %>

这样通过在model中添加几个虚拟属性,在view里调用,显得很合理,而且模板代码更简洁明了了。

下一步就是将controller里的代码理一理。因为controller只能算是个中介,不应该参与很多的逻辑处理。
# app/models/person.rb
class Person < ActiveRecord::Base
    def self.find_recent
        people = find(
            :conditions => ["added_at > ? and deleted = ?", Time.now.utc, false],
            :order => "last_name, first_name")
        people.reject { |p| p.address.nil? }
    end

    # ...
end

# app/controllers/people_controller.rb
class PeopleController < ActionController::Base
    def index
        @people = Person.find_recent
    end
end

现在看index这个action,扫一眼就知道它要干吗。而且如果find_recent方法在以后需要改变时,可以直接在model里进行修改。

--总结一下,尽量使得controller的actions中的代码和view中的代码更少,在action中要是能只写一行达到效果最好。在view中要尽量使代码贴近html结构。

还有一个不太明显的好处就是,瘦action可以使得 respond_to 结构更突出,可以看出输出的类型是什么。
class PeopleController < ActionController::Base
    def index
        @people = Person.find_recent

        respond_to do |format|
            format.html
            format.xml { render :xml => @people.to_xml(:root => "people") }
            format.rss { render :action => "index.rxml" }
        end
    end
end
分享到:
评论

相关推荐

    JAVA富客户端开发教程源代码

    3. **Model-View-Controller (MVC)架构**:这是一种常见的设计模式,用于组织富客户端应用的结构。模型负责数据处理,视图负责展示,控制器则作为两者之间的桥梁,处理用户交互并更新模型或视图。 4. **网络通信**...

    基于RIA的在线多媒体教学资源网站的设计与实现

    它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller),有助于提高代码的可读性和可维护性。 #### 四、系统分析与设计 ##### 1. 功能需求 根据用户需求,该在线多媒体教学资源网站...

    J2EE 《核心模式》

    1. **客户端层(Client Layer)**:这是用户与应用程序交互的部分,可以是浏览器、瘦客户端或富客户端应用。 2. **Web层(Web Tier)**:包含Web服务器,负责处理HTTP请求,常使用Servlet和JSP技术。Web层也包括...

    WEB技术发展与REST的由来.pdf

    随着Web应用程序复杂性的提升,WebMVC(Model-View-Controller)模式应运而生,如Struts、Spring MVC等框架,它们促进了瘦客户端应用的发展,将业务逻辑移至服务器端。接着,RIA(富互联网应用)时代来临,Ajax技术...

    j2ee.rar_java 学习笔记

    - 客户端层:可以是Web浏览器、瘦客户端或富客户端应用,与服务器进行交互。 - Web层:处理HTTP请求,包括Servlet、JSP(JavaServer Pages)等技术。 - 业务逻辑层:包含EJB(Enterprise JavaBeans)和Java ...

    J2EE教学全程(1) J2EE教学全程(1)

    1. **客户端层**:这是用户与应用交互的界面,可以是Web浏览器、瘦客户端或富客户端应用。J2EE提供了多种技术来支持客户端开发,如JavaFX、Swing等。 2. **Web层**:主要处理HTTP请求,负责展示静态和动态内容。...

    清华大学J2EE—PPT.rar

    客户端可以是基于浏览器的瘦客户端,也可以是富客户端应用。Web层包括Servlet、JSP(JavaServer Pages)和JSF(JavaServer Faces),用于处理HTTP请求。业务逻辑层主要由EJB(Enterprise JavaBeans)组成,提供业务...

    J2EE.rar_J2EE

    1. **客户端层(Client Layer)**:这是用户与应用交互的地方,可以是传统的Web浏览器,也可以是瘦客户端或富客户端应用。 2. **Web层(Web Tier)**:包括Web服务器和Servlets,处理HTTP请求,提供静态内容和动态...

    J2EE开发使用手册

    1. **客户端层**:用户与应用交互的部分,可以是传统的Web浏览器,也可以是瘦客户端或富客户端应用。 2. **Web层**:主要处理HTTP请求,包括Servlet和JSP(Java Server Pages),负责动态网页的生成。 3. **业务逻辑...

    j2ee api文档

    1. 客户端层:用户通过浏览器、瘦客户端或富客户端应用与系统交互。 2. Web 层:负责处理 HTTP 请求,常用技术有 JSP、Servlet 和 JSF。 3. 业务逻辑层:包含 EJB(Enterprise JavaBeans),处理应用的核心业务逻辑...

    struts2 jar包

    Struts2是一个基于MVC(Model-View-Controller)设计模式的Java Web应用程序框架,它极大地简化了在Java EE平台上构建动态Web应用的过程。Struts2的核心是Action类,它负责处理请求,与业务逻辑交互,并将结果返回给...

    原创-REST原理及Opendaylight应用--冀烨

    - **瘦客户端应用阶段**: MVC(Model-View-Controller)模式成为主流,提高了开发效率。 - **RIA(Rich Internet Application,富互联网应用)阶段**: Ajax等技术让网页具备了更丰富的交互性。 - **移动Web应用阶段*...

Global site tag (gtag.js) - Google Analytics