если еще или еще: когда использование условных операторов является (или не является) запахом кода

Когда операторы if — плохая идея? Как вы можете сказать?

Недавно я писал код, который выглядел примерно так:

def main(args):
    if args.whatever == 1:
        do_this_thing(args)
    else if args.whatever == 2:
        do_this_other_thing(args)
    else if args.whatever === 3:
        if args.thingy:
            do_the_wacky_thing()
    ...etc

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

TL;DR

  • Возможно, вам не понадобится рефакторинг. Это полностью зависит от того, что делает условное выражение.
  • Прочитайте это". Это отличный список способов упростить условные операторы во многих различных сценариях.
  • Если вы используете условные операторы для проверки существования вещей в качестве меры предосторожности, вам не нужно этого делать. Читайте о EAFP. (Примечание: это относится к Python и может не применяться к другим языкам)
  • Если вы используете операторы if для создания объектов разных типов, подумайте об использовании полиморфизма. Хороший короткий пример того, что здесь.

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

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

Должно ли возвращаемое значение «ложь» для любого из ваших операторов if полностью остановить программу? Изменится ли общее поведение вашей программы в зависимости от оператора if? Вы используете для проверки данные, которые уже есть в другой форме?

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

Извлеките свои условные выражения в методы

Когда вы начинаете добавлять кучу условных выражений вместе, это может стать трудным для чтения. В этом случае вы можете захотеть извлечь проверку условий в методы. Они не только более читабельны, но и могут использоваться повторно и могут сохранить ваш код СУХИМ. См. эту ветку Stack Exchange для получения дополнительной информации.

Полиморфизм и абстрактные базовые классы

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

Если, например, вы знаете, что ваша программа будет принимать множество видов входных данных, будет анализировать их и затем помещать в базу данных…

Вы могли бы подумать о создании общего базового класса, описывающего, как следует обрабатывать все источники ввода (например, все они должны быть прочитаны, иметь целевой вывод, использовать регистратор и т. д.). Затем вы можете создать подклассы, которые наследуют (или переопределяют ) поведение по умолчанию, предоставляемое базовым классом.

Этот тип родительского класса — тот, который используется в качестве схемы для других классов — называется «абстрактным базовым классом» или ABC.

ABC в основном говорят: «Эй, я хочу, чтобы все классы, которые исходят от меня, имели эти методы и атрибуты. Но они могут делать с ними все, что захотят». В этом подходе хорошо то, что будущие разработчики могут планировать, чтобы дочерние классы и объекты всегда имели согласованный интерфейс. Например, все исходные классы будут иметь метод чтения, метод регистратора и т. д.

Подробнее об абстрактных базовых классах
* Страница Википедии с примером python: https://en.wikipedia.org/wiki/Specification_pattern
* python docs: https:/ /docs.python.org/3/library/abc.html
* средняя статья: https://medium.com/technology-nineleaps/abstract-base-classes-in-python-2f8366c140a2
* Тема SO: https://stackoverflow.com/questions/3570796/why-use-abstract-base-classes-in-python

Государственный шаблон проектирования

Если условные операторы определяют, как будет вести себя программа в целом, возможно, вы захотите рассмотреть шаблон проектирования состояния. Это сложнее, и я еще не полностью разобрался с этим, поэтому я просто оставлю ссылку здесь и позволю вам погрузиться в нее самостоятельно.

Любые учебные ресурсы, которые вы считаете полезными (особенно если они на Python), приветствуются!

Общие правила

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

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