Buenas Prácticas de desarrollo en Ruby on Rails

3,961 views
3,841 views

Published on

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,961
On SlideShare
0
From Embeds
0
Number of Embeds
42
Actions
Shares
0
Downloads
56
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Buenas Prácticas de desarrollo en Ruby on Rails

  1. 1. Buenas prácticas de desarrollo en Ruby on Rails Sergio Gil Pérez de la Manga
  2. 2. 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
  3. 3. 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)
  4. 4. “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”
  5. 5. “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”
  6. 6. Cosas de las que no voy a hablar (por obvias)
  7. 7. TESTING
  8. 8. Código Buen fácil de Código testear
  9. 9. Refactorizar sin tests es un deporte de riesgo
  10. 10. Control de Versiones
  11. 11. Infórmate, participa, interactúa
  12. 12. LEE
  13. 13. LEE Documentación
  14. 14. LEE Documentación Blogs
  15. 15. LEE Documentación Blogs Listas de correo
  16. 16. ESCRIBE Documentación Blogs Listas de correo
  17. 17. Acude a Conferencias
  18. 18. Acude a Conferencias ¡Y habla si te dejan!
  19. 19. Ven a las quedadas
  20. 20. Haz pair programming si puedes
  21. 21. Hablemos de código
  22. 22. Conoce tus herramientas
  23. 23. some_things = [] some_other_things.each do |some_other_thing| some_things << some_other_thing.wadus end
  24. 24. some_things = some_other_things.map do |some_other_thing| some_other_thing.wadus end
  25. 25. some_things = some_other_things.map(&:wadus)
  26. 26. DRY pero no tanto
  27. 27. Don’t Repeat Yourself “Every piece of knowledge must have a single, unambiguous, authoritative representation within a system”
  28. 28. Pero DRY es un medio, no un fin
  29. 29. Pero DRY es un medio, no un fin Lo único importante es:
  30. 30. Pero DRY es un medio, no un fin Lo único importante es: Legibilidad
  31. 31. Pero DRY es un medio, no un fin Lo único importante es: Legibilidad Mantenibilidad
  32. 32. login: &login adapter: mysql username: username password: password host: mysql.example.com Pero DRY es un medio, no un fin development: <<: *login Lo único importante es: database: app_dev Legibilidad Mantenibilidad test: <<: *login database: app_test production: <<: *login database: app_prod
  33. 33. MVC
  34. 34. Skinny Controller, Fat Model
  35. 35. Modelo cocinero, controlador camarero
  36. 36. class Person < AR::B has_one :address end class PeopleController < AC end <% people = Person.find( :conditions => [quot;added_at > ? and deleted = ?quot;, Time.now.utc, false], :order => quot;last_name, first_namequot;) %> <% people.reject { |p| p.address.nil? }.each do |person| %> <div class=quot;personquot;> <span class=quot;namequot;> <%= person.last_name %>, <%= person.first_name %> </span> <span class=quot;agequot;> <%= (Date.today - person.birthdate) / 365 %> </span> </div> <% end %>
  37. 37. class Person < AR::B has_one :address end class PeopleController < AC def index @people = Person.find( :conditions => [quot;added_at > ? and deleted = ?quot;, Time.now.utc, false], :order => quot;last_name, first_namequot;) @people = @people.reject { |p| p.address.nil? } end end <% @people.each do |person| %> <div class=quot;personquot;> <span class=quot;namequot;> <%= person.last_name %>, <%= person.first_name %> </span> <span class=quot;agequot;> <%= (Date.today - person.birthdate) / 365 %> </span> </div> <% end %>
  38. 38. class Person < ActiveRecord::Base has_one :address def self.find_recent people = find( :conditions => [quot;added_at > ? and deleted = ?quot;, Time.now.utc, false], :order => quot;last_name, first_namequot;) people.reject { |p| p.address.nil? } end def name quot;#{last_name}, #{first_name}quot; end def age (Date.today - person.birthdate) / 365 end end class PeopleController < ActionController::Base def index @people = Person.find_recent end end <% @people.each do |person| %> <div class=quot;personquot;> <span class=quot;namequot;><%= person.name %></span> <span class=quot;agequot;><%= person.age %></span> </div> <% end %>
  39. 39. Hacia el controlador trivial
  40. 40. Hacia el controlador trivial Plugins como resource_controller
  41. 41. Hacia el controlador trivial Plugins como resource_controller class PostsController < ApplicationController resource_controller end
  42. 42. REST
  43. 43. RESTricción liberadora
  44. 44. Si lo que quieres hacer no encaja en REST
  45. 45. Si lo que quieres hacer no encaja en REST • Puede que pertenezca al 20% de cosas que no encajan
  46. 46. Si lo que quieres hacer no encaja en REST • Puede que pertenezca al 20% de cosas que no encajan • Puede que lo estés enfocando mal
  47. 47. Si lo que quieres hacer no encaja en REST • Puede que pertenezca al 20% de cosas que no encajan • Puede que lo estés enfocando mal • Así que dale una vuelta
  48. 48. Demeter y el Acoplamiento
  49. 49. Un método de un objeto sólo debe llamar a:
  50. 50. Un método de un objeto sólo debe llamar a: • Métodos del mismo objeto
  51. 51. Un método de un objeto sólo debe llamar a: • Métodos del mismo objeto • Métodos de objetos directamente relacionados
  52. 52. comment.article.author.address.city.country.two_letter_code
  53. 53. class User < AR::B # email end class Blog < AR::B belongs_to :user has_many :articles end class Article < AR::B belongs_to :blog end article.blog.user.email
  54. 54. class User < AR::B # email end class Blog < AR::B belongs_to :user has_many :articles delegate :email, :to => :user end class Article < AR::B belongs_to :blog delegate :email, :to => :blog end article.email
  55. 55. 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 quot;should have two_letter_code 'es'quot; do @comment.article.author.adress.city.country.two_letter_code.should == 'es' end
  56. 56. El termómetro del test before(:each) do @comment = mock_model(Comment, :author_country_code => 'es') end it quot;should have two_letter_code 'es'quot; do @comment.author_country_code.should == 'es' end
  57. 57. Uso de convenciones
  58. 58. Las de Rails: piénsatelo antes de saltártelas
  59. 59. Crea las tuyas propias
  60. 60. Crea las tuyas propias ¡Y cúmplelas!
  61. 61. Refactorización
  62. 62. Refactoriza durante el desarrollo...
  63. 63. ...y no al final
  64. 64. 1. No refactorices y añadas funcionalidad a la vez
  65. 65. 1. No refactorices y añadas funcionalidad a la vez 2. Haz tests antes de refactorizar. Y ejecútalos a menudo
  66. 66. 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
  67. 67. Uso de variables
  68. 68. 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 -%>
  69. 69. Minimizar uso de variables, y su scope def show @post = Post.find(params[:id]) @related_posts = @post.recent_posts end <h2><%= @post.title %></h2> <%= simple_format(@post.body) %> <%- @recent_posts.each do |post| -%> ... <%- end -%>
  70. 70. Minimizar uso de variables, y su scope def show @post = Post.find(params[:id]) end <h2><%= @post.title %></h2> <%= simple_format(@post.body) %> <%- @post.recent_posts.each do |post| -%> ... <%- end -%>
  71. 71. Minimizar uso de variables, y su scope
  72. 72. Minimizar uso de variables, y su scope Mi convención:
  73. 73. Minimizar uso de variables, y su scope Mi convención: Una variable de instancia por acción
  74. 74. Minimizar uso de variables, y su scope Mi convención: Una variable de instancia por acción • Instancia de un modelo
  75. 75. 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
  76. 76. Minimizar uso de variables, y su scope Mi convención: Una variable de instancia por acción • Instancia de un • Array de instancias modelo de un modelo • Nombrada como el modelo
  77. 77. Minimizar uso de variables, y su scope Mi convención: Una variable de instancia por acción • Instancia de un • Array de instancias modelo de un modelo • Nombrada como el • Nombrada como el modelo modelo en plural
  78. 78. El idioma del código
  79. 79. • Se trata de intercambiar, ¿no?
  80. 80. • Se trata de intercambiar, ¿no? • Rails hace un gran esfuerzo por acercarse al lenguaje humano. Si escribimos en spanglish, nos lo cargamos
  81. 81. • 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
  82. 82. Recomendaciones bibliográficas
  83. 83. ¿...?
  84. 84. Muchas Gracias sgilperez@gmail.com sergio@bebanjo.com http://lacoctelera.com/porras http://twitter.com/porras
  85. 85. Referencias 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” http://en.wikipedia.org/wiki/Best_practices http://en.wikipedia.org/wiki/Law_of_Demeter http://www.ccs.neu.edu/home/lieber/LoD.html http://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‐model http://c2.com/cgi/wiki?DontRepeatYourself
  86. 86. Enjuto Mojamuto en: “Debuggeando una aplicación sin tests” Caca de bug Como Se Fue Vino™

×