Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ruby DCI

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest. →
Avatar for Wolox Wolox
September 15, 2014

Ruby DCI

Introducción a DCI y cómo implementarlo en aplicaciones Ruby on Rails.

Avatar for Wolox

Wolox

September 15, 2014

Other Decks in Programming

Transcript

  1. Class Oriented Programming Un programa es orientado a clases si

    define tanto lo que un objeto es como lo que un objeto hace como parte de una jerarquía de clases.
  2. Class Oriented Programming A la hora de implementar comportamiento nuevo

    para un objeto: • Se agregan métodos a su clase • Se crea una nueva clase
  3. Class Oriented Programming • Lenguajes estáticos (Java, C++, C#) •

    Conceptos como polimorfismo sólo son posibles usando la jerarquía o interfaces • El compilador sabe de antemano el comportamiento que un objeto puede llegar a tener
  4. Object Oriented Programming • El foco está en los objetos

    y no en sus clases. • Las clases representan lo que un objeto es • Los objetos hacen cosas siempre y cuando estén cumpliendo un rol
  5. Object Oriented Programming • Lenguajes dinámicos (Ruby, Python, JS, etc.)

    • Permiten definir comportamiento en runtime • Existen objetos más allá de las clases • El polimorfismo es transparente
  6. Ejemplo La clase Person es la representación del modelo de

    una persona. • Si quiero modelar a un estudiante, ¿qué hago?
  7. Ejemplo La clase Student puede heredar de Person y agregar

    el comportamiento de un estudiante. • Ahora se quiere modelar a un estudiante que trabaja, ¿qué hago? Person Student
  8. Ejemplo Si Employee hereda de Student: • ¿Como modelo a

    un trabajador que no estudia? Si Employee hereda de Person • ¿Cómo modelo a un estudiante que trabaja? Person Student Employee Person Student Employee
  9. Ejemplo ¿Dónde está el problema? • Estoy pensando en clases,

    no en objetos • La persona es un objeto que puede jugar varios roles
  10. Data Context Interaction • Es un paradigma pensado para modelar

    la interacción entre objetos • Fue inventado por Trygve Reenskaug (MVC)
  11. Data Context Interaction Objetivos: • Mejorar la lectura de código

    OO • Separar lo que el sistema es de lo que el sistema hace • Ayudar al programador a recrear nuestro modelo mental con objetos
  12. Data Context Interaction • Data: modelos de dominio • Context:

    casos de uso • Role: comportamiento agregado
  13. Data “What the system is” • Estructura estática de un

    modelo • Propiedades • Asociaciones
  14. Context • Código que relaciona roles bajo un algoritmo o

    caso de uso • Es el encargado de asignarle el rol a los objetos y hacerlos interactuar
  15. Roles “What the system does” • Stateless • Agregan comportamiento

    a un objeto de dominio • Un objeto puede jugar diferentes roles
  16. DCI en Ruby - Modelos Los modelos (ActiveRecord, ActiveModel) generalmente

    representan los datos class Model < ActiveRecord::Base # Associations has_many ... belongs_to ... # Validations validates ... # Methods related to the model structure end
  17. DCI en Ruby - Contextos Los contextos son objetos que

    se inicializan con los datos y se invocan con parámetros adicionales class Context def initialize(model, ...) @role = Role.new(model) ... end def call(parameter) ... end end
  18. DCI en Ruby - Roles Los roles pueden lograrse de

    varias maneras: • Modules • Concerns • SimpleDelegator
  19. DCI en Ruby - Modules module M def self.included(base) base.extend

    ClassMethods base.class_eval do scope :disabled, -> { where(disabled: true) } end end module ClassMethods ... end end
  20. DCI en Ruby - Concerns require 'active_support/concern' module M extend

    ActiveSupport::Concern included do scope :disabled, -> { where(disabled: true) } end module ClassMethods ... end end
  21. DCI en Ruby - SimpleDelegator class Role < SimpleDelegator def

    initialize(model) super(model) end def do_something_new .. end end
  22. DCI en Ruby • Extender modulos en runtime es más

    costoso que incluirlos • Usar SimpleDelegator es lo más costoso en la mayoría de los casos • Los concerns están disponibles a partir de Rails 4
  23. DCI en Ruby - Ejemplo Tengo que modelar la funcionalidad

    de vender un proyecto dentro de Wolox, lo cual implica entender los requisitos del cliente, estimarlos y luego armar el presupuesto.
  24. DCI en Ruby - Ejemplo class Woloxer < ActiveRecord::Base def

    log_hours(duration, date) ... end end
  25. DCI en Ruby - Ejemplo class TechnicalLead < SimpleDelegator def

    initialize(woloxer) super(woloxer) end def estimate(project) ... end end
  26. DCI en Ruby - Ejemplo class ProductOwner < SimpleDelegator def

    initialize(woloxer) super(woloxer) end def understand(client) ... end end
  27. DCI en Ruby - Ejemplo class BudgetAnalyst < SimpleDelegator def

    initialize(woloxer) super(woloxer) end def create_budget(project, estimation) ... end end
  28. DCI en Ruby - Ejemplo class SalesProcess def initialize(budget_analyst, product_owner,

    developer) @budget_analyst = BudgetAnalyst.new(budget_analyst) @product_owner = ProductOwner.new(product_owner) @technical_lead = Developer.new(technical_lead) end def send_budget(client) project = @product_owner.understand(client) estimation = @technical_lead.estimate(project) budget = @budget_analyst.create_budget(project, estimation) Mailer.send_budget_email(client, budget) end end
  29. Lectura • Metaprogramming Ruby (Paolo Perrota) • Practical Object-Oriented Design

    in Ruby (Sandi Metz) • http://dec0de.me/2013/02/dci-performance/ • http://pettermahlen.com/2010/09/10/dci-architecture- good-not-great-or-both/ • Clean Ruby (http://clean-ruby.com/)