Cómo agregar funcionalidad a las clases de Ruby con decoradores

Los decoradores nos permiten agregar comportamiento a los objetos en tiempo de ejecución y no afectan a otros objetos de la clase. Los decoradores se pueden aplicar cuando necesite agregar y eliminar dinámicamente responsabilidades a una clase. El patrón decorador es una alternativa útil para crear subclases. Proporcionan funcionalidad adicional a una clase y al mismo tiempo mantienen la coherencia de la API pública. Veamos un ejemplo para comprender la importancia de Ruby Decorators. Considere que tenemos una clase Tattoo con un método de precio que devuelve 300.
Clase Tattoo def precio 300 final final
Ahora agregaremos un color adicional como característica y el precio aumentaría en 150 La forma más sencilla es crear una subclase TattooWithColour que devuelva 450 en el método del precio.
clase TattooWithColour < Tatuaje def precio 450 fin fin
A continuación, debemos representar un tatuaje grande que suma 200 al precio de nuestros tatuajes. Podemos representar esto usando una subclase de Tattoo BigTattoo.
clase BigTattoo < Tatuaje def precio 500 fin fin
También podríamos tener tatuajes de mayor tamaño y podrían añadir más precio a nuestro BigTattoo. Si tuviéramos que considerar que estos tipos de tatuajes podrían usarse con colores, necesitaríamos agregar las subclases BigTattooWithColour y BiggerTattooWithColour. Con este método, terminamos con un total de 6 clases. Incluso duplique ese número si desea representar estas combinaciones con diseños adicionales en el tatuaje.

Heredar dinámicamente con módulos

Para simplificar nuestro código, podemos usar módulos para agregar dinámicamente comportamiento a nuestra clase Tattoo. Escribamos los módulos ColourTattoo y BigTattoo para esto.
módulo ColourTattoo def precio super + 150 final final
módulo BigTattoo def precio super + 200 final final
Ahora podemos extender nuestros objetos de tatuaje dinámicamente usando el método Object#extend. tatuaje = Tatuaje.nuevo tatuaje.extend(ColorTattoo) tatuaje.extend(BigTattoo) Esta es una buena mejora con respecto a nuestra implementación basada en herencia. En lugar de tener subclases, solo tenemos una clase y 3 módulos. Si necesitáramos agregar diseño adicional a la ecuación, necesitaríamos solo cuatro módulos en lugar de 12 clases.

Aplicando el patrón decorador

Esta solución basada en módulos ha simplificado enormemente nuestro código, pero aún podemos mejorarlo usando el decorador. Consideraremos un BiggerTatto como el que se forma sumando dos veces 150 al coste de un Tatuaje. No podemos hacer esto con nuestro enfoque basado en módulos. Sería tentador llamar a tattoo.extend(BigTattoo) dos veces para obtener BiggerTattoo. Extender el módulo por segunda vez no tiene ningún efecto cuando ya hemos usado los extendidos. Si continuáramos usando la misma implementación, necesitaríamos tener un módulo BiggerTattoo que devuelva super + 300 como costo. En su lugar, podemos usar un decorador que se puede componer para construir objetos complejos. Comenzamos con un decorador llamado BigTattoo que envuelve un objeto Tattoo.
clase BigTatto def inicializar (tatuaje) @tattoo = final del tatuaje
def precio @tattoo.price + 150 fin fin
Ahora se puede crear un tatuaje más grande usando este contenedor dos veces en un objeto de tatuaje. tatuaje = Tatuaje.nuevo big_tattoo= BigTattoo.new(tatuaje) más grande_tattoo = BigTattoo.new(big_tattoo) De manera similar, podemos representar un tatuaje en color usando un decorador TattooWithColour. Usando sólo tres clases, ahora podemos representar 6 tipos de tatuajes. Con una amplia experiencia en todas las facetas del desarrollo de Ruby On Rails, en Railscarma, le ofrecemos una amplia gama de servicios para ayudarle a implementar una estrategia integral personalizada para comunicarse con sus prospectos y sus clientes en el momento adecuado, a través de los canales correctos. Para más detalles Contáctenos.

Suscríbete para recibir las últimas actualizaciones

Artículos Relacionados

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

es_ESSpanish