Nazwałbym praktykę „wyraźne inaczej”, którą nazywacie anty-wzorcem, ponieważ przesłania fakt, że nie ma kodu specjalnego przypadku jako innego dla waszego if.
Czytelność / łatwość konserwacji jest ogólnie poprawiona, gdy przeważnie masz tylko niezbędne konstrukcje przepływu kodu i minimalizujesz je. Oznacza to nadmiarowe wady i if, które dodadzą zakres do całej funkcji, utrudniają śledzenie i utrzymanie jej.
Powiedz na przykład, że masz tę funkcję:
public void ConfigureOblogon(Oblogon oblogonToConfigure)
{
if (_validColors.Contains(oblogonToConfigure.Color))
{
oblogonToConfigure.ColorIndex = _validColors.IndexOf(oblogonToConfigure.Color);
}
else
{
oblogonToConfigure.Color = _validColors[0];
oblogonToConfigure.ColorIndex = 0;
}
}
Teraz pojawia się wymóg, że podczas konfiguracji należy również określić indeks typu / typu oblogon, istnieje wiele zakresów, w których ktoś może umieścić ten kod i skończyć z nieprawidłowym kodem, tj.
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);
}
}
Porównaj to z tym, czy oryginalny kod został napisany z minimalnymi potrzebnymi i minimalnymi konstrukcjami kontroli przepływu.
public void ConfigureOblogon(Oblogon oblogonToConfigure)
{
if (!_validColors.Contains(oblogonToConfigure.Color))
{
oblogonToConfigure.Color = _validColors[0];
}
oblogonToConfigure.ColorIndex = _validColors.IndexOf(oblogonToConfigure.Color);
}
Znacznie trudniej byłoby teraz przypadkowo umieścić coś w niewłaściwym zakresie lub skończyć rozdętymi zakresami, powodując dublowanie w długim okresie wzrostu i utrzymania tej funkcji. Ponadto jest oczywiste, jakie są możliwe przepływy przez tę funkcję, więc poprawiono czytelność.
Wiem, że ten przykład jest nieco wymyślony, ale wiele razy widziałem
SomeFunction()
{
if (isvalid)
{
/* ENTIRE FUNCTION */
}
/* Nothing should go here but something does on accident, and an invalid scenario is created. */
}
Dlatego sformalizowanie tych reguł dotyczących konstrukcji kontroli przepływu może pomóc ludziom rozwinąć intuicję niezbędną do wyczuwania czegoś, kiedy zaczną pisać kod w ten sposób. Wtedy zaczną pisać ...
SomeFunction()
{
if (!isvalid)
{
/* Nothing should go here, and it's so small no one will likely accidentally put something here */
return;
}
/* ENTIRE FUNCTION */
}
else
wydaje się nieprawdziwa. Dość często po prostu nie ma nic do włożenia welse
blok, chyba że się pochylisz.