Перевод статьи «Switch is ok».

Конструкция switch
в последнее время пользуется дурной славой. Одни разработчики всеми силами пытаются ее избегать, другие считают, что ее вообще следует отнести к устаревшим. То есть, эту конструкцию практически воспринимают как какой-то анти-паттерн. Чтобы проиллюстрировать примеры такого отношения, приведу несколько ссылок на статьи:
- Eliminate the switch statement for better code
- Deprecating the switch statement
- Replace your switch statement and multiple «if and else», using Object Literals
В своей статье я попытаюсь опровергнуть распространенные доводы против switch
.
Switch — старая и неуклюжая конструкция
Да, конструкция switch
— старая. Но if
-выражение тоже старое, да и цикл for немолод, и что с того? Это реально очень странный аргумент. Новые и блестящие штуки не обязательно лучше старых.
Нам приходится вручную добавлять break
Это интересный довод, поскольку во всех приводимых при этом примерах switch
показан с ключевым словом break
. Так что, в качестве контраргумента, приведу свой пример. На самом деле break
в конструкции switch
не обязателен, мы можем ограничиться одним лишь return
.
switch (x) { case "DC": return "Batman"; case "Marvel": return "Wolverine"; default: return "Spiderman" }
Ну, и где тут break
?
Это не выражение
Да, не выражение. Но оберните switch
в функцию, и получите выражение:
function hero(x) { switch (x) { case "DC": return "Batman"; case "Marvel": return "Wolverine"; default: return "Spiderman" } } const myHero = hero("DC");
Это признак нечистого и процедурного программирования
Вы работаете с мультипарадигменным языком, где можете изменять все, что угодно, можете сделать любой побочный эффект по своему желанию, и при этом приводите подобные аргументы? Чистота в таких языках, как JS, это лишь практика кодинга. Если вы хотите писать чистый код, switch
не будет препятствием, поверьте мне.
Конструкция switch располагает к ошибкам
Прекратите пользоваться Notepad. Пожалуйста.
И обновите свою Windows 8.
Вместо switch следует использовать объектные литералы
Да, это можно. Я не буду утверждать, что использование литералов это плохая идея. Но говорить, что использование switch
намного хуже, тоже преувеличение. Посмотрите на эти два примера:
// switch function hero(x) { switch (x) { case "DC": return "Batman"; case "Marvel": return "Wolverine"; default: return "Spiderman" } } // literal function hero(x = "default") { const herosMap = { "DC": "Batman", "Marvel" : "Wolverine", "default": "Spiderman" } return herosMap[x]; }
Да-да, я знаю: вы заметили, что второй пример меньше, а еще там хороший прием с дефолтным значением, а это секси. Но код не должен быть «секси», за этим обращайтесь к своей девушке/парню. Да и меньше — не всегда лучше. Когда вы читаете эти два куска кода, на втором вы наверняка задерживаетесь чуть дольше. Признайте это!
Эти примеры равноценны, здесь нет победителя. Не вижу никаких проблем в том, чтобы использовать любой из них.
switch не подходит для ООП-кода
Ну да, а ваш StrategyFactoryProducerPattern
, конечно, лучше. Но если серьезно, switch
и вправду может не сочетаться с принципами объектно-ориентированного программирования насчет полиморфизма.
А вы вообще пишете объектно-ориентированный код? Если нет, то этот аргумент пролетает мимо.
Мы можем сделать какой-то FP-wrapper, чтобы больше никогда не видеть switch
Зачем использовать switch
, если можно использовать функцию? Ниже приведен пример из статьи «Eliminate the switch statement for better code». Вы можете сделать так:
const switchcase = cases => defaultCase => key => cases.hasOwnProperty(key) ? cases[key] : defaultCase const counter = (state = 0, action) => switchcaseF({ 'INCREMENT': () => state + 1, 'DECREMENT': () => state -1 })(state)(action.type)
а можете проще:
const counter = (state = 0, action) => { switch (action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 default: return state } }
Да, но в первом варианте нет {
, нет явного return
, зато есть частичное применение, и обратите внимание, как в конце эта функция вызывается дважды (state)(action.type)
— это секси!
Если для вас это аргумент, идите поспите, а затем перечитайте код снова. И — да, я уже говорил, кто именно должен быть секси.
Конструкция switch вполне нормальна
В конструкции switch
нет ничего плохого. Мы можем использовать ее без break
, она наглядна, в ней четко видны все возможные ветки. Если вы думаете, что использование switch
и функциональное программирование несовместимы, посмотрите на чистые функциональные языки, в которых есть совпадение с шаблоном. Взгляните на пример кода на Elm:
hero x = case x of DC -> "Batman" Marvel -> "Wolverine" _ -> "Spiderman"
Да, это функциональное программирование, и — да, case of
это выражение, но это не значит, что нужно непременно отказаться от switch
. Используйте эту конструкцию, сделайте так, чтобы она что-то возвращала в любом случае. Не нужно усложнять то, что должно быть простым.
Хорошая статья, полезная. Правда, если честно, я недолюбливал всегда switch, даже до становления ООП.