Definirei la pratica "esplicita dell'altro" a cui ti riferisci come anti-pattern, in quanto oscura il fatto che non esiste un codice di caso speciale come altro per il tuo if.
La leggibilità / manutenibilità è generalmente migliorata quando per lo più non hai altro che costrutti di flusso di codice necessari e li minimizzi. Ciò significa che gli altri ridondanti e gli if che aggiungono un ambito a un'intera funzione rendono più difficile seguirlo e mantenerlo.
Supponiamo che tu abbia questa funzione:
public void ConfigureOblogon(Oblogon oblogonToConfigure)
{
if (_validColors.Contains(oblogonToConfigure.Color))
{
oblogonToConfigure.ColorIndex = _validColors.IndexOf(oblogonToConfigure.Color);
}
else
{
oblogonToConfigure.Color = _validColors[0];
oblogonToConfigure.ColorIndex = 0;
}
}
Ora arriva il requisito che durante la configurazione dovresti anche specificare l'indice tipo / tipo dell'oblogon, ci sono più ambiti in cui qualcuno potrebbe inserire quel codice e finire con un codice non valido, ad es.
public void ConfigureOblogon(Oblogon oblogonToConfigure)
{
if (!_validOblogons.Contains(oblogonToConfigure.Type))
{
oblogonToConfigure.Type = _validOblogons[0];
oblogonToConfigure.TypeIndex = 0;
if (_validColors.Contains(oblogonToConfigure.Color))
{
oblogonToConfigure.ColorIndex = _validColors.IndexOf(oblogonToConfigure.Color);
}
else
{
oblogonToConfigure.Color = _validColors[0];
oblogonToConfigure.ColorIndex = 0;
}
}
else
{
oblogonToConfigure.TypeIndex = _validOblogons.IndexOf(oblogonToConfigure.Type);
}
}
Confronta questo con se il codice originale fosse scritto con costrutti di flusso di controllo minimi necessari e minimizzati a quello.
public void ConfigureOblogon(Oblogon oblogonToConfigure)
{
if (!_validColors.Contains(oblogonToConfigure.Color))
{
oblogonToConfigure.Color = _validColors[0];
}
oblogonToConfigure.ColorIndex = _validColors.IndexOf(oblogonToConfigure.Color);
}
Ora sarebbe molto più difficile mettere accidentalmente qualcosa nello scopo sbagliato o finire con gli scopi gonfiore che causano la duplicazione nella crescita e nel mantenimento a lungo termine di questa funzione. Inoltre è ovvio quali sono i possibili flussi attraverso questa funzione, quindi la leggibilità è migliorata.
Lo so, l'esempio è un po 'inventato, ma ho visto molte volte
SomeFunction()
{
if (isvalid)
{
/* ENTIRE FUNCTION */
}
/* Nothing should go here but something does on accident, and an invalid scenario is created. */
}
Quindi, formalizzare quelle regole sui costrutti del flusso di controllo, penso che possa aiutare le persone a sviluppare l'intuizione necessaria per annusare qualcosa quando iniziano a scrivere codice in quel modo. Quindi inizieranno a scrivere ..
SomeFunction()
{
if (!isvalid)
{
/* Nothing should go here, and it's so small no one will likely accidentally put something here */
return;
}
/* ENTIRE FUNCTION */
}
else
sembra falsa. Abbastanza spesso, semplicemente non c'è niente da mettere nelelse
blocco a meno che non ti pieghi all'indietro.