Есть такое правило для читабельности кода: надо писать так, как ты бы сказал естественным языком. Т.е. если ты не можешь сформулировать русским языком, что та или иная часть кода должна сделать, то и браться писать не надо -- даже если заработает, наверняка будет не самым естественным образом.
В твоем случае, если бы тебя спросили, что ты хочешь получить данным куском кода, то ты, наверное, сказал бы что-то вроде: "хочу получить условие того, что данный элемент selected, т.е. true в том случае, если а) не указано явно, что он deselected, И б) либо явно указано, что он selected, либо его parent selected". Т.е. "более читаемый" код -- второй, который можно еще переписать так (сделав акцент на "важности" и приоритете deselected по сравнению с selected):
!deselected && (selected || parent_selected)
Кстати, когда формулируешь естественным языком сразу всплывают "подводные камни". Например, а что если указаны оба deselected и selected, при такой формулировке предпочтение явным образом отдается deselected, или, например, а как понимать parent_selected -- это parent.selected или для parent применяется аналогичное правило? Возможно, что у тебя переизбыточное использование состояний-переменных, а может и нет -- может оно тебе так надо. Но это все детали твоей разработки, и к поставленному вопросу прямого отношения не имеет.
Здравствуйте, vadimcher, Вы писали:
V>Есть такое правило для читабельности кода: надо писать так, как ты бы сказал естественным языком. Т.е. если ты не можешь сформулировать русским языком, что та или иная часть кода должна сделать, то и браться писать не надо -- даже если заработает, наверняка будет не самым естественным образом.
V>В твоем случае, если бы тебя спросили, что ты хочешь получить данным куском кода, то ты, наверное, сказал бы что-то вроде: "хочу получить условие того, что данный элемент selected, т.е. true в том случае, если а) не указано явно, что он deselected, И б) либо явно указано, что он selected, либо его parent selected". Т.е. "более читаемый" код -- второй, который можно еще переписать так (сделав акцент на "важности" и приоритете deselected по сравнению с selected): V>
V>!deselected && (selected || parent_selected)
V>
Необязательно такая трактовка.
Значение "выбранность" данного элемента
1. определяется флагами selected и deselected*
2. либо наследуется от родителя (значение parent_selected)
*) если оба флага взведены, то приоритет отдаётся deselected
Естественная логика, хорошо известная, например, по CSS.
И безо всяких юридически крючкотворств "если явно не указано обратное".
V>Кстати, когда формулируешь естественным языком сразу всплывают "подводные камни". Например, а что если указаны оба deselected и selected, при такой формулировке предпочтение явным образом отдается deselected, или, например, а как понимать parent_selected -- это parent.selected или для parent применяется аналогичное правило? Возможно, что у тебя переизбыточное использование состояний-переменных, а может и нет -- может оно тебе так надо. Но это все детали твоей разработки, и к поставленному вопросу прямого отношения не имеет.
Из человеческого описания, приведённого мной, это становится очевидно.
Как и всякие мелкие штрихи и баги дизайна.
1) избыточность и противоречивость флагов — из-за которых приходится так или иначе разруливать конфликт
— отдавать приоритет флагу deselected
— игнорировать оба флага и переходить к наследованию
— трактовать как ошибку (и, например, кинуть исключение)
2) смешивание двух типов "булевы флаги" и "булево значение" — откуда и возникает желание написать оптимизированную булеву функцию (причём в зависимости от способа разруливания конфликта она будет разной).
Кардинальное решение — ввести трёхзначный флаг "selected/deselected/inherit".
Но не факт, что предметная область это позволяет. Если там уже гвоздями прибито, что флаг кодируется двумя битами — никуда от запрешённой комбинации не деться. Может быть, валидировать на самой ранней стадии, не доводя до данного момента?
V>Голосую за второй вариант.
Голосую за первый вариант, как более ясно выражающий исходное намерение (пусть и кривовато).
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, vadimcher, Вы писали:
V>>Есть такое правило для читабельности кода: надо писать так, как ты бы сказал естественным языком. Т.е. если ты не можешь сформулировать русским языком, что та или иная часть кода должна сделать, то и браться писать не надо -- даже если заработает, наверняка будет не самым естественным образом.
V>>В твоем случае, если бы тебя спросили, что ты хочешь получить данным куском кода, то ты, наверное, сказал бы что-то вроде: "хочу получить условие того, что данный элемент selected, т.е. true в том случае, если а) не указано явно, что он deselected, И б) либо явно указано, что он selected, либо его parent selected". Т.е. "более читаемый" код -- второй, который можно еще переписать так (сделав акцент на "важности" и приоритете deselected по сравнению с selected): V>>
Так вот в том-то и дело, что плясать надо не от кода как таково-го, а от трактовки. Мысль была именно в этом.
К>Кардинальное решение — ввести трёхзначный флаг "selected/deselected/inherit".
Исходное выражение можно обобщить следующим образом: Selected && !Deselected; то, что Selected в нашем случае означает selected || parent_selected, а Deselected всего лишь deselected, а не deselected || parent_deselected, просто отражает тот фает, что deselection в отличие от selection не наследуется. На то, будет ли понятнее, если написать сначала Selected, потом Deselected, а не наоборот, наследование одного и ненаследование другого никак не влияют. То есть сравниваем следующие два способа записи:
Selected && !Deselected
и
!Deselected && Selected
Не вижу преимуществ ни у одного из них, но на естественный язык первый по-моему переводится понятнее, поскольку deselection эффективно применяется только к тем элементам (объектам, сущностям), к которым уже была применена selection, то есть deselection в этом смысле вторична. Во втором же (твоем) варианте читать приходится начиная с этой самой вторичной deselection. То есть как бы, еще и не selected ничего, а мы уже проверяем, не применить ли к нему deselection.
Тем не менее, во избежание недоразумений, еще раз: в общем случае оба варианта одинаково понятны.
Я за такой и только такой вариант, а основывается этот вариант на правиле, что в дебаге мы проводим долше чем в релизе
а тут можно проще раставить бряки для разных ситуаций