100
Buenas prácticas de desarrollo en Ruby on Rails Sergio Gil Pérez de la Manga

Buenas Prácticas de desarrollo en Ruby on Rails

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Buenas Prácticas de desarrollo en Ruby on Rails

Buenas prácticas de desarrollo en

Ruby on Rails

Sergio Gil Pérez de la Manga

Page 2: Buenas Prácticas de desarrollo en Ruby on Rails

Súper Mega Disclaimer

Todo el contenido de esta charla se basa en opiniones personalísimas del autor, salvo cuando se citen

expresamente las opiniones de otros autores, en cuyo caso se trata de

interpretaciones personalísimas de las mismas

Page 3: Buenas Prácticas de desarrollo en Ruby on Rails

Súper Mega Disclaimer

Lo que tenga un asterisco gordo al lado, es que no me lo he inventado (y está en la lista de referencias)

*

Page 4: Buenas Prácticas de desarrollo en Ruby on Rails

“Best Practice is an idea that asserts that there is a technique, method, or process

that is more e!ective at delivering a particular outcome than any other

technique, method or process”

*

Page 5: Buenas Prácticas de desarrollo en Ruby on Rails
Page 6: Buenas Prácticas de desarrollo en Ruby on Rails
Page 7: Buenas Prácticas de desarrollo en Ruby on Rails

“En el Go todas las piezas son iguales; en el Ajedrez,

son diferentes, y obedecen a reglas de desplazamiento

distintas, lo que complica el aprendizaje de la regla,

pero facilita la tarea del debutante: un cuadro de

juego codificado es de un uso más sencillo que una libertad completa con la

que no se sabe qué hacer”

Pierre Aroutche!,“El Go”

Page 8: Buenas Prácticas de desarrollo en Ruby on Rails

Cosas de las que no voy a hablar (por obvias)

Page 9: Buenas Prácticas de desarrollo en Ruby on Rails
Page 10: Buenas Prácticas de desarrollo en Ruby on Rails
Page 11: Buenas Prácticas de desarrollo en Ruby on Rails
Page 12: Buenas Prácticas de desarrollo en Ruby on Rails
Page 13: Buenas Prácticas de desarrollo en Ruby on Rails
Page 14: Buenas Prácticas de desarrollo en Ruby on Rails

TESTING

Page 15: Buenas Prácticas de desarrollo en Ruby on Rails

Buen Código

Código fácil de testear

Page 16: Buenas Prácticas de desarrollo en Ruby on Rails

Refactorizar sin tests es un deporte

de riesgo

Page 17: Buenas Prácticas de desarrollo en Ruby on Rails

Control de Versiones

Page 18: Buenas Prácticas de desarrollo en Ruby on Rails

Infórmate, participa, interactúa

Page 19: Buenas Prácticas de desarrollo en Ruby on Rails

LEE

Page 20: Buenas Prácticas de desarrollo en Ruby on Rails

LEE

Documentación

Page 21: Buenas Prácticas de desarrollo en Ruby on Rails

LEE

DocumentaciónBlogs

Page 22: Buenas Prácticas de desarrollo en Ruby on Rails

LEE

DocumentaciónBlogs

Listas de correo

Page 23: Buenas Prácticas de desarrollo en Ruby on Rails

ESCRIBE

DocumentaciónBlogs

Listas de correo

Page 24: Buenas Prácticas de desarrollo en Ruby on Rails

Acude a Conferencias

Page 25: Buenas Prácticas de desarrollo en Ruby on Rails

Acude a Conferencias

¡Y habla si te dejan!

Page 26: Buenas Prácticas de desarrollo en Ruby on Rails
Page 27: Buenas Prácticas de desarrollo en Ruby on Rails

Ven a las quedadas

Page 28: Buenas Prácticas de desarrollo en Ruby on Rails

Haz pair programming si puedes

Page 29: Buenas Prácticas de desarrollo en Ruby on Rails

Hablemos de código

Page 30: Buenas Prácticas de desarrollo en Ruby on Rails

Conoce tus herramientas

Page 31: Buenas Prácticas de desarrollo en Ruby on Rails

some_things = []some_other_things.each do |some_other_thing| some_things << some_other_thing.wadusend

Page 32: Buenas Prácticas de desarrollo en Ruby on Rails

some_things = some_other_things.map do |some_other_thing| some_other_thing.wadusend

Page 33: Buenas Prácticas de desarrollo en Ruby on Rails

some_things = some_other_things.map(&:wadus)

Page 34: Buenas Prácticas de desarrollo en Ruby on Rails

DRY pero no tanto

Page 35: Buenas Prácticas de desarrollo en Ruby on Rails

Don’t Repeat Yourself

*

“Every piece of knowledge must have a single, unambiguous, authoritative

representation within a system”

Page 36: Buenas Prácticas de desarrollo en Ruby on Rails

Pero DRY es un medio, no un fin

Page 37: Buenas Prácticas de desarrollo en Ruby on Rails

Pero DRY es un medio, no un finLo único importante es:

Page 38: Buenas Prácticas de desarrollo en Ruby on Rails

Pero DRY es un medio, no un finLo único importante es:

Legibilidad

Page 39: Buenas Prácticas de desarrollo en Ruby on Rails

Pero DRY es un medio, no un finLo único importante es:

LegibilidadMantenibilidad

Page 40: Buenas Prácticas de desarrollo en Ruby on Rails

Pero DRY es un medio, no un finLo único importante es:

LegibilidadMantenibilidad

login: &login adapter: mysql username: username password: password host: mysql.example.com

development: <<: *login database: app_dev

test: <<: *login database: app_test

production: <<: *login database: app_prod

Page 41: Buenas Prácticas de desarrollo en Ruby on Rails

MVC

Page 42: Buenas Prácticas de desarrollo en Ruby on Rails
Page 43: Buenas Prácticas de desarrollo en Ruby on Rails

Skinny Controller, Fat Model

*

Page 44: Buenas Prácticas de desarrollo en Ruby on Rails

Modelo cocinero, controlador camarero

*

Page 45: Buenas Prácticas de desarrollo en Ruby on Rails

class Person < AR::B has_one :addressend

class PeopleController < ACend

<% 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 class="person"> <span class="name"> <%= person.last_name %>, <%= person.first_name %> </span> <span class="age"> <%= (Date.today - person.birthdate) / 365 %> </span> </div><% end %> *

Page 46: Buenas Prácticas de desarrollo en Ruby on Rails

class Person < AR::B has_one :addressend

class PeopleController < AC 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? } endend

<% @people.each do |person| %> <div class="person"> <span class="name"> <%= person.last_name %>, <%= person.first_name %> </span> <span class="age"> <%= (Date.today - person.birthdate) / 365 %> </span> </div><% end %> *

Page 47: Buenas Prácticas de desarrollo en Ruby on Rails

class Person < ActiveRecord::Base has_one :address 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 def name "#{last_name}, #{first_name}" end def age (Date.today - person.birthdate) / 365 endendclass PeopleController < ActionController::Base def index @people = Person.find_recent endend

<% @people.each do |person| %> <div class="person"> <span class="name"><%= person.name %></span> <span class="age"><%= person.age %></span> </div><% end %> *

Page 48: Buenas Prácticas de desarrollo en Ruby on Rails

Hacia el controlador trivial

Page 49: Buenas Prácticas de desarrollo en Ruby on Rails

Hacia el controlador trivial

Plugins como resource_controller

Page 50: Buenas Prácticas de desarrollo en Ruby on Rails

Hacia el controlador trivial

Plugins como resource_controller

class PostsController < ApplicationController resource_controllerend

Page 51: Buenas Prácticas de desarrollo en Ruby on Rails

REST

Page 52: Buenas Prácticas de desarrollo en Ruby on Rails

RESTricción liberadora

Page 53: Buenas Prácticas de desarrollo en Ruby on Rails

Si lo que quieres hacer no encaja en REST

Page 54: Buenas Prácticas de desarrollo en Ruby on Rails

• Puede que pertenezca al 20% de cosas que no encajan

Si lo que quieres hacer no encaja en REST

Page 55: Buenas Prácticas de desarrollo en Ruby on Rails

• Puede que pertenezca al 20% de cosas que no encajan

• Puede que lo estés enfocando mal

Si lo que quieres hacer no encaja en REST

Page 56: Buenas Prácticas de desarrollo en Ruby on Rails

• Puede que pertenezca al 20% de cosas que no encajan

• Puede que lo estés enfocando mal

• Así que dale una vuelta

Si lo que quieres hacer no encaja en REST

Page 57: Buenas Prácticas de desarrollo en Ruby on Rails

Demeter y el Acoplamiento

Page 58: Buenas Prácticas de desarrollo en Ruby on Rails

*

Un método de un objeto sólo debe llamar a:

Page 59: Buenas Prácticas de desarrollo en Ruby on Rails

*

Un método de un objeto sólo debe llamar a:

• Métodos del mismo objeto

Page 60: Buenas Prácticas de desarrollo en Ruby on Rails

*

Un método de un objeto sólo debe llamar a:

• Métodos del mismo objeto

• Métodos de objetos directamente relacionados

Page 61: Buenas Prácticas de desarrollo en Ruby on Rails

comment.article.author.address.city.country.two_letter_code

Page 62: Buenas Prácticas de desarrollo en Ruby on Rails

class User < AR::B # emailend

class Blog < AR::B belongs_to :user has_many :articlesend

class Article < AR::B belongs_to :blogend

article.blog.user.email

Page 63: Buenas Prácticas de desarrollo en Ruby on Rails

class User < AR::B # emailend

class Blog < AR::B belongs_to :user has_many :articles delegate :email, :to => :userend

class Article < AR::B belongs_to :blog delegate :email, :to => :blogend

article.email

Page 64: Buenas Prácticas de desarrollo en Ruby on Rails

El termómetro del test

before(:each) do @country = mock_model(Country, :two_letter_code => 'es') @city = mock_model(City, :country => @country) @address = mock_model(Address, :city => @city) @author = mock_model(User, :address => @address) @article = mock_model(Article, :author => @author) @comment = mock_model(Comment, :article => @article)end

it "should have two_letter_code 'es'" do @comment.article.author.adress.city.country.two_letter_code.should == 'es'end

Page 65: Buenas Prácticas de desarrollo en Ruby on Rails

El termómetro del test

before(:each) do @comment = mock_model(Comment, :author_country_code => 'es')end

it "should have two_letter_code 'es'" do @comment.author_country_code.should == 'es'end

Page 66: Buenas Prácticas de desarrollo en Ruby on Rails

Uso de convenciones

Page 67: Buenas Prácticas de desarrollo en Ruby on Rails

Las de Rails: piénsatelo antes de saltártelas

Page 68: Buenas Prácticas de desarrollo en Ruby on Rails
Page 69: Buenas Prácticas de desarrollo en Ruby on Rails

Crea las tuyas propias

Page 70: Buenas Prácticas de desarrollo en Ruby on Rails

Crea las tuyas propias¡Y cúmplelas!

Page 71: Buenas Prácticas de desarrollo en Ruby on Rails

Refactorización

Page 72: Buenas Prácticas de desarrollo en Ruby on Rails

Refactoriza durante el desarrollo...

*

Page 73: Buenas Prácticas de desarrollo en Ruby on Rails

...y no al final

*

Page 74: Buenas Prácticas de desarrollo en Ruby on Rails

*

Page 75: Buenas Prácticas de desarrollo en Ruby on Rails

1. No refactorices y añadas funcionalidad a la vez

*

Page 76: Buenas Prácticas de desarrollo en Ruby on Rails

1. No refactorices y añadas funcionalidad a la vez

2. Haz tests antes de refactorizar. Y ejecútalos a menudo

*

Page 77: Buenas Prácticas de desarrollo en Ruby on Rails

1. No refactorices y añadas funcionalidad a la vez

2. Haz tests antes de refactorizar. Y ejecútalos a menudo

3. Refactoriza en pasos pequeños

*

Page 78: Buenas Prácticas de desarrollo en Ruby on Rails

Uso de variables

Page 79: Buenas Prácticas de desarrollo en Ruby on Rails

Minimizar uso de variables, y su scope

def show @post = Post.find(params[:id]) @related_posts = Post.find(:all, :conditions => { :category_id => @post.category_id }, :limit => 5)end

<h2><%= @post.title %></h2><%= simple_format(@post.body) %>

<%- @recent_posts.each do |post| -%> ...<%- end -%>

Page 80: Buenas Prácticas de desarrollo en Ruby on Rails

Minimizar uso de variables, y su scope

<h2><%= @post.title %></h2><%= simple_format(@post.body) %>

<%- @recent_posts.each do |post| -%> ...<%- end -%>

def show @post = Post.find(params[:id]) @related_posts = @post.recent_postsend

Page 81: Buenas Prácticas de desarrollo en Ruby on Rails

<h2><%= @post.title %></h2><%= simple_format(@post.body) %>

<%- @post.recent_posts.each do |post| -%> ...<%- end -%>

Minimizar uso de variables, y su scope

def show @post = Post.find(params[:id])end

Page 82: Buenas Prácticas de desarrollo en Ruby on Rails

Minimizar uso de variables, y su scope

Page 83: Buenas Prácticas de desarrollo en Ruby on Rails

Minimizar uso de variables, y su scope

Mi convención:

Page 84: Buenas Prácticas de desarrollo en Ruby on Rails

Minimizar uso de variables, y su scope

Mi convención:Una variable de instancia por acción

Page 85: Buenas Prácticas de desarrollo en Ruby on Rails

Minimizar uso de variables, y su scope

Mi convención:Una variable de instancia por acción

• Instancia de un modelo

Page 86: Buenas Prácticas de desarrollo en Ruby on Rails

Minimizar uso de variables, y su scope

Mi convención:Una variable de instancia por acción

• Instancia de un modelo

• Nombrada como el modelo

Page 87: Buenas Prácticas de desarrollo en Ruby on Rails

Minimizar uso de variables, y su scope

Mi convención:Una variable de instancia por acción

• Instancia de un modelo

• Nombrada como el modelo

• Array de instancias de un modelo

Page 88: Buenas Prácticas de desarrollo en Ruby on Rails

Minimizar uso de variables, y su scope

Mi convención:Una variable de instancia por acción

• Instancia de un modelo

• Nombrada como el modelo

• Array de instancias de un modelo

• Nombrada como el modelo en plural

Page 89: Buenas Prácticas de desarrollo en Ruby on Rails

El idioma del código

Page 90: Buenas Prácticas de desarrollo en Ruby on Rails
Page 91: Buenas Prácticas de desarrollo en Ruby on Rails

• Se trata de intercambiar, ¿no?

Page 92: Buenas Prácticas de desarrollo en Ruby on Rails

• Se trata de intercambiar, ¿no?

• Rails hace un gran esfuerzo por acercarse al lenguaje humano. Si escribimos en spanglish, nos lo cargamos

Page 93: Buenas Prácticas de desarrollo en Ruby on Rails

• Se trata de intercambiar, ¿no?

• Rails hace un gran esfuerzo por acercarse al lenguaje humano. Si escribimos en spanglish, nos lo cargamos

has_many :legajos

Page 94: Buenas Prácticas de desarrollo en Ruby on Rails

Recomendaciones bibliográficas

Page 95: Buenas Prácticas de desarrollo en Ruby on Rails
Page 96: Buenas Prácticas de desarrollo en Ruby on Rails
Page 97: Buenas Prácticas de desarrollo en Ruby on Rails

¿...?

Page 99: Buenas Prácticas de desarrollo en Ruby on Rails

Referencias

http://en.wikipedia.org/wiki/Best_practiceshttp://en.wikipedia.org/wiki/Law_of_Demeterhttp://www.ccs.neu.edu/home/lieber/LoD.htmlhttp://brian.maybeyoureinsane.net/blog/2006/12/15/law‐of‐demeter‐or‐how‐to‐avoid‐coding‐yourself‐into‐a‐corner‐in‐rails/http://weblog.jamisbuck.org/2006/10/18/skinny‐controller‐fat‐modelhttp://c2.com/cgi/wiki?DontRepeatYourself

Pierre Aroutche!, “El Go”Andrew Hunt, Dave Thomas, “The Pragmatic Programmers”Andrew Hunt, Venkat Subramaniam, “Practices of an Agile Developer”Martin Fowler, “Refactoring: Improving the Design of Existing Code”

Page 100: Buenas Prácticas de desarrollo en Ruby on Rails

Enjuto Mojamuto en:“Debuggeando una aplicación sin tests”

Caca de bug

Como Se Fue Vino™