В довольно большом приложении на Ruby возникает ситуация, когда данный объект идентифицируется с помощью нескольких вещей: name и id, скажем. Каждый из этих типов значений служит несколько разной цели и поэтому не является абсолютно эквивалентным (идентификатор и имя сохраняются в разных местах). Таким образом, мы получаем множество значений, передаваемых приложению (идентификаторы, имена и объекты). Эта ситуация кажется проблемой, по крайней мере, в некоторой степени, так как нас уже укусили ошибки, связанные с непонятностью, какой тип должен быть передан данной функции. Я на самом деле помню, как видел код проблемы в ряде приложений на протяжении многих лет, хотя я снова никогда не давал ему конкретного имени.
Ruby, как язык без типов, не допускает классических полиморфных функций на основе типов, как это делает C ++. В качестве обходного пути коллега часто прибегает к коду такого рода:
def initialize starting_value
if starting_post.kindof? Foo
@starting_id = get_id_from_foo starting_value
elsif starting_post.kindof? Bar
@starting_id = get_id_from_bar starting_value
else
raise "illegal type"
end
end
Распространение этого кода вокруг нашей кодовой базы (не только инициализаторов) приводит к тому, что я бы назвал "грязным полиморфизмом". Это часто работает, но иногда создает очень загадочные ситуации.
У меня есть три вопроса по этому поводу.
- Есть ли официальное название для этого как
анти-модель? «Грязный интерфейс?», «Грязный полиморфизм?» или что-то еще?
- Насколько плохо люди думают, что это так?
- Есть ли систематический способ рефакторинга?
этот? Задача, которую мы имеем с
обычный рефакторинг, что многие тесты, которые мы создали, используют это
свободная печать, и поэтому мы должны были бы изменить оба
тесты и реализации
одновременно и поэтому не будет иметь эффект эшафот от обычного теста на основе
рефакторинг. Я думаю, что на самом деле можно «усилить» этот свободный полиморфизм,
и абстрагируйте код в функцию, а не немедленно вырвите его. Но бы
это хорошая идея?