- Как избавиться от операторов switch — малоизвестный способ
- Каким решением разработчики пользуются чаще?
- Решение
- Заключение
- Что такое switch и как с ним бороться?
- Замена условного оператора полиморфизмом
- Проблема
- Решение
- Причины рефакторинга
- Достоинства
- Порядок рефакторинга
- Подготовка к рефакторингу
- Шаги рефакторинга
- Устали читать?
- ООП или как избавиться от switch -case
- Избавится от switch case
Как избавиться от операторов switch — малоизвестный способ
Простой способ облагородить свой код
Скорее всего, вы, как и я, научились не перегружать исходный код операторами if . Они трудно читаются. Такой код сложно проверить и выглядит он совсем не ахти.
Конечно же, это абстрактный пример, вырванный из контекста реального приложения. Только представьте себе, как мы выполняем вызовы функций внутри операторов. Или проверяем большое количество условий.
Каким решением разработчики пользуются чаще?
Давайте рассмотрим следующий пример. Сначала мы сравниваем выражение с набором значений, а затем выполняем код, когда одно из значений становится true . Все ли вы понимаете? Может, будет проще воспользоваться оператором switch ?
Я специально не убрал отбивку, пусть даже она не особо нужна при операторе return .
А сможете сразу понять, что не так с этим примером?
Написав такое, вы ничуть не сократите детализацию кода. Да и сложность кода никуда не денется. Такой код по-прежнему странно выглядит и с трудом поддерживается. Хотя теперь легче понять, что же вы пытаетесь в нем сделать.
Решение
Думаю, вам должно быть интересно, как работает рефакторинг. И почему этот пример может быть поучительным. Большинство людей привыкло писать код в такой хронологии:
- подумать о проблеме;
- реализовать черновое решение или прототип;
- написать код;
- подкорректировать части кода, чтобы он выглядел/выполнялся/работал лучше.
Последняя часть обычно считается рефакторингом. И она не должна быть «разовой акцией». Не проводите рефакторинг впопыхах сразу после написания кода, чтобы затем позабыть о файле.
Это так не работает. Рефакторинг похож на замкнутый круг. Вы что-то реализуете, затем стараетесь это дело улучшить, потом сокращаете, а после — избавляетесь от проблемных мест.
“Код должен быть гибким. И вы поддерживаете эту гибкость своим непрерывным вниманием к деталям ”.
Поэтому постарайтесь еще глубже погрузиться в процесс рефакторинга. Не останавливайтесь на первом этапе. А если работаете с уже готовым кодом, то пытайтесь улучшить его сразу. Плавно и без лишней спешки.
Давайте закончим с проверкой условий. Почему бы не воспользоваться функцией вместо switch ?
Обратите внимание, как мы определяем объект ingredients . Так мы избегаем его создания при каждом вызове getIngredients . А || используется для управления стандартными случаями, когда мы возвращаем lemon .
Проще, красивее и легче поддерживается. Это как раз то, что может сделать хороший рефакторинг. Но не останавливайтесь после первой попытки.
И помните, что вы можете пользоваться Map :
Заключение
Целью данной статьи было не просто показать вам, как можно улучшить код, но и пролить свет на процесс рефакторинга, а также объяснить, почему многие из нас его делают неправильно. Надеюсь, эта информация была вам полезной.
Источник
Что такое switch и как с ним бороться?
Программа без ветвления — очень простая и странная программа. Программа должна думать, просчитывать варианты, по-разному реагировать на различные внешние воздействия и вообще не быть однообразной. А это все невозможно без ветвлений. Ветвления реализуются при помощи опреаторов if и switch. Так зачем е с ним бороься?
Периодически, при просмотре чужого кода, мне попадаются длинные методы и громоздкие конструкции вложенных if и switch. Например, такие:
Меня лично, такие методы пугают и они просто не помещяются в моей голове. Первое что просится — это дать названия всем магичесским числам. Например, так:
Но если присмотреться, то мы не учитываем LoginSection если установлено значение self.loggedIn и прячем DetailsSection если сброшено значение self.settings.showDetails. Но мы просто преобразуем значение section в SectionIndex исходя из текущего состояния:
По-моему, уже выглядит гораздо приятнее, особенно если учесть, что таких ветвлений в объекте обычно несколько. Например, -titleForItem:inSection:, -performActionForItem:inSection: и т.п. А что если вспомнить о том, что язык у нас объектно-ориентированный, и состояние системы можно занести в объект-состояние? Тогда все эти методы сократятся до одной строки — обращение к объекту-состояния?
По-моему, вполне красиво. Осталось только откуда-то досать это самое состояние. Можн настраивать объекты состояний в самом объекте или написать нескольуо классов, определяющих состояния.
Получается, что мы избавились от ветвлений в нескольких местах, заменив его одной установкой состояния, а сами состояния получились целостными, понятными и собранными в одном месте.
Источник
Замена условного оператора полиморфизмом
Проблема
У вас есть условный оператор, который, в зависимости от типа или свойств объекта, выполняет различные действия.
Решение
Создайте подклассы, которым соответствуют ветки условного оператора. В них создайте общий метод и переместите в него код из соответствующей ветки условного оператора. Впоследствии замените условный оператор на вызов этого метода. Таким образом, нужная реализация будет выбираться через полиморфизм в зависимости от класса объекта.
Причины рефакторинга
Этот рефакторинг может помочь, если у вас в коде есть условные операторы, которые выполняют различную работу, в зависимости от:
класса объекта или интерфейса, который он реализует;
значения какого-то из полей объекта;
результата вызова одного из методов объекта.
При этом если у вас появится новый тип или свойство объекта, нужно будет искать и добавлять код во все схожие условные операторы. Таким образом, польза от данного рефакторинга увеличивается, если условных операторов больше одного, и они разбросаны по всем методам объекта.
Достоинства
Этот рефакторинг реализует принцип говори, а не спрашивай: вместо того, чтобы спрашивать объект о его состоянии, а потом выполнять на основании этого какие-то действия, гораздо проще просто сказать ему, что нужно делать, а как это делать он решит сам.
Убивает дублирование кода. Вы избавляетесь от множества почти одинаковых условных операторов.
Если вам потребуется добавить новый вариант выполнения, все, что придётся сделать, это добавить новый подкласс, не трогая существующий код (принцип открытости/закрытости).
Порядок рефакторинга
Подготовка к рефакторингу
Чтобы выполнить этот рефакторинг, вам следует иметь готовую иерархию классов, в которых будут содержаться альтернативные поведения. Если такой иерархии ещё нет, нужно создать её. В этом могут помочь другие рефакторинги:
Замена кодирования типа подклассами. При этом для всех значений какого-то свойства объекта будут созданы свои подклассы. Это хоть и простой, но менее гибкий способ, так как нельзя будет создать подклассы для других свойств объекта.
Замена кодирования типа состоянием/стратегией. При этом для определенного свойства объекта будет выделен свой класс и из него созданы подклассы для каждого значения этого свойства. Текущий класс будет содержать ссылки на объекты такого типа и делегировать им выполнение.
Последующие шаги этого рефакторинга подразумевают, что вы уже создали иерархию.
Шаги рефакторинга
Если условный оператор находится в методе, который выполняет ещё какие-то действия, извлеките его в новый метод.
Для каждого подкласса иерархии, переопределите метод, содержащий условный оператор, и скопируйте туда код соответствующей ветки оператора.
Удалите эту ветку из условного оператора.
Повторяйте замену, пока условный оператор не опустеет. Затем удалите условный оператор и объявите метод абстрактным.
Устали читать?
Сбегайте за подушкой, у нас тут контента на 7 часов чтения.
Или попробуйте наш интерактивный курс. Он гораздо более интересный, чем банальный текст.
Этот рефакторинг — малая часть интерактивного онлайн курса по рефакторингу.
Источник
ООП или как избавиться от switch -case
Помощь в написании контрольных, курсовых и дипломных работ здесь.
Как в as3 можно избавиться от оператора switch-case?
Добрый день! Использую в программе фабрику создания экземпляров животных public class.
Как объединить несколько функций в операторе Switch case или if
Доброго времени суток! Добавлено через 7 минут Доброго времени суток! Помогите у меня есть.
Как сделать возможность использовать в функции нужный массив без кучи if или switch-case?
Есть несколько массивов и одна функция.Как сделать возможность использовать в функции нужный массив.
switch-case, как писать в самом case
Такс дело вот в чём,прога работает всё хорошо,вот только мне не нравится как записваю страны в.
Вот есть у меня класс «tracker». Там реализовано как раз меню без case:
switch case 1 ИЛИ 2
делаю разбор вводимых команд, некоторые обрабатываются похоже, команды однобуквенные, разбираю.
If или switch().case. Что быстрее
Есть два кода. Первый: if(a == 2) a += 2; if(a == 3) a+= 3; if(a == 4) a+=4; Второй:
Что лучше использовать? if-else, switch-case или class?
Что используется чаще в програмирование когда есть много вариантов выбора? К примеру программа: .
Статический хеш или switch-case/if-else для выбора
Добрый день. Положим есть такой код:void parseByType(const QString &data, const QString &type) <.
Оператор Switch Case или недогоняю условие задачи
Добрый день. Дана задача. (C# console) Оператор Switch Case Составить программу, которая.
Источник
Избавится от switch case
Помощь в написании контрольных, курсовых и дипломных работ здесь.
Как избавится от switch case?
Как избавится от большого swich case допустим вот такой, хотя у меня он намного больше. Может.
Можно ли избавится от switch?
есть вот такая конструкция можно как то ее заменить ? — на Linq допустим switch (wtf.ToLower()).
SWITCH-CASE
switch — case 1 to 5
в вб используя select case можно указать для ветви Case 1 to 5 — тогда программа зайдет в эту веть.
Нам он почему-то не нравится. Попробуем перевести его в стратегию, и чтобы было более приближенно к реальности, добавим фабрику.
Теперь зададим себе вопрос — что поменялось? Всесто простой конструкции switch добавилось куча классов, которые еще предстоит поддерживать. При этом «x», «y» и «z» так же декларативно заданы, только внутри фабрики. Кажется не рационально.
Можно ли их задать динамически, подгрузив в рантайме из некоторого источника данных. Ответ можно. Но тогда и значения словаря придется создавать на уровне рефлексии, и то в случае если паттерн будет соответствовать некоторой конвенции по названиям классов в программе. Поддерживать такой код тоже достаточно неприятно.
Конечно есть случаи, когда такой подход имеет плюсы. Но если говорить обобщенно, то следует хорошо подумать и взвесить, а нужно ли такое делать.
Источник