В довольно большом приложении Ruby мы имеем ситуацию, когда данный объект идентифицируется несколькими вещами: имя и идентификатор, скажем. Каждый из этих типов значений выполняет несколько другую цель и поэтому не совсем эквивалентен (id и name сохраняются в разных местах). Таким образом, мы завершаем различные значения, передаваемые вокруг приложения (идентификаторы, имена и объекты). Эта ситуация кажется проблемой как минимум в некоторой степени, поскольку мы уже были укушены ошибками, в которых не было ясно, какой тип должен быть передан данной функции. На самом деле я напомню, что за многие годы наблюдался похожий код проблемы в ряде приложений, хотя я снова никогда не давал ему определенного имени.«messy-polymorphism» anti-pattern
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
Распространение этого кода вокруг нашего кода базы (не только инициализаторов) приводит то, что я бы назвал «грязный-полиморфизм». Он часто работает, но иногда создает очень загадочные ситуации.
У меня есть три вопроса об этом.
- Есть ли формальное название для этого как анти-шаблон? «Беспорядочный интерфейс?», «Беспорядочный полиморфизм»? или что-то другое?
- Как плохо люди думают, что это так?
- Есть ли систематический способ для рефакторинга ? Задача, которую мы имеем с обычным рефакторингом, заключающаяся в том, что многие тесты, которые мы создали, используют этот , и мы должны были бы изменить как тесты, так и реализации одновременно, и поэтому не было бы эффекта эстафеты обычного теста на основе рефакторинг. Я думаю, что на самом деле можно «укрепить» этот свободный полиморфизм, и абстрагировать код в функцию, а не немедленно разорвать ее. Но будет это хорошая идея?
Это приложение Rails? –