Pro kontrolu platnosti parametrů se využívají validační třídy z někerý Java frameworků, rád bych připomněl (z mého pohledu) ty nejvýznamnější:
- Validate z projektu Apache Commons
- Preconditions z projektu Google Common
- Assert z projektu Spring Framework
- Objects z Java 8 (metoda requireNonNull(), doplněno 2019-09-12)
Třídy se liší počtem i názvem veřejných metod, všechny (výše zmíněné) podporují zprávy pro výjimku, ale jen první dvě umožňují vkládání parametrů pomocí šablon pro rychlejší běh aplikace (finální zprávu lze sestavit až před vyhozením výjimky, zpravidla
IllegalArgumentException). Pokud však máte v oblibě framework pro logování událostí zvaný
LogBack, vznikne v projektu nekonzistence zápisu parametrů v šabloně, protože LogBack označuje pozici parametru v šabloně dvojicí složených závorek
"{}"
(na rozdíl od validátorů používajích zpravidla výraz
"%s"
). Této rozdílnosti se nezbavíme ani použitím třídy
Logger ze standardní Java knihovny, protože jeho šablona očekává číslovaný seznam parametrů podle vzoru
"{0} {1}"
. Také se mi nelíbí nejednotné vyhazování výjimek, protože první dvě implementace (výše zmíněné) vyhazují při porušení pravidla
not-null odlišnou výjimku (typu
NullPointerException). Přesto, že uvedené výhrady nejsou zásadní, po zvážení jsem přistoupil ke vlastní implementaci validátoru s plným vědomím rizika, že to nezpůsobí revoluci ve světě IT :-). Jako vzor pro inspiraci jsem použil třídu
Assert ze Spring frameworku, líbilo se mi, jak autoři obešli zápor v názvu metody pro testování parametru typu
not-empty. Nový validátor využívají (podle očekávání) ostatní moduly frameworku
Ujorm, třída zodpovědná za sestavování zpráv se využívá také pro interní proxy loggger.
Popis třídy Assert z frameworku Ujorm
Vlastnosti nové implementace:
- podporuje parametry v šabloně (na rozdíl od svého vzoru)
- pozice parametrů se označuje párem složených závorek
"{}"
, formátování hodnot parametrů není podporováno šablonou
- do zprávy se zapisují i parametry, které nemají vlastní značku v šabloně a jsou pak odděleny čárkou
- parametry typu Throwable, které nemají vlastní značku v šabloně vypisují stacktrace
- jsou podporované také argumenty typu Supplier (od verze 1.82+)
- podmínku platnosti parametru lze popsat Lambda výrazem
- při porušení platnosti se vyhazuje výhradně výjimka IllegalArgumentException
Uvádím vzorové použití, v komentáři najdete zprávu vyhozené výjimky:
Integer value = 20;
Assert.isTrue(value < 10, "Wrong number {}!", value); // "Wrong number 20!"
Assert.isTrue(value < 10, "Wrong", value); // "Wrong, 20"
Assert.isTrue(value < 10, value); // "20"
Assert.isTrue(value < 10); // null
value = null;
Assert.isTrue(value, (x)-> x<10, "Wrong number {}!", value); // "Wrong number null!"
Supplier<Object> s = () -> value;
Assert.isTrue(value < 10, "Wrong number {}!", s); // "Wrong number null!"
Všimněte si, že parametry postrádající svoji značku v šabloně se zapsaly na konec zprávy (například framework LogBack je zahazuje). Pokud je skutečný počet parametrů šablony naopak menší, nevyužité značky se zobrazí beze změny. Metody sice neřeší formátování parametrů, ale v případě nouze je možné parametry pro logování obalit vlastní třídou s překrytou metodou
toString()
, která to formátování řešit může. Pokud má parametr hodnotu
null
, tak nedochází k volání Lambda výrazu a není třeba to ošetřovat v kódu. Vzorové použití dalších metod uvádím pro zjednodušení bez kometářů, všechna tvrzení jsou pravdivá:
Assert.isTrue(true);
Assert.isTrue(30, (x)-> x>20);
Assert.notNull("ABC");
Assert.hasLength("ABC");
Assert.hasLength(new char[]{'A', 'B', 'C'});
Assert.hasLength(new StringBuilder().append("ABC"));
Assert.hasLength(Arrays.asList("A", "B", "C"));
Assert.isFalse(false);
Assert.isFalse(30, (x)-> x<20);
Assert.isNull (null);
Assert.isEmpty("");
Assert.isEmpty(new char[0]);
Assert.isEmpty(new StringBuilder());
Assert.isEmpty((List) null);
Performance testy vychází poměrně příznivě, pro zájemce přikládám odkaz na
jUnit testy třídy
Assert
, případně
na testy třídy
MsgFormatter
, která je zodpovědná za sestavování chybových zpráv. Pokud vás tento článek zaujal, knihovnu můžete připojit snadno pomocí Mavenu, velikost JAR je pouze 10 KB, modul přitom nemá žádné další závislosti.
<dependency>
<groupId>org.ujorm</groupId>
<artifactId>ujo-tools</artifactId>
<version>1.82</version>
</dependency>
Žádné komentáře:
Okomentovat