Let’s go through the code step by step and explain what each part does.
```ruby
# Step 1: Create a class called `Nameable` with an abstract method `correct_name`.
class Nameable
def correct_name
raise NotImplementedError, "Subclasses must implement this method"
end
end
```
– Here, a class `Nameable` is defined. This class serves as an abstract base class, meaning it provides a blueprint for other classes to inherit from. It declares a method `correct_name` but doesn’t provide an implementation. Instead, it raises a `NotImplementedError` with a message indicating that subclasses must implement this method.
```ruby
# Step 2: Modify your `Person` class to inherit from `Nameable` and implement the `correct_name` method.
class Person < Nameable
attr_reader :id, :name
def initialize(id, name)
@id = id
@name = name
end
def correct_name
name
end
end
“`
– The `Person` class is defined. It inherits from the `Nameable` class, which means it must implement the `correct_name` method as required by the base class.
– It has attributes `id` and `name`, and a constructor that takes an `id` and a `name`.
– The `correct_name` method is implemented to simply return the `name`.
```ruby
# Step 3: Create a base decorator class that inherits from `Nameable`.
class Decorator < Nameable
def initialize(nameable)
@nameable = nameable
end
def correct_name
@nameable.correct_name
end
end
“`
– The `Decorator` class is defined. It also inherits from `Nameable`.
– It has a constructor that takes a `nameable` object and assigns it to an instance variable `@nameable`.
– The `correct_name` method is implemented to delegate the call to `correct_name` of the `nameable` object.
```ruby
# Step 4: Implement the `CapitalizeDecorator` class.
class CapitalizeDecorator < Decorator
def correct_name
super.capitalize
end
end
```
– The `CapitalizeDecorator` class is defined, which inherits from the `Decorator` class.
– It overrides the `correct_name` method. It first calls `super` to invoke the `correct_name` method of the wrapped `nameable` object. Then, it capitalizes the result using `capitalize`.
```ruby
# Step 5: Implement the `TrimmerDecorator` class.
class TrimmerDecorator < Decorator
def correct_name
super[0, 10] # Trim to a maximum of 10 characters
end
end
```
– The `TrimmerDecorator` class is defined, also inheriting from `Decorator`.
– It overrides the `correct_name` method. It first calls `super` to invoke the `correct_name` method of the wrapped `nameable` object. Then, it uses `[0, 10]` to extract the first 10 characters, effectively trimming the string if it’s longer.
```ruby
# Step 6: Test the decorators with the provided code.
person = Person.new(22, 'maximilianus')
puts person.correct_name # Outputs: maximilianus
capitalized_person = CapitalizeDecorator.new(person)
puts capitalized_person.correct_name # Outputs: Maximilianus
capitalized_trimmed_person = TrimmerDecorator.new(capitalized_person)
puts capitalized_trimmed_person.correct_name # Outputs: Maximilian
```
– Finally, in the testing phase, a `Person` object is created with an id of 22 and a name of ‘maximilianus’.
– The `correct_name` method is called on the `person` object and it prints ‘maximilianus’.
– Two decorators (`CapitalizeDecorator` and `TrimmerDecorator`) are used to modify the behavior of the `Person` object. The decorators are wrapped around the `person` object.
– The `correct_name` method is called on each decorated object and the results are printed.
Overall, this code demonstrates the use of the Decorator design pattern to dynamically add behavior to objects. It also showcases how decorators can be chained to provide multiple layers of functionality.