Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Множественные вложенные IF-ы, как сделать код читабельным? 
:(
    Опции темы
_Y_
Дата 5.8.2012, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 5
Всего: 34



Вопрос по правильному кодописанию. Столкнулся с такой задачей. Имеется множество ветвящихся условий. То-есть многоуровневая система IF-ов вложенных друг в друга. Код, естественно, совершенно нечитаем.

Вопрос естественный - что же делать? Как код написать "красиво"? Кто как делает?

Сам я пока придумал только одно улучшение. Писать множество вложенных приватных методов с осмысленными названиями. В каждом - один IF с обращением в двух ветвях к двум следующим методам. Но  проблема в том, что, с одной стороны, не всегда такому вложенному методу можно дать осмысленное название, с другой, все время приходится пеедавать чертову уйму параметров. Да и вообще не бог весть какое хорошее решение.


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
leniviy
Дата 5.8.2012, 16:42 (ссылка)    | (голосов:4) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: нет
Всего: 5



1. сделай отступ 1 пробел
2. больше каментов
например, в конце большого блока, если он не умещается на странице, надо делать такой камент:
Код

if (1==1) {
...
} /* END if (1==1) */

3. делай "параграфы", "главы" выделяй их разным количеством пустых строк


Это сообщение отредактировал(а) leniviy - 5.8.2012, 16:44
PM MAIL   Вверх
_Y_
Дата 5.8.2012, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 5
Всего: 34



leniviy, спасибо, но это, вроде, само собой разумеется. 

Вопрос о вложенных IF  структурах, которые уже ни в какие рамки не лезут. Скажем так, если каждый вложеннй уровень сдвигать вправо должным количеством пробелов (как это всегда делается), то сам код уедет за правый край экрана, а в поле видимости останутся только IF-ы, скобки и масса пустого места smile  smile 


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
Cheloveck
Дата 5.8.2012, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: нет
Всего: 32



Роберт Мартин, "Чистый код" , глава 3

Цитата(leniviy @  5.8.2012,  17:42 Найти цитируемый пост)
1. сделай отступ 1 пробел
2. больше каментов
например, в конце большого блока, если он не умещается на странице, надо делать такой камент:
3. делай "параграфы", "главы" выделяй их разным количеством пустых строк

Это всё признаки гoвнокода!


Это сообщение отредактировал(а) Cheloveck - 5.8.2012, 18:05


--------------------
user posted image
PM Jabber   Вверх
Stolzen
Дата 5.8.2012, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1041
Регистрация: 17.10.2005

Репутация: 23
Всего: 48



А в чем проблема? Если вложенность больше 2 (3) - делаем extract method - самое лучшее решение.

Это сообщение отредактировал(а) Stolzen - 5.8.2012, 20:11


--------------------
datatalks.ru - анализ данных, статистика, машинное обучение
PM MAIL WWW   Вверх
_Y_
Дата 5.8.2012, 23:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 5
Всего: 34



Цитата(Stolzen @  5.8.2012,  20:10 Найти цитируемый пост)
extract method - самое лучшее решение.


Что такое extract method? Я не в курсе smile 


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
LSD
Дата 6.8.2012, 07:32 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(_Y_ @  6.8.2012,  00:42 Найти цитируемый пост)
Что такое extract method? Я не в курсе

Рефакторинг. К.О.
Разбивай метод на более простые и читабельные. Т.е. вместо одного метода с 10 if-ами, пусть лучше будет 10 маленьких методов с одним if-ом каждый. Опять же можно попробовать заменить if на switch. В любом случае универсального решения нет, надо смотреть по ситуации.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
jk1
Дата 6.8.2012, 09:43 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 40
Всего: 75



Иногда сложную условную логику удобно заменить полиморфизмом, ввести несколько стратегий. Особенно если условная логика идет по типам, вроде часто встречаемого

Код

if (mail instanceof MimeMessage){
    ...
}


Это сообщение отредактировал(а) jk1 - 6.8.2012, 09:43


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
baldina
Дата 6.8.2012, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



Цитата(_Y_ @  5.8.2012,  16:33 Найти цитируемый пост)
есть многоуровневая система IF-ов вложенных друг в друга

лучше от нее избавиться (см. выше).
насчет большого числа параметров: если параметр - массив или объект, он может быть один. или вообще без параметров, через контекст.
PM MAIL   Вверх
jManiak
Дата 6.8.2012, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 130
Регистрация: 6.2.2007
Где: Санкт-Петербург

Репутация: нет
Всего: 1



ЕСЛИ этот ветвящийся код описывает поведение одного объекта в зависимости от условий, то можно прибегнуть к одному из шаблонов проектирования: Strategy
Если нет, то либо что-то другое либо рефакторингом обходиться.
PM MAIL ICQ   Вверх
baldina
Дата 6.8.2012, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



Цитата(_Y_ @  5.8.2012,  16:33 Найти цитируемый пост)
Писать множество вложенных приватных методов с осмысленными названиями

на самом деле это хороший способ в простых случаях

Цитата(_Y_ @  5.8.2012,  16:33 Найти цитируемый пост)
не всегда такому вложенному методу можно дать осмысленное название

значит надо пересмотреть разделение на методы. осмысленному действию легче дать осмысленное название 
PM MAIL   Вверх
NoliX
Дата 10.8.2012, 13:45 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 103
Регистрация: 5.7.2005

Репутация: нет
Всего: 1



Очень помогает инвертировать условие:

Вместо:
Код

if (condition1){
  statements1;
  if (condition2){
    statements2;
  }
}


Код

if (!condition1){
  return;
}

statements1;
if (!condition2){
  return;
}
statements2


Код становится одноуровневым и читабельным.

If c else выносить в отдельный метод с возвращаемым значением:
Вместо:
Код

if (arg == null){
  System.out.print("something1")
} else {
  System.out.print("something2")
}


Код


System.out.print(resolveString(arg))
...

private static String resolveString(Object arg){
  retrun arg == null ? "something1" : "something2"
}

(Я упростил, естественно, в данном случае проще заменить на тернарный оператор, но суть примерно понятна)
Писать комментарии категорически не советую, особенно ерунду типа /* END if (1==1) */. Ни IDE, ни коллеги эти комметы поддерживать не будут, и через пару коммитов это станет неправдой + это вообще лишняя работа совершенно.


Это сообщение отредактировал(а) NoliX - 10.8.2012, 13:46
--------------------
Опыт - это учитель, который очень дорого берет за свои уроки
PM MAIL   Вверх
_Y_
Дата 14.8.2012, 23:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 5
Всего: 34



Спасибо. Подведу итого того, что понял.

Моя идея выносить каждый вложенный IF в отдельный метод была оценена как достойная. Даже умному назвнию  "extract method" Stolzen с LSD научили.

Полиморфизм, предложенный jk1 и jManiak я очень уважаю, а, в случае конечных автоматов, даже люблю. За высокий уровень инкапсуляции. Но здесь он "не окупится". Большинство классов будут имплементировать одну строчку кода.

Цитата(baldina @  6.8.2012,  11:00 Найти цитируемый пост)
если параметр - массив или объект, он может быть один. или вообще без параметров, через контекст. 

Это, конечно, не массив, но любые данные можно превратить в объект. А вот как делать через конекст я не знаю. Как это?

NoliX, IF-ы с return-ами я объединяю практически всегда, когда возможно. ИМХО такой код гораздо читабельнее. Но здесь этим не обойдешься.

...................

Собственно, наверное стОит объяснить задачу.

Имеем много полей ввода разных типов. Некоторые значения некоторых полей открывают дополнительные поля ввода. Довольно обычный высоконагруженный пользовательский интерфейс. А вот дальше начинаются сложности. Данные должны попасть в БД. Но, при этом, должны делаться проверки как введенных данных, так и уже имеющихся в базе. Т.е. данные и отношения между ними могут создавать новые записи, а могут и дополнять имеющиеся. При этом от самих данных зависит "чья возьмет". Т.е. данные в БД могут иметь больший или меньший приоритет по сравнению с тем, что ввел пользователь. Собственно, логика простая, но подразумевающая множество проверок, специфических для различных комбинаций данных..... Понятней, надо понимать не стало   smile 


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
korian
Дата 15.8.2012, 00:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: нет
Всего: 17



Давайт больше конкретики, тогда можно будет подумать.
Возможно есть смысл насоздавать новых объектов или еще чего.
PM   Вверх
baldina
Дата 15.8.2012, 10:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



Цитата(_Y_ @  14.8.2012,  23:55 Найти цитируемый пост)
любые данные можно превратить в объект. А вот как делать через конекст я не знаю. Как это?

данные объекта это и есть контекст

Цитата(_Y_ @  14.8.2012,  23:55 Найти цитируемый пост)
Имеем много полей ввода разных типов

Цитата(_Y_ @  14.8.2012,  23:55 Найти цитируемый пост)
Понятней, надо понимать не стало 

наоборот, стало. это имхо не if-ами должно решаться.
Цитата(_Y_ @  14.8.2012,  23:55 Найти цитируемый пост)
 данные и отношения между ними 

надо эти отношения переместить из кода в данные. тогда код будет обобщенный (без конкретной логики), короткий и понятный, а логика будет задаваться в данных. что-то похожее на конечный автомат с реакцией в узлах состояний.
если не очень понятно, позже подробней отпишусь
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0854 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.