Liber IT School

Блог

Паттерн Decorator в Ruby

17 Jul , 2023 · views

Декоратор - это структурный паттерн проектирования, который позволяет добавлять дополнительное поведение или функциональность к существующим объектам без необходимости изменять исходный код этих объектов. Он использует композицию объектов, где декоратор оборачивает (декорирует) целевой объект, добавляя ему новые возможности.

Декоратор может быть использован для обертывания модели и добавления новых полей или функциональности. Новые поля или методы могут быть определены в декораторе и доступны через его интерфейс, расширяя возможности базовой модели.

Пример реализации декоратора в Ruby может выглядеть следующим образом:

class ModelDecorator
def initialize(model)
@model = model
end
def additional_field
# Ваш код для определения значения дополнительного поля
end
def method_missing(method, *args, &block)
if @model.respond_to?(method)
@model.send(method, *args, &block)
else
super
end
end
def respond_to_missing?(method, include_private = false)
@model.respond_to?(method, include_private) || super
end
end

В этом примере ModelDecorator оборачивает модель и добавляет новое поле additional_field. Декоратор делегирует вызовы методов модели, перенаправляя их к соответствующим методам модели с помощью method_missing.

Таким образом, вы можете использовать декоратор для оборачивания экземпляра модели и добавления новых полей или функциональности без необходимости изменять саму модель.

Использование SimpleDelegator для создание декоратора

SimpleDelegator в Ruby часто используется для создания декораторов, которые добавляют дополнительное поведение к существующему объекту. Декораторы позволяют модифицировать поведение объекта, не изменяя его исходный код. Вот пример использования SimpleDelegator для создания декоратора:

require 'delegate'
# Класс, который будет декорирован
class Component
def operation
puts 'Выполняется базовая операция'
end
end
# Декоратор, который добавляет дополнительное поведение
class Decorator < SimpleDelegator
def operation
puts 'Выполняется дополнительная операция перед вызовом базовой операции'
super # Вызываем базовую операцию через делегирование
puts 'Выполняется дополнительная операция после вызова базовой операции'
end
end
# Использование декоратора
component = Component.new
decorated_component = Decorator.new(component)
decorated_component.operation

В данном примере Component представляет базовый класс или объект, который будет декорирован, и имеет метод operation. Класс Decorator является декоратором и наследуется от SimpleDelegator. Он переопределяет метод operation, добавляя дополнительное поведение перед и после вызова базовой операции с использованием ключевого слова super для вызова базовой операции через делегирование.

При выполнении кода вы увидите, что вызов decorated_component.operation сначала выполнит дополнительные операции из декоратора, а затем вызовет базовую операцию из Component.

Таким образом, используя SimpleDelegator, вы можете создавать декораторы, которые обогащают или изменяют поведение существующих объектов, не изменяя их исходный код.

Расширяем фунционал модели используя Decorator на основе SimpleDelegator

Давайте представим, что у нас есть модель User, которая представляет пользователей в системе. Модель User имеет поля first_name и last_name. Мы хотим создать декоратор для модели User, который добавит поле full_name, содержащее полное имя пользователя. Мы можем использовать SimpleDelegator для этой цели. Вот пример:

require 'delegate'
# Модель User
class User
attr_accessor :first_name, :last_name
def initialize(first_name, last_name)
@first_name = first_name
@last_name = last_name
end
end
# Декоратор для модели User
class UserDecorator < SimpleDelegator
def full_name
"#{first_name} #{last_name}"
end
end
# Использование декоратора
user = User.new('John', 'Doe')
decorated_user = UserDecorator.new(user)
puts decorated_user.full_name

В этом примере мы создали модель User с полями first_name и last_name. Затем мы создали декоратор UserDecorator, который наследуется от SimpleDelegator. Декоратор добавляет метод full_name, который объединяет first_name и last_name в полное имя пользователя.

При использовании декоратора мы создаем экземпляр User и передаем его в UserDecorator. Затем мы можем вызывать методы first_name, last_name и full_name на декорированном пользователе. В данном случае, вызов decorated_user.full_name выведет полное имя пользователя, объединяя first_name и last_name.

Таким образом, мы использовали SimpleDelegator для создания декоратора модели User, добавив новое поле full_name на основе существующих полей first_name и last_name.

Заключение

В целом, использование декораторов в Ruby помогает создавать более гибкую, модульную и расширяемую архитектуру приложений. Они предоставляют мощный инструмент для добавления функциональности к объектам, не нарушая существующий код и принципы проектирования.

Декораторы позволяют разделить различные аспекты функциональности объекта, размещая их в отдельных декораторах. Это улучшает структуру кода и позволяет легко добавлять или изменять поведение объекта, не затрагивая его основной класс.

Liber IT School

Либер Виталий Анатольевич

ИНН 720692679400

vitalyliber@gmail.com

Договор-офертаПолитика конфиденциальности