Существует ли антипаттерн для описания этого метода кодирования? [закрыто]

26

У меня есть кодовая база, где программист склонен заключать вещи в области, которые не имеют смысла. Например, если у нас есть журнал ошибок, вы можете войти через

ErrorLog.Log(ex, "friendly message");

Он добавил различные другие средства для выполнения точно такой же задачи. НАПРИМЕР

SomeClass.Log(ex, "friendly message");

Который просто оборачивается и вызывает первый метод. Это добавляет уровни сложности без дополнительной выгоды. Есть ли анти-паттерн, чтобы описать это?

P.Brian.Mackey
источник
36
«Плохое кодирование» охватывает это;)
Одед
12
Зависит. Это оболочка для библиотеки журналов? Если когда-либо был шанс, что это могло быть обменено, это - фактически хорошая практика ...
Rig
3
@lortabac: проблема с «пахлавным кодом» заключается в том, что он звучит хорошо и вкусно, а значит, и желательно.
FrustratedWithFormsDesigner
10
Что говорит этот программист, когда вы добавляете их, почему они добавляют эти методы? Понимание их рассуждений должно облегчить их обучение.
Кит
3
Звучит как уровень косвенности , который может быть хорошим, если вы хотите избежать связи между двумя классами, как указывал @Rig. Возможно, это был просто кодер, страдающий от паттерна - просто пытаясь по некоторому шаблону решить проблему, которой нет, нарушая KISS.
Fuhrmanator

Ответы:

54

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

Остальное мы просто называем "мусорным кодом" ...


Если бы я предложил название для этой конкретной вредной привычки, это было бы «Обсессивное расстройство абстракции» :-)

Стивен С
источник
9
Я всегда использовал «Ад косвенности».
Дэн Нили,
27

Нет, это не анти паттерн, но я бы поднял следующие вопросы.

Нарушение принципа единой ответственности

SRP говорит, что у класса должна быть одна причина для изменения. Добавление метода ведения журнала означает, что класс также должен измениться, если необходимо изменить логику ведения журнала.

Нарушение is-aотношений

Базовые классы не являются наборами инструментов, где вы можете добавить несколько удобных методов.

Это эффективно связывает все унаследованные классы с реализациями, которые есть у базового класса.

Сравните это с составом.

jgauffin
источник
1
«Единый вопрос ответственности»? SRP? Возможно, вы хотели написать «Принцип единой ответственности»? Просто соединяю их здесь. :)
zxcdw
8

Не то чтобы это приемлемо, но это может быть незаконченный рефакторинг. Может быть, SomeClass.log () имел свою собственную логику и был реализован первым. И позже они поняли, что должны использовать ErrorLog.Log (). Поэтому вместо изменения 100 мест, где вызывается SomeClass.Log (), они просто делегируются в ErrorLog.Log (). Лично я бы изменил все ссылки на ErrorLog.Log () или хотя бы прокомментировал SomeClass.log (), чтобы сказать, почему он делегирует так, как это происходит.

Просто кое-что рассмотреть.

Хит Лилли
источник
7

Мне приходит в голову термин «код лазаньи», хотя, по-видимому, он означает разные вещи для разных людей . Моя интерпретация всегда была «многослойной ради того, чтобы быть многослойной».

dasblinkenlight
источник
3
Я также слышал "Луковый код", чтобы описать то же самое.
Джастин Нисснер
4

Я не уверен, что это будет нарушением принципа единой ответственности, потому что если есть изменение в сигнатуре метода ErrorLog (метод, который вызывается SomeClass), каждый клиентский код, который вызывает этот метод, потерпит неудачу.

Там, очевидно, есть способ использовать наследование (или создание классов, для которых требуется ведение журнала, реализуя интерфейс ведения журнала).


источник
Все еще плохая практика, потому что: 1) вряд ли это изменится 2) если это изменится, они могут просто создать класс-оболочку с тем же именем и изменить импорт.
Кевин Клайн
2
+1. А вот «дядя Боб» (Роберт Мартин) выступает за централизацию зависимостей в ограниченном количестве модулей, а не за разбрасывание их по коду.
MarkJ
3

Или мы можем рассматривать это как «обучающий момент» :)

Ваш разработчик может быть на полпути к хорошей идее. Предположим, вы хотите иметь требование, чтобы все ваши бизнес-объекты были способны к интеллектуальной регистрации. Вы можете определить:

   public interface IBusinessObjectLogger
   {
       void Log(Exception ex, string logMessage)
   }

Теперь внутри ваших объектов вы можете использовать объект ErrorLog для фактического ведения журнала, в то время как код SomeClass добавляет конкретное значение объекта в сообщение журнала. Затем вы можете дополнительно расширить свои API ведения журналов, чтобы реализовать функции ведения журналов на основе файлов, баз данных или сообщений, не затрагивая бизнес-объекты.

cdkMoose
источник
3

Я не уверен, что это автоматически зло.

Если вы вызываете SomeClass.Log, то это, безусловно, зло, но если Log используется только из WITHIN SomeClass, это сокращает связь, и я бы назвал ее приемлемой.

Лорен Печтель
источник
2

На самом деле это довольно часто встречается в определенных стилях кодирования, и основы мышления сами по себе не являются анти-паттерном.

Вероятно, это результат того, что кто-то по необходимости кодирует без знания более широкой кодовой базы: «Хорошо, этот код должен регистрировать ошибку, но эта функция не является основной целью кода. Поэтому мне нужен метод / класс, который это сделает для меня". Это хороший способ мышления; но, не зная ErrorLog, они создали SomeClass. Затем они нашли ErrorLog на более позднем этапе, и вместо того, чтобы заменить все методы, которые они вставили, они сделали вызов метода ErrorLog. Вот где это становится проблемой.

Keiths
источник
2

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

http://en.wikipedia.org/wiki/Accidental_complexity

JoelFan
источник
1

Это может быть злоупотребление / неправильное понимание шаблона фасада . Я видел похожие вещи в кодовой базе, с которой работал. Разработчики прошли через этап, когда они были без ума от шаблонов проектирования, не понимая всеобъемлющих принципов ОО-дизайна.

Неправильное использование шаблона Facade приводит к размытию уровней абстракции по уровням приложения.

Kazark
источник
1

Этот программист выполняет обертывание некоторого кода, чтобы он не имел прямой зависимости от модуля журналирования. Без более конкретной информации невозможно дать более конкретную модель. (То, что эти обертки бесполезны - это ваше мнение, с которым невозможно согласиться или не согласиться без гораздо большей информации.)

Это может быть шаблон «Прокси» , « Делегат» , « Декоратор» , « Композит» или другие, связанные с упаковкой, сокрытием или распределением вызовов. Это может одна из таких вещей в неполном состоянии развития.

Kaz
источник
0

Я мог представить, что это культурная разница. Возможно, есть веская причина для дублирования функциональности в этой конкретной кодовой базе. Я мог представить легкость написания, чтобы быть такой причиной. Мой программист на Python все равно сказал бы, что это плохо, так как « Должен быть один - и желательно только один - очевидный способ сделать это », но некоторые ребята из Perl могут привыкнуть к тому, что « Существует более одного способ сделать это ".

Бенгт
источник
1
Простота первоначального написания не является хорошей причиной для дублирования. Плохой код может быть легче написать в первый раз, но это не облегчает написание кода в долгосрочной перспективе. Как поступает новый парень с дублированной функциональностью? Какой метод он вызывает? Он тратит время на их поиск и чтение, но обнаруживает, что они делают то же самое.
Казарк
Возможно, этот код изначально задумывался как прототип, который затем использовался в качестве приращения (ab). Я думаю, что в этом случае оптимизация для первоначального написания была бы действительной.
Бенгт