SlideShare une entreprise Scribd logo
1  sur  31
Télécharger pour lire hors ligne
Usnadněte si práci

silně typovaným kódem 💪

a statickou analýzou! 🔎
Ondřej Mirtes
100 %
Code coverage
Jediný	dnes	uznávaný	způsob,	jak	mít	spolehlivou	aplikaci	bez	chyb,	je	100	%	pokrytí	testy.	
Žádná	reálná	aplikace	to	ovšem	nesplňuje	a	snažit	se	o	100	%	ani	nemá	ekonomický	smysl.
Business logika
Wiring
* nezměřeno vědeckou metodou
Jak	z	toho	ven?	Ne	všechny	zdrojáky	jsou	si	rovny	a	něco	se	vyplatí	testovat	víc	a	něco	míň.

Já	kód	rozděluji	na	business	logiku,	kterou	je	důležité	testovat,	a	wiring	(kterého	je	v	aplikaci	
nadpoloviční	většina*),	kde	testy	nepotřebujeme	a	spolehlivost	zajistíme	jinak.
Wiring	=	boilerplate.	
Controllery,	fasády,	
vytahování	výsledků	a	
přeposílání	jinam	-	do	
modelu,	do	šablony.	
Gettery,	settery,	
přiřazování	do	properties.	
Čím	složitější	architektura,	
tím	více	wiringu.
Business	logika	=	to	
důležité,	co	aplikace	
dělá.	Omezení	hodnot,	
validace,	filtrování	a	
řazení,	parsování,	
počítání,	
zaokrouhlování.	Mělo	
by	na	ni	jít	psát	rychlé	
unit	testy.
Wiring	se	dá	totiž	zažitými	postupy	testovat	pouze	integračně.	Integrační	testy	jsou	pomalé,	
křehké	a	nerad	je	píšu.	Pokud	bychom	na	wiring	psali	unit	testy,	tak	bychom	museli	psát	
spoustu	mocků	a	to	taky	není	ideální.	Testy	se	ale	u	wiringu	dají	nahradit	pořádnými	typy.
Stringly–typed code
function foo(string $id, string $name,
string $email, string $directory, 

string $filename, string $address, 

string $price, string $date
) { }
Pokud	někdo	nepíše	silně	typovaný	kód,	tak	to	vypadá	nějak	takhle.	Všechno	je	string,	
případně	jiné	skalární	typy.	Pokud	si	odmyslíme	typehinty	úplně,	může	nám	všude	dorazit	
null,	což	znamená	další	kontroly	a	možné	chyby	navíc.
Strongly–typed code
function foo(
Email $email,
SplFileInfo $directory,
Address $address,
Money $price,
DateTimeImmutable $date

): FooBar { }
Co	znamená	používat	silné	typy?	Využívat	na	všechno	co	nejpřesnější	typ,	objekt.	Co	tím	
získám?	Správný	objekt	může	vzniknout	jedině	konzistentní	a	zvalidovaný.	Typehintem	říkám,	
co	jedině	lze	do	metody	předat.	A	v	neposlední	řadě,	vím,	co	daný	objekt	dokáže,	pohledem	
na	jeho	metody.	A	nezapomeňme	na	co	nejpřesnější	return	typehinty.
Stringly–typed code
$container->get('fooService')->doFoo();
Za	stringy-typed	kód	nepovažuji	pouze	reprezentaci	všeho	jako	stringů,	ale	jakékoli	
odkazování	na	základě	magických	stringů.	Až	při	běhu	programu	můžu	zjistit,	že	požadovaná	
servisa	neexistuje.
Strongly–typed code
/** @var FooService */

private $fooService;

…
$this->fooService->doFoo();
Mnohem	lepší	je	vyžádat	si	servisu	přes	konstruktor	s	typehintem,	čímž	zajistím	a	informuji	
vývojáře/IDE/statický	analyzátor	o	tom,	co	v	daném	parametru	a	property	je.	Proto	rád	
používám	DI	i	v	controllerech,	protože	se	při	kompilaci	kontejneru	dozvím,	jestli	je	vše	OK.
Nadužívání polí
function foo(array $values) {
…

$values['name']
…
}
S	pořádnými	typehinty	nelze	metodu	zavolat	špatně,	ale	v	poli	vždy	může	chybět

důležitý	klíč.	A	taky	nevíme	typy	hodnot	jednotlivých	klíčů	(pokud	se	mezi	sebou	liší).
Pole jako seznam hodnot ✅
/**

* @param User[] $users
*/
function foo(array $users)
{
foreach ($users as $user) { }
}
Použít	pole	jako	kolekci	hodnot	stejného	typu,	nad	kterou	iteruji,	je	v	pořádku.	V	této	ukázce	
si	mohu	být	jistý	tím,	co	bude	v	$user.
"Umím zpracovat cokoli"
/**

* @param array|string $values
*/
function foo($values) {
if (is_array($values)) {
…
} else {
…
}
}
Metoda,	co	přijímá	více	různých	typů,	znamená,	že	musíme	napsat	if	-	složitější	kód,	více	
větví	k	testování.
function foo(array $values) {
…
}
function bar(string $value) {
…
}
"Umím zpracovat jeden typ"
Přitom	můžeme	napsat	dvě	funkce,	které	přijímají	konkrétní	typ	a	z	každého	místa	zavolat	tu	
správnou.	To	samé	platí	pro	návratové	typy	-	vždy	vracet	jeden	konkrétní	typ.
Boolean parametery
function foo($values, bool $force) {
if ($force) {
…
} else {
…
}
}
Boolean	parametr	většinou	znamená,	že	metoda	dělá	trochu	něco	jiného.	Opět	znamená	
napsat	if	a	více	větví	k	testování.
Boolean parametery
foo([1, 2, 3], false);
foo([1, 2, 3], true);
foo([1, 2, 3]);
forceFoo([1, 2, 3]);
Rozdělení na více metod
Správné	řešení	namísto	boolean	parametru	je	opět	rozdělit	na	více	metod	a	z	různých	míst	
zavolat	tu	správnou,	co	potřebuji.
Nullable parametry
function foo($a = null, $b = null,

$c = null, $d = null, $e = null,

$f = null, $g = null
) { }
U	metod	s	větším	množstvím	nullable	či	nepovinných	argumentů	většinou	platí	jen	některé	
kombinace,	např.	první	tři	parametry	nenulové	spolu	apod.	To	není	nijak	zanesené	do	
typového	systému	a	navíc	tyto	kombinace	obvykle	vyjadřují	různé	use	casy.	Řešení	-	
rozdělení	na	více	metod	bez	nullable	parametrů.	Výsledek	-	mnohem	robustnější	kód.
function foo(
string $country,
string $currency,
string $errorCode
)
Výčty – enumy
Pokud	nějaký	parametr	přijímá	omezený	obor	hodnot,	který	je	pevně	daný	v	kódu	aplikace,	
použití	skalárních	typů	není	vhodné,	protože	hodnotu	nijak	neomezují.
Výčty – enumy
github.com/consistence/consistence
function foo(
Country $country,
Currency $currency,
ErrorCode $errorCode
)
Reprezentujte	výčty	pomocí	objektů,	např.	skrze	knihovnu	Consistence.	Vyjádříte	tím,	co	
volající	musí	do	metody	předat,	a	zajistíte	validitu	předané	hodnoty.
Controller
Weak
HTTP request
Strong
ModelControllerHTTP response
Pokud	necháte	typy	prorůst	vaší	aplikací,	bude	celá	daleko	spolehlivější,	protože	budete	co	
nejmíň	věcí	mít	"mixed".	Typy	jsou	i	důvod,	proč	rád	používám	ORM.
Zpětná vazba od typů
Nevhodné interfaces
Naimplementovat	interface	a	u	půlky	metod	vyhazovat	výjimku	-	porušení	Barbary	Liskov,	
nevhodný	interface.	Musíme	naslouchat,	jaký	nám	kód	dává	feedback	o	našich	typech.	
Pořádný	typový	systém	je	nemilosrdnější	než	testy,	hodnotí,	co	vše	lze	někam	předat,	nejen	
to,	jaké	vstupy	jsme	otestovali.
Zpětná vazba od typů
Využívání informace,
která není v typech
Pokud	něco	není	zanesené	do	typů	a	jen	díky	předchozí	kontrole	či	proprietárním	znalostem	
vím,	že	mi	z	volané	metody	přijde	nějaká	konkrétní	třída,	která	není	v	typehintu.
Statická analýza 🔎
Statický	analýza	hledá	chyby	v	kódu,	aniž	by	ho	spouštěla,	pouze	zkoumáním	zdrojáků.	
Zkontroluje,	že	aplikace	nespadne	na	něčem	nedefinovaném,	že	všude	předávám	správné	
typy,	že	vracím,	co	jsem	slíbil	atd.
composer require --dev phpstan/phpstan
github.com/phpstan/phpstan
První spuštění
• Parse errory
• Třídy, které nejdou vůbec načíst
• Špatně nastavený autoloading
Projekt,	který	je	již	nějakou	dobu	vyvíjen	bez	statické	analýzy,	naakumuluje	soubory,	které	
třeba	ani	nejdou	načíst,	takže	se	nedivte,	když	takové	PHPStan	u	vás	najde.
Levely v PHPStanu
$%&'()
Abych	omezil	množství	chyb,	které	PHPStan	po	nainstalování	začne	hlásit,	zavedl	jsem	umělé	
levely.	Začněte	ho	používat	na	levelu	0	a	opravte	těch	pár	chyb,	abyste	měli	zelený	build.	A	až	
budete	mít	příště	čas,	navyšte	level	a	opravte	další	chyby.
if ($foo instanceof Foo)
catch (FooException $e)
Foo::class
function foo(Bar $bar)
PHP	samotnému	nevadí,	pokud	se	v	těchto	případech	odkazujete	na	neexistující	třídy.	
PHPStan	takové	případy	najde	a	donutí	vás	je	opravit.
Foo::NONEXISTENT_CONSTANT
Foo::$nonexistentProperty
$this->nonexistentProperty
$this->nonexistentMethod()
nonexistentFunction()
Na vyšších levelech
• Nejen na $this
• Předávané typy, nejen počty
• Návratové hodnoty
• Nedefinované proměnné
• …a řada dalších kontrol
PHPStan	na	levelu	0	hledá	chyby	na	statických	voláních	a	na	$this.	Tam	si	může	být	jistý	
typem.	Na	vyšších	levelech	hledá	chyby	na	všem,	ale	už	při	tom	musí	číst	a	spoléhat	se

na	phpDocy,	ve	kterých	může	být	také	chyba,	kterou	vám	ochotně	nahlásí.
vs. PHPStan?
Proč	používat	PHPStan,	když	mám	PhpStorm?	PHPStan	byste	měli	integrovat	a	pouštět	v	
rámci	CI	buildu	(Travis,	TeamCity,	Jenkins,	GitLab	CI…).	Ne	všichni	vývojáři	používají	PhpStorm	
a	mají	ho	stejně	nakonfigurovaný,	a	nevšimnou	si	každé	chyby,	co	IDE	podtrhne.
youtu.be/h5jC7l0-jRI👉
Pro	více	informací	o	PHPStanu,	co	všechno	umí	a	jaké	možnosti	konfigurace	a	rozšíření	skýtá,	
mrkněte	na	záznam	z	Poslední	soboty.
phpstan/phpstan
@OndrejMirtes
ondrej.mirtes.cz

Contenu connexe

Similaire à Ondřej Mirtes: Usnadněte si práci silně typovaným kódem a statickou analýzou!

MS Awards Brozura 2015 210x210 R7 LR
MS Awards Brozura 2015 210x210 R7 LRMS Awards Brozura 2015 210x210 R7 LR
MS Awards Brozura 2015 210x210 R7 LR
Jaromir Sponar
 
Zkušenosti s využitím Cloud Computingu ve výuce
Zkušenosti s využitím Cloud Computingu ve výuceZkušenosti s využitím Cloud Computingu ve výuce
Zkušenosti s využitím Cloud Computingu ve výuce
KISK FF MU
 
Interpretace výsledků penetračních testů (Karel Miko)
Interpretace výsledků penetračních testů (Karel Miko)Interpretace výsledků penetračních testů (Karel Miko)
Interpretace výsledků penetračních testů (Karel Miko)
DCIT, a.s.
 
Krev net a_slzy
Krev net a_slzyKrev net a_slzy
Krev net a_slzy
Etnetera
 
Caleum firemni profil
Caleum firemni profilCaleum firemni profil
Caleum firemni profil
Josef Ladra
 
Katalog - 120 vteřIn pro inovativní firmy - 1.6.2011
Katalog - 120 vteřIn pro inovativní firmy - 1.6.2011Katalog - 120 vteřIn pro inovativní firmy - 1.6.2011
Katalog - 120 vteřIn pro inovativní firmy - 1.6.2011
jindrichweiss
 

Similaire à Ondřej Mirtes: Usnadněte si práci silně typovaným kódem a statickou analýzou! (20)

Semináře M-Files: Konec hledání řešení pro správu firemních dat
Semináře M-Files: Konec hledání řešení pro správu firemních datSemináře M-Files: Konec hledání řešení pro správu firemních dat
Semináře M-Files: Konec hledání řešení pro správu firemních dat
 
Prezentace Pharma 2014 - Nemáte nebo nechcete vlastní IT?
Prezentace Pharma 2014 - Nemáte nebo nechcete vlastní IT?Prezentace Pharma 2014 - Nemáte nebo nechcete vlastní IT?
Prezentace Pharma 2014 - Nemáte nebo nechcete vlastní IT?
 
2019 09-23-snidane qa-public
2019 09-23-snidane qa-public2019 09-23-snidane qa-public
2019 09-23-snidane qa-public
 
Office 365 představení
Office 365 představeníOffice 365 představení
Office 365 představení
 
MS Awards Brozura 2015 210x210 R7 LR
MS Awards Brozura 2015 210x210 R7 LRMS Awards Brozura 2015 210x210 R7 LR
MS Awards Brozura 2015 210x210 R7 LR
 
Kefer
KeferKefer
Kefer
 
Citrix Story
Citrix StoryCitrix Story
Citrix Story
 
IoT – používáme posbíraná data správně?
IoT – používáme posbíraná data správně?IoT – používáme posbíraná data správně?
IoT – používáme posbíraná data správně?
 
Zkušenosti s využitím Cloud Computingu ve výuce
Zkušenosti s využitím Cloud Computingu ve výuceZkušenosti s využitím Cloud Computingu ve výuce
Zkušenosti s využitím Cloud Computingu ve výuce
 
Pořídit hotové řešení nebo si nechat vyrobit vlastní?
Pořídit hotové řešení nebo si nechat vyrobit vlastní? Pořídit hotové řešení nebo si nechat vyrobit vlastní?
Pořídit hotové řešení nebo si nechat vyrobit vlastní?
 
Interpretace výsledků penetračních testů (Karel Miko)
Interpretace výsledků penetračních testů (Karel Miko)Interpretace výsledků penetračních testů (Karel Miko)
Interpretace výsledků penetračních testů (Karel Miko)
 
Krev net a_slzy
Krev net a_slzyKrev net a_slzy
Krev net a_slzy
 
Caleum firemni profil
Caleum firemni profilCaleum firemni profil
Caleum firemni profil
 
Moderní principy aplikační bezpečnosti
Moderní principy aplikační bezpečnostiModerní principy aplikační bezpečnosti
Moderní principy aplikační bezpečnosti
 
Katalog - 120 vteřIn pro inovativní firmy - 1.6.2011
Katalog - 120 vteřIn pro inovativní firmy - 1.6.2011Katalog - 120 vteřIn pro inovativní firmy - 1.6.2011
Katalog - 120 vteřIn pro inovativní firmy - 1.6.2011
 
Microservices - morning talk
Microservices -  morning talkMicroservices -  morning talk
Microservices - morning talk
 
Bezpečnost pro vaše data s minimem úsilí
Bezpečnost pro vaše data s minimem úsilíBezpečnost pro vaše data s minimem úsilí
Bezpečnost pro vaše data s minimem úsilí
 
BIM-Fórum 2015 – Projektování TZB v Revitu
BIM-Fórum 2015 – Projektování TZB v RevituBIM-Fórum 2015 – Projektování TZB v Revitu
BIM-Fórum 2015 – Projektování TZB v Revitu
 
Progress Is
Progress IsProgress Is
Progress Is
 
Agilní architektura
Agilní architekturaAgilní architektura
Agilní architektura
 

Plus de Develcz

Martin Hassman: Jak se tvoří addony pro World of Warcraft
Martin Hassman: Jak se tvoří addony pro World of WarcraftMartin Hassman: Jak se tvoří addony pro World of Warcraft
Martin Hassman: Jak se tvoří addony pro World of Warcraft
Develcz
 

Plus de Develcz (20)

Daniel Steigerwald: WYSIWYG je šik! (když funguje)
Daniel Steigerwald: WYSIWYG je šik! (když funguje)Daniel Steigerwald: WYSIWYG je šik! (když funguje)
Daniel Steigerwald: WYSIWYG je šik! (když funguje)
 
Ondřej Hlaváček: Životní cyklus featury
Ondřej Hlaváček: Životní cyklus featuryOndřej Hlaváček: Životní cyklus featury
Ondřej Hlaváček: Životní cyklus featury
 
Martin Hassman: Jak se tvoří addony pro World of Warcraft
Martin Hassman: Jak se tvoří addony pro World of WarcraftMartin Hassman: Jak se tvoří addony pro World of Warcraft
Martin Hassman: Jak se tvoří addony pro World of Warcraft
 
Ondřej Voves: Jak přepsat monolit do mikroslužeb
Ondřej Voves: Jak přepsat monolit do mikroslužebOndřej Voves: Jak přepsat monolit do mikroslužeb
Ondřej Voves: Jak přepsat monolit do mikroslužeb
 
Marcel Šulek: Zpraste svoje kódy
Marcel Šulek: Zpraste svoje kódyMarcel Šulek: Zpraste svoje kódy
Marcel Šulek: Zpraste svoje kódy
 
Michal Illich: Vývojáři staví letadlo
Michal Illich: Vývojáři staví letadloMichal Illich: Vývojáři staví letadlo
Michal Illich: Vývojáři staví letadlo
 
Ondřej Kokeš: Zpracování dat z veřejných zdrojů
Ondřej Kokeš: Zpracování dat z veřejných zdrojůOndřej Kokeš: Zpracování dat z veřejných zdrojů
Ondřej Kokeš: Zpracování dat z veřejných zdrojů
 
Patrick Zandl: Open source software, hardware, 3D tiskárny a tvrdý business -...
Patrick Zandl: Open source software, hardware, 3D tiskárny a tvrdý business -...Patrick Zandl: Open source software, hardware, 3D tiskárny a tvrdý business -...
Patrick Zandl: Open source software, hardware, 3D tiskárny a tvrdý business -...
 
Štěpán Bechynský: Hardware pro IoT projekty nejen pro hobby, ale i pro průmysl
Štěpán Bechynský: Hardware pro IoT projekty nejen pro hobby, ale i pro průmyslŠtěpán Bechynský: Hardware pro IoT projekty nejen pro hobby, ale i pro průmysl
Štěpán Bechynský: Hardware pro IoT projekty nejen pro hobby, ale i pro průmysl
 
Tomáš Vondra: Paralelizace dotazu a partitioning v PostgreSQL
Tomáš Vondra: Paralelizace dotazu a partitioning v PostgreSQLTomáš Vondra: Paralelizace dotazu a partitioning v PostgreSQL
Tomáš Vondra: Paralelizace dotazu a partitioning v PostgreSQL
 
Tomáš Zvěřina: Flutter.io - multiplatformní vývoj mobilních aplikací
Tomáš Zvěřina: Flutter.io - multiplatformní vývoj mobilních aplikacíTomáš Zvěřina: Flutter.io - multiplatformní vývoj mobilních aplikací
Tomáš Zvěřina: Flutter.io - multiplatformní vývoj mobilních aplikací
 
Jakub Vrána: Dokazatelná bezpečnost
Jakub Vrána: Dokazatelná bezpečnostJakub Vrána: Dokazatelná bezpečnost
Jakub Vrána: Dokazatelná bezpečnost
 
Roman Schejbal: From Madness To Reason
Roman Schejbal: From Madness To ReasonRoman Schejbal: From Madness To Reason
Roman Schejbal: From Madness To Reason
 
Michal Illich: Zuri aneb Vývojáři staví letadlo
Michal Illich: Zuri aneb Vývojáři staví letadloMichal Illich: Zuri aneb Vývojáři staví letadlo
Michal Illich: Zuri aneb Vývojáři staví letadlo
 
Ondřej Šika: Docker, Traefik a CI - Mějte nasazené všeny větve na kterých pra...
Ondřej Šika: Docker, Traefik a CI - Mějte nasazené všeny větve na kterých pra...Ondřej Šika: Docker, Traefik a CI - Mějte nasazené všeny větve na kterých pra...
Ondřej Šika: Docker, Traefik a CI - Mějte nasazené všeny větve na kterých pra...
 
David Majda: Autoformátování kódu
David Majda: Autoformátování kóduDavid Majda: Autoformátování kódu
David Majda: Autoformátování kódu
 
David Grudl: Open source: The Good, the Bad and the Ugly
David Grudl: Open source: The Good, the Bad and the UglyDavid Grudl: Open source: The Good, the Bad and the Ugly
David Grudl: Open source: The Good, the Bad and the Ugly
 
Ondřej Machulda: Začíná zlatá doba end-to-end testů!
Ondřej Machulda: Začíná zlatá doba end-to-end testů!Ondřej Machulda: Začíná zlatá doba end-to-end testů!
Ondřej Machulda: Začíná zlatá doba end-to-end testů!
 
Adam Kudrna: Headless WordPress/Drupal
Adam Kudrna: Headless WordPress/DrupalAdam Kudrna: Headless WordPress/Drupal
Adam Kudrna: Headless WordPress/Drupal
 
Jaroslav Tulach: GraalVM - z vývoje nejrychlejšího virtuálního stroje na světě
Jaroslav Tulach: GraalVM - z vývoje nejrychlejšího virtuálního stroje na světěJaroslav Tulach: GraalVM - z vývoje nejrychlejšího virtuálního stroje na světě
Jaroslav Tulach: GraalVM - z vývoje nejrychlejšího virtuálního stroje na světě
 

Ondřej Mirtes: Usnadněte si práci silně typovaným kódem a statickou analýzou!