У мене є стан
if(exists && !isDirectory || !exists)
{}
як я можу це змінити, щоб воно було більш зрозумілим.
exists
і те і те isDirectory
й інше?
У мене є стан
if(exists && !isDirectory || !exists)
{}
як я можу це змінити, щоб воно було більш зрозумілим.
exists
і те і те isDirectory
й інше?
Відповіді:
||
комутативно, так
if(!exists || (exists && !isDirectory))
рівнозначний.
Тепер, оскільки існує завжди вірно, у другій частині ||
ви можете скинути &&
:
if(!exists || !isDirectory)
Або ви можете піти на крок далі і зробити:
if(!(exists && isDirectory))
&&
має більшу перевагу (принаймні, у більшості відомих мов - можуть бути винятки), ніж ||
. Таким чином a && b || c
, рівнозначно, (a && b) || c
але не a && (b || c)
.
!exists || !isDirectory
це більш «зрозумілим», тому що, isDirectory
не може бути правдою , якщо !exists
. Тож як людина ми скажемо "якщо її не існує, або вона [існує і вона] не є каталогом".
||
є лише комутативним, якщо використовується для значень без побічних ефектів - якщо, наприклад, використовується з функціями, деякі функції можуть не викликатися (коротке замикання) або повертати інше значення в іншому порядку.
В якості процесу я пропоную побудувати таблицю правдивості:
e = exists
d = isDirectory
e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0
Це відповідає NAND
операції , яка просто:
!(exists && isDirectory)
Якщо ви не пам'ятаєте всіх своїх логічних воріт, у wikipedia є гарне посилання на таблиці істинності для завантаження .
@Christoffer Hammarström підкреслив важливий момент про стан isDirectory
прив'язаності до держави exists
. Якщо припустити, що вони посилаються на ту саму посилання і що неможливо мати стан, коли посилання не існує і є каталогом, таблицю істинності можна записати так:
e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | n/a
1 | 0 | 1
1 | 1 | 0
n/a
Використовується для позначення стану , яке не має значення. Прийнятні скорочення можуть призвести до стану 1
або 0
до стану, що призведе до n/a
.
Зважаючи на це, !(exists && isDirectory)
все-таки є дійсним зменшення, що призводить до 1
отримання !e && d
.
Тим НЕ менше, !isDirectory
було б набагато простіше , скорочення, в результаті чого 0
для !e && d
.
isDirectory
залежить від цього exists
. Це не може бути і каталогом, і не існувати.
n/a
у місцях, де стан неможливо досягти, а рівняння відповідно зменшити.
Для кращої читабельності я люблю вилучати булеві умови методами:
if(fileNameUnused())
{...}
public boolean fileNameUnused() {
return exists && !isDirectory || !exists;
}
Або з кращою назвою методу. Якщо ви можете правильно назвати цей метод, читачеві вашого коду не потрібно з'ясовувати, що означає булева умова.
boolean fileNameUnused = !exists || !isDirectory; if (fileNameUnused) { doSomething(); }
Ви можете просто спробувати прибити непрохідні справи і рятувати , якщо це показує вгору.
while(someCondition) {
if(exists && isDirectory)
continue;
// maybe "break", depends on what you're after.
// the rest of the code
}
або навіть
function processFile(someFile)
{
// ...
if(exists && isDirectory)
return false;
// the rest of the code
// ...
}
Ви можете використовувати таблицю правдивості, як вказувалося. Другим кроком може стати KV-карта для мінімізації кількості термінів.
Використання законів булевої алгебри - ще один підхід:
A = існує
B =! IsDirectory
! A =! Існує
&& = *
|| = +
[Редагувати]
Простіше перетворення, оскільки операції І та АБО взаємно розподіляють:
існує &&! isDirectory || ! існує
= A * B +! A
= (A +! A) * (B +! A)
= 1 * (B +! A)
= B +! A
[/ редагувати]
існує &&! isDirectory || ! існує
= A * B +! A
= A * B +! A * 1 // Ідентичність
= A * B +! A * (B + 1) // Annihilator
= A * B +! A * B +! A / / Розповсюдження та ідентичність
= B * (A +! A) +! A // Розподільність
= B * 1 +! A // Доповнення 2
= B +! A // Ідентичність
=! IsDirectory || ! існує
Або з подвійним доповненням (!! x = x):
A * B +! A
= !! (A * B +! A)
=! (! (A * B) * A)
=! ((! A +! B) * A)
=! (! A * A + ! B * A)
=! (0 +! B * A)
=! (! B * A)
= B +! A
=! IsDirectory || ! існує
Я не люблю використовувати "!" коли в виразі є більше однієї умови. Я додаю рядки коду, щоб зробити його більш читабельним.
doesNotExist = !exists;
isFile = exists && !isDirecotry;
if (isFile || doesNotExist)
{}
Як було зазначено раніше, стан можна зменшити до:
if (!(exists && isDirectory))
Однак, я буду обділятися, що бути каталогом означає існування. Якщо так, ми можемо зменшити умову до:
if (!isDirectory)