Проблема
Есть задача при использовании switch у разных case выполнять еще и код из default (или например final реализовать), что бы не дублировать одинаковый код в разных кейсах.
switch ("b") {
case 'a':
case 'z':
case 'q':
echo "a
"; // not need run default action
break;
case 'b':
echo "b
"; // need run default case without case 'c'
break;
case 'c':
echo "c
";
default:
echo "default"; // need run for "b" & "c" cases
}
Выводит:
b
А хотелось бы:
b
default
Если убрать break у варианта b, то будет выполнен лишний код
b
c
default
Есть решение через goto, что является плохим стилем кодирования:
switch ("b") {
case 'a':
echo "a
";
break;
case 'b':
echo "b
";
goto caseFinal;
break;
case 'c':
echo "c
";
goto caseFinal;
break;
default:
caseFinal:
echo "default";
}
Полная задача
Есть массив полей разных сущностей и нужно разные действия у разных полей сделать.
switch ($fieldName) {
case 'id': // не нужно default
unset($properties['actions']['create']);
unset($properties['actions']['edit']);
break;
case 'content':
// одинаковый код нужно вынести в defaut
unset($properties['actions']['dashboard']);
// ...
break;
case 'isDeleted':
// одинаковый код нужно вынести в defaut
unset($properties['actions']['dashboard']);
// ...
break;
default:
// код нужне для всех остальных полей + кейсы выше
unset($properties['actions']['dashboard']);
}
Вопрос
Как это сделать без использования goto? Может есть вариант с другим подходом в архитектуре.
P.S. Если goto здесь уместен (лично я не боюсь динозавров), то почему это плохой стиль кодирования?
Ответ
После изучения ответов, статей и умозрительных эксперементов, пришел к выводу.
Вывод
В данном случае использование goto допустимо, пока не будет добавлена подобная конструкция в синтаксис switch и если соблюдаются условия:
Ты уже не Junior
Переходить можно только вперёд
Заходить в блоки и выходить категорически нельзя
Любой while и вложенные if так же опасны как goto. Для выхода из множественных циклов есть break N
Плюсы которые я вижу
Краткость и простота кода при соблюдении вышеописанных условиях
Меньше занимаемой памяти и скорее всего быстрота выполнения
Лучше "плохой тон", чем много избыточного кода, который сложнее поддерживать
Для себя я решил использовать только в группах исключающих условий:
switch ("b") {
case 'a':
echo "a
";
break;
case 'b':
echo "b
";
goto caseFinal;
break;
case 'c':
echo "c
";
goto caseFinal;
break;
default:
caseFinal:
echo "default";
}
Конечно при усложнении логики и увеличении строк кода, лучше всего воспользоваться ответом n4nn31355 и выносить в классы и отдельные методы, но внутри у них все равно наверно будет что-то похожее ;)
Интересные статьи на эту тему:
Запретный плод GOTO сладок
GOTO or not GOTO вот в чём вопрос
Комментариев нет:
Отправить комментарий