Jste zde

Ještě jednou a lépe: zjišťování (ne)prázdnosti vráceného kontejneru

V příspěvku se podíváme na vhodnější alternativu za kód stylu if (obj->getItems().size() > 0) či if (!obj->getItems().empty()).

Původní kód

Dejme tomu, že máme třídu Directory, která má metodu getSubdirectories(). Ta vrátí seznam podadresářů. Dále mějme nějaký konkrétní adresář:

Directory *dir = new Directory("/path/to/directory");

Chcete pak v kódu zjistit, zda má daný adresář podadresáře. Obvykle vídávám jeden z takovýchto kódů:

if (dir->getSubdirectories().size() > 0)
if (dir->getSubdirectories().size() >= 1)
if (dir->getSubdirectories().size() != 0)
if (!dir->getSubdirectories().empty())

Proč takto raději ne?

Z několika důvodů:

  • Čitelnost. Abyste pochopili záměr kódu, musíte jej analyzovat. Nejdříve se získají všechny podadresáře. Pak se na podadresářích volá size(), což by mělo získat jejich počet. Ten se pak porovná s danou konstantou. Výsledkem je, že se if provede, pokud je velikost nenulová. Kód s empty() je na tom o něco lépe, ale i tak je tam ono získávání všech podadresářů. Navíc je tam pak negace, která pochopení opět ztíží.
  • Duplicitní kód. Podobných kontrol budete mít v kódu více. Na každém místě musíte zopakovat tentýž kód, tedy získání podadresářů a zjištění jejich velikosti.
  • Výkonnost. V případě, kdy getSubdirectories() vrací výsledný kontejner hodnotou, tak se musí zkopírovat, jenom aby se na něm zavolalo size() či empty(). Výsledná kopie se pak ihned zahodí. To může být zbytečně neefektivní.
  • Spoléhání se na implementaci. V ono kódu se spoléháte na to, že navrácený objekt má metodu size() či empty(). Pokud se změní implementace, máte problém. V neposlední řadě se jedná o porušení Deméteřina zákona.

Mimochodem, tento příklad ilustruje porušení principu Tell, don't ask, o kterém jsem psal nedávno.

Jak to udělat lépe?

Přidejte do třídy Directory metodu hasSubdirectories(). Kód uživatelů této třídy pak bude vypadat takto:

if (dir->hasSubdirectories())

Nádhera. Čitelné, jasné, krásné. Přesně tak, jak to mám rád.

Přidat komentář