基于Ruby On Rails开发高品质Web应用

开发 后端
文章将逐一探讨多个影响Web使用质量的要素,同时希望读者们可以从中领悟到Rails为创建高质量的Web应用程序的特性,和Rails的各种设计给我们的启示,以及Rails 3的改进所代表的意义和趋向。

越来越多的企业开始挑选Ruby On Rails作为Web开发的框架,Rails在以前还是一些“轻量级公司”的选择。挑选Rails的原由,是由于它高速构建的才干,是由于它是Web开发的DSL。那么挑选了Rails就代表了“高效开发”呢?其中有哪些因素影响着Web应用的质量呢?

51CTO推荐专题: Ruby On Rails开发教程

 

MVC

我们都知晓Rails是一个MVC架构方式的Web框架,MVC各局部的职责也很清楚。但疑问在于我们能不能真的遵照了MVC架构方式做到了各局部职责的明白别离?能不能遵照了单一职责的准绳?

在大非少数代码内部,这种混沌不清的形态存在于model和controller之间:controller承当了太多本应由model承当的职责。其中比拟典型的例子是内嵌(多)对象表单。比如,Album和Photo之间是一对多的联系,我们要创立一个含有多个photo的album。在 Rails 2.3之前,我们能够会写出类似的代码:

  1. AlbumsController   
  2.  def create   
  3. album = Album.new params[:album]   
  4. album.photos << Photo.new params[:album][:photo]   
  5. ...  

假设是一个触及更多品种型对象的表单,这里的代码能够会愈加庞杂。但在AlbumsController内部,我们真实想关心的只是Album的创立,而不是Photo或其它关联对象的创立。并且从Album的角度看,创立流程中photo跟其它attributes没有区别,应该得到一致地处置。Rails 2.3之后,我们就能够很容易地抵达这个目标。在Album内部做这样的声明:

  1. class Album < ActiveRecord::Base   
  2.  ...   
  3.  accepts_nested_attributes_for :photos   
  4. end  

然后,controller中的代码就能够被简化为:

  1. AlbumsController   
  2.  def create   
  3. album = Album.new params[:album]   
  4. ...  

从这个例子中能够看到Rails在推进MVC三局部之间职责明白上所做的全力和提高。许多人能够会说,我们的代码没有这样的疑问。但MVC三局部之间职责开端模糊,往往出如今业务逻辑变得庞杂之后。我们应该经常审视我们的代码,做到真实的职责单一。

#p#

REST

现今的互联网使用曾经很难是一个独立的个体,互联网使用之间的交互越来越多。所以,树立REST架构作风的互联网使用变得越来越首要。Rails的 router很好地支持了REST作风的外部接口设计。Rails 3所做的一个很大改进就是router的改进,以强调REST作风的接口设计。

REST也让我们以资源的角度看待使用中的数据,我们的代码设计因而也发生了一些改动。当须要添加一个invoice的PDF文件下载功用的时分,我们普通会向InvoicesController添加这么一段代码:

  1. InvoicesController   
  2.  def download_pdf   
  3. ...   
  4. send_data(generate_pdf(@invoice), :type => 'application/pdf')   
  5.  end  

这段代码至少存在两个疑问:第一个疑问,就是我们先面所述的职责明白疑问。PDF的generate属于Invoice而不是controller 的职责,所以我们应该把PDF生成的逻辑移到Invoice内部。第二个疑问,则是语义能不能恰当的疑问 。假设我们以资源的角度看待Invoice的话,PDF跟Html或许XML一样,只是Invoice的另一种表现方式而已。而表现一个资源,在show action中处置最为恰当。重写之后,代码如下:

  1. def show   
  2.  ...   
  3.  respond_to do format   
  4. format.html   
  5. format.pdf { render :pdf => @invoice.pdf }   
  6.  end   
  7. end  

重写之后的代码不只更契合REST的作风,并且愈加简约优美。

JavaScript

随着RIA的普及以及时代的即未来临,JavaScript的江湖位置正在与日俱增。从Google的一些使用就能够看出业界关于 JavaScript态度的一些改动。比如Gmail,它提供了在无JavaScript支持环境下的普通版本和有JavaScript支持的全功用版本 ──这是一种渐进式加强的设计理念。但随后几年推出的Google Doc,曾经完全丢弃了对无JavaScript环境的支持。从这些改动能够看出,JavaScript曾经是Web使用的“必需品”。甚至有人把 JavaScript称为当今最首要的编程言语,从某种意义上这种说法也不过火。

很久以来,我们不断以“脚本”的态度看待JavaScript。顺序员对JavaScript的注重水平很不够,业界对顺序员的JavaScript才干要求也不高。如今,必需做出这种态度的转变。Rails 3所做的很大一个改进就是:Unobtrusive JavaScript(非侵入式的JavaScript),以完成对HTML和JavaScript代码的别离。比如:

  1. <%= link_to "delete", album_path(@album), :method => :delete, :confirm => "Are you sure?"%>
  2.   

在Rails 3之前,它生成的代码应为(代码举行了省略):

  1. <a href="/albums/1" onclick="if (confirm('Are you sure?')) {   
  2.     var f = document.createElement('form');   
  3.     f.style.display = 'none'; this.parentNode.appendChild(f);   
  4.     f.method = 'POST'; ...  

能够看到,生成的HTML内嵌了大量的JavaScript代码,这是一种不好的做法。Rails 3所做的其中一个改动,就是别离HTML和JavaScript代码,生成的HTML中内嵌的JavaScript代码消逝了:

  1. <a href="/albums/1" data-confirm="Are you sure?" data-method="delete" rel="nofollow">deletea>
  2.   

那么JavaScript代码到哪里去了?它们都被放到了一个叫做Rails.js的文件中。跟服务端MVC要求职责别离一样,这个准绳也应该表如今客户端的代码上。HTML、Css和JavaScript应该职责明白地各自傲责数据、显示和行为。同时,这种别离也对顺序员的JavaScript才干提出了更高的要求。

#p#

功用

从一个央求(Request)的数据传输角度看,数据普通会阅历从数据库到服务器,结尾到客户端这么一个流程(能够尚有其它层次)。数据离客户端越近,照应速度必须越快。因而,缓存是提高功用的一大利器。

而客户端缓存是离用户近来的地点。关于客户端缓存的一条准绳是:不要缓存静态HTML页面,但长久缓存一切其它文件类型。Rails对静态文件的处置很好地表现了这条准绳。比如下面这段代码:

  1. stylesheet_link_tag("application")
  2.   

它生成的HTML是:

  1. <link href="/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css"/>
  2.   

其中application.css?1232285206的后缀是这个文件的时间戳。那么客户端就能够不担忧肠长久缓存这个静态文静。由于文件一旦更新,客户端就会以为这是一个新的央求,即会去获取最新的文件。

Rails还在其它许多方面提供了简便的办法使功用优化变得容易,比如服务端缓存机制等。但大非少数时分,功用疑问源自于我们自己的完成或许设计疑问。比如关于Active Record Query Interface的的滥用,非少数时分功用疑问都能够议决齐备数据库查询来得到很大的改进。关于数据库查询,我们应该经常重视多个疑问,比如:获取的数据后果集中能不能有大量无用数据,数据库查询次数能不能能够降低等等。

用户体验

用户体验是Web使用十分首要的元素,Rails作为Web开发的DSL在这方面也有许多重视。 在Web使用中我们经常遇到的一个疑问是:submit button(提交按钮)被屡次点击。假设没有被恰当处置,就会惹起表单的屡次提交。用Rails的form helper办法能够很容易地防止这个疑问:

  1. submit_tag "Submit", :disable_with => "Submitting..."
  2.   

代码中的:disable_with选项的作用是:在button被点击之后把它disable掉,并且把button的文字交流成“Submitting”。一个容易的选项带来了显而易见的益处:不只防止了屡次点击的疑问,并且显式地通知了用户表单正在被提交当中。

Rails提供了许多便捷的办法,让提高用户体验变得十分容易。作为顺序员,我们也应该对用户体验有更多重视,比如如何设计更好的交互来防止AJAX所带来的种种用户体验疑问等等。

安全

Web使用面对着许多安全隐患,比如Session定置(Session Fixation)、跨站央求伪造(CSRF)和日志信息泄露(Logging)疑问。在Rails中我们能够用容易到只需一行代码的方式来防止这些安全疑问。下面是各安全隐患以及对应战略。

Session定置

攻击者议决某种方式强迫用户运用他所掌握的Session ID,在用户登录之后攻击者即可运用此Session ID窃取用户的信息。处置方案:

reset_session 

在登录逻辑中添加此段代码,以在登录之前重置session,这样便能够防止攻击者议决Session Fixation攻击来获得用户信息。

跨站央求伪造

CSRF是指在页面中注入一些歹意代码或许链接──指向用户运用的其它站点,比如站点A。当用户访问被净化的页面时,假设刚好站点A仍处于有效认证期,则用户在站点A的数据就会被侵犯。处置方案:

  1. protect_from_forgery :secret => "123456789012345678901234567890..."
  2.   

此代码会在非get央求中添加一个security token,假设token不一致,则央求将失败。这种方式能够有效防止CSRF,当然前提是我们正确地运用了HTTP method。

日志信息泄露

默许情况下,Rails会把一切的央求信息都记载在日志文件中。那么攻击者就能够议决窃取日志文件,以得到一些秘密信息,比如登录密码、信誉卡信息等等。处置方案:

  1. filter_parameter_logging :passWord 
  2.  

这行代码就能够过滤那些不期盼被日志文件记载的信息,比如password等,从而防止议决日志来泄露敏感信息。

Web使用还面对着许多其它安全疑问,比如SQL注入,XSS等等。我们应该更多重视Web使用所面对的安全疑问,并尽能够防止。何况,在Rails中要防止大非少数疑问,办法都很容易。

业务模型

结尾一个疑问虽然与Rails甚至技术的联系并不大,但是却联系到一个Web使用质量的最首要疑问:创立的Web使用能不能契合业务模型。我们以前在一个电子商务使用的开发流程中遇到这么一个疑问:整个购置流程的结尾一步是破费页面,用于完成破费并生成收据的PDF文件。产品交付之后,客户开端埋怨破费页面的功用疑问:照应时间超越了容忍度。于是我们试图改进破费页面的功用,但由于破费页面触及的逻辑和业务真实过多,功用提高很难处。

但当我们重新审视破费页面的业务逻辑时,我们发觉这个页面原本包含了两局部功用:破费和PDF文件的生成。而从业务角度看,PDF文件的生成不属于破费流程,而是破费完成之后的逻辑。并且,并不是一切的用户都须要生成PDF,强迫在破费的同时生成PDF是一种资源的糜费。所以,我们把破费页面举行了拆分:把生成PDF文件的功用移到了破费成功页面,并且只需在客户点击相应链接之后才会生成PDF。容易的改动之后,不只功用疑问得到了处置,并且使用也愈加契合真实的业务流程。

当我们遇到疑问或许举步维艰之时,停下来思索一下:我们对业务的明白能不能出现了疑问,我们的设计能不能出现了疑问。许多时分我们都能够在这里找到答案。重新思索业务逻辑或许重新设计之后,完成能够会容易许多,甚至也许疑问本身都曾经不复存在了。

【编辑推荐】

  1. 跑起来吧 Ruby on Rails开发初体验
  2. Ruby on Rails性能优化七剑
  3. Ruby on Rails应用技巧全解析
  4. 总结各种Ruby on Rails命令
  5. Ruby on Rails验证输入技术讲解
责任编辑:王晓东 来源: 清风网络
相关推荐

2015-10-31 18:41:58

MDSA线下公开课

2009-05-18 09:12:59

JavaRuby on RaiMVC

2016-01-04 11:04:17

Web开发Ruby

2009-12-17 17:37:42

Ruby on Rai

2009-08-27 10:21:22

Ruby on Rai

2017-11-29 14:48:01

Node.JSRails语言

2009-07-20 09:12:54

Ruby on Rai

2009-12-14 15:37:35

Ruby on Rai

2010-07-27 09:06:11

Ruby on Rai

2014-11-11 15:30:46

DockerRails集群Ruby

2009-08-06 09:13:36

Ruby on Rai

2009-06-11 14:45:50

Linux免费CAD

2009-12-17 15:02:32

Ruby on Rai

2015-01-17 13:28:59

线下公开课51CTO沙龙MDSA

2011-08-05 08:57:14

Ruby

2010-07-13 09:31:08

RubyRuby on Rai

2009-12-18 11:14:26

Ruby On Rai

2009-04-23 09:39:31

Ruby on Rai开发网站

2009-12-16 16:37:59

Ruby on Rai

2015-10-10 11:00:05

RubyRails性能
点赞
收藏

51CTO技术栈公众号