Принятие методов "Расширение объектно-ориентированного программного обеспечения" для Ruby on Rails

Я читал Растущее объектно-ориентированное программное обеспечение, руководствуясь тестами от Стива Фримена и Нат Прайс и очень впечатлило. Я хочу принять идеи этой книги в проектах Rails с помощью RSpec, хотя ее примеры написаны на Java.

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

Но у Ruby нет синтаксиса, эквивалентного Java interface. Как я могу использовать их методы для проектов Rails?

UPDATE

Например, на странице 126 авторы представили интерфейс Auction для реализации метода bid. Во-первых, они издевались над Auction.class, чтобы выполнить тестовый проход, затем они внедрили класс Auction в качестве анонимного внутреннего класса в классе Main. Наконец, они извлекли новый конкретный класс XMPPAuction из Main (стр. 131-132).

Этот инкрементный подход - это суть этой книги, на мой взгляд.

Как я могу принять или подражать такой серии преобразований кода в разработке Ruby?

Ответ 2

Так как в Ruby все вещи напечатаны в стиле утка, а интерфейс - это просто набор полей и методов, которые публично открыты, вы можете сделать одно или несколько из следующих действий:

Test

Создайте свои тесты для проверки интерфейсов и имени и прокомментируйте свои тесты соответствующим образом - тогда вы можете передать все ваши "конкретные реализации" вашего "интерфейса" через один и тот же набор тестов. Пока ваш набор тестов охватывает случаи вашего приложения, все что угодно в вашем приложении, которое принимает экземпляр любого из этих конкретных классов, сможет обрабатывать экземпляр любого из других конкретных классов.

Использовать базовые классы

Определите базовый класс, который наследует все ваши конкретные классы, из которых все методы выбрасывают ошибку NotImplemented. Это дает вам иерархию, которую вы можете визуализировать, однако она требует дополнительных классов и может поощрять многочисленные тесты is a в вашем производственном коде, а не в том, что код основан на has a.

Ответ 3

Вы правы, что Ruby не имеет формальных интерфейсов. Вместо этого интерфейсы неявны в сообщениях, обрабатываемых объектом (см. утиная печать).

Если вы все еще ищете более формальный способ "обеспечить соблюдение" интерфейса в Ruby, подумайте о том, чтобы написать набор автоматических модульных тестов, которые являются зелеными, если объект соответствует интерфейсу должным образом и в противном случае являются красными.

Примеры см. в ActiveModel:: Lint:: Tests и rspec общие примеры.