Модуль Forwardable и как он решает Interface Segregation Problem

В статье обсуждались принципы SOLID, включая Interface Segregation Principle, и был рассмотрен пример на языке ruby. Он не совсем удачный ввиду того, что обычно принцип рассматривается на примере интерфейсов, коих в ruby нет. Более “корректную” демонстрацию принципа разделения интерфейса можно реализовать с помощью наследования и модуля Forwardable.

И так, у нас есть класс Blog — базовый класс для управления постами, и класс Moderator.

Модератор должен иметь возможность редактировать посты, на то он и модератор, но вкупе с редактированием он также наследует методы создания и удаления, которые ему не нужны.

Clients should not be forced to depend upon interfaces that they do not use.” — так нам завещал дядюшка Robert C. Martin. Избавиться от “лишних” методов можно с помощью модуля forwardable:

Теперь класс Moderator не наследует класс Blog, взамен этого мы воспользовались директивой def_delegators для делегации метода :edit_post объекту (delegate object:@blog, который инициализируется в конструкторе класса Moderator. Теперь, вместо того, чтобы предоставлять доступ к полному определению класса, мы можем определить конкретный метод, с которым должен работать Модератор. При выполнении кода метод edit_post успешно будет исполнен, а при вызове delete_post компилятор выдаст нам ошибку:

isp_good_example.rb:28:in `<main>’: undefined method `delete_post’ for #<Moderator:0x007f7f5189a9e0 @blog=#<Blog:0x007f7f5189aa08>> (NoMethodError)