Date post: | 22-Jan-2018 |
Category: |
Software |
Upload: | konference-phplive |
View: | 390 times |
Download: | 2 times |
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
github.com/DusanKasan
twitter.com/DusanKasan
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
github.com/DusanKasan
twitter.com/DusanKasan
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
github.com/DusanKasan
twitter.com/DusanKasan
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
O com to bude?• Aký máme problém?
• Čo sú kolekcie
• Kolekcie v PHP
• Práca s kolekciami
• Funkcionálny prístup v PHP
• Otázky
Problém | Kolekcie | PHP | Ukážky | FP
ˇ
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Aký máme problém?
Problém | Kolekcie | PHP | Ukážky | FP
$likedPosts = [];foreach ($users as $user) { if ($user['verified']) { $userId = $user['id']; foreach ($user['posts'] as $post) { if (count($post['likes'])) { $likedPosts[$userId][] = $post; } } }}
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Aký máme problém?
Problém | Kolekcie | PHP | Ukážky | FP
$likedPosts = [];foreach ($users as $user) { if ($user['verified']) { $userId = $user['id']; foreach ($user['posts'] as $post) { if (count($post['likes'])) { $likedPosts[$userId][] = $post; } } }} 4 úrovne odsadenia
ťažšie na pochopenie
kandidát na refaktoring
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Refaktoring - viac funkcií?
Problém | Kolekcie | PHP | Ukážky | FP
$likedPosts = [];foreach ($users as $user) { if ($user['verified']) { $userId = $user['id']; foreach ($user['posts'] as $post) { if (count($post['likes'])) { $likedPosts[$userId][] = $post; } } }} private function getLikedPosts(array $posts)
{ $likedPosts = []; foreach ($posts as $post) { if (count($post['likes'])) { $likedPosts[] = $post; } } return $likedPosts; }
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Refaktoring - viac funkcií?
Problém | Kolekcie | PHP | Ukážky | FP
$likedPosts = [];foreach ($users as $user) { $likedPosts = $this->getLikedPosts($user['posts']); if ($user['verified'] && count($likedPosts)) { $likedPosts[$user['id']] = $likedPosts; }}
• “OK” riešenie
• Meno čiastkových funkcií nesie dostatočný význam
• Pre úplné pochopenie treba skákať medzi funkciami
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Refaktoring - built-in array funkcie?
Problém | Kolekcie | PHP | Ukážky | FP
$indexedUsers = [];foreach ($users as $user) { $indexedUsers[$user['id']] = $user; }$verifiedUsers = array_filter( $indexedUsers, function ($user) { return $user['verified']; });
$likedPosts = array_map( function($verifiedUser) { return array_filter( $verifiedUser['posts'], function($post) {return count($post['likes']);} ); }, $verifiedUsers);
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Refaktoring - built-in array funkcie?
Problém | Kolekcie | PHP | Ukážky | FP
To je hnus
velebnosti,
já jdu blejt.
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Refaktoring - built-in array funkcie?
Problém | Kolekcie | PHP | Ukážky | FP
$indexedUsers = [];foreach ($users as $user) { $indexedUsers[$user['id']] = $user; }$verifiedUsers = array_filter( $indexedUsers, function ($user) { return $user['verified']; });
$likedPosts = array_map( function($verifiedUser) { return array_filter( $verifiedUser['posts'], function($post) {return count($post['likes']);} ); }, $verifiedUsers);
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Kolekcie
Problém | Kolekcie | PHP | Ukážky | FP
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Kolekcie
Problém | Kolekcie | PHP | Ukážky | FP
• Čo je kolekcia?
• Skupina prvkov, resp. dvojíc kľúč - hodnota
• Collection pipeline
• Návrhový vzor
• Sekvenčné spájanie operácií nad kolekciou
• Operácie napr.: filter, map alebo reduce
• Bežný pri FP, ale aj v OO jazykoch, ktoré majú lambdy
• Výhody?
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Kolekcie - funkcie
Problém | Kolekcie | PHP | Ukážky | FP
append, combine, concat, contains, countBy, cycle, diff, distinct,
drop, dropLast, dropWhile, each, every, except, extract, filter, find,
first, flatten, flip, frequencies, get, getOrDefault, groupBy,
groupByKey, has, indexBy, interleave, interpose, intersect, isEmpty,
isNotEmpty, keys, last, map, mapcat, only, partition, partitionBy,
prepend, realize, reduce, reduceRight, reductions, reject, replace,
reverse, second, shuffle, size, slice, some, sort, splitAt, splitWith,
take, takeNth, takeWhile, transform, toArray, zip,
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Refaktoring - Kolekcie
Problém | Kolekcie | PHP | Ukážky | FP
$likedPosts = [];foreach ($users as $user) { if ($user['verified']) { $userId = $user['id']; foreach ($user['posts'] as $post) { if (count($post['likes'])) { $likedPosts[$userId][] = $post; } } }}
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Refaktoring - Kolekcie
Problém | Kolekcie | PHP | Ukážky | FP
$likedPosts = [];foreach ($users as $user) { if ($user['verified']) { $userId = $user['id']; foreach ($user['posts'] as $post) { if (count($post['likes'])) { $likedPosts[$userId][] = $post; } } }}
$likedPosts = Collection::from($users) ->filter(function ($user) {return $user['verified'];}) ->indexBy(function($user) {return $user['id'];}) ->map(function($user) { return Collection::from($user['posts']) ->filter(function($post) {return count($post['likes']);}); }) ->reject(function($posts) {return isEmpty($posts);});
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Kedy použit kolekcie
Problém | Kolekcie | PHP | Ukážky | FP
• Práca so zložitými dátovými štruktúrami
• API
• Import CSV so zložitejšou logikou
• Transformácie datasetov
• Refaktoring vnorených cyklov pre ľahšie porozumenie
'
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Kolekcie v PHP - knižnice
Problém | Kolekcie | PHP | Ukážky | FP
• CakePHP Collection (github.com/cakephp/collection)
• Laravel Collections (github.com/illuminate/support)
• PHP-Collection (github.com/emonkak/php-collection)
• Knapsack (github.com/DusanKasan/Knapsack)
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Kolekcie v PHP - nedostatky
Problém | Kolekcie | PHP | Ukážky | FP
$collection->map(function($item) { return $item->field; });
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Kolekcie v PHP - nedostatky
Problém | Kolekcie | PHP | Ukážky | FP
$collection->map(function($item) {return $item->field;});
$collection->map(function($item) { return $item->field; });
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Kolekcie v PHP - nedostatky
Problém | Kolekcie | PHP | Ukážky | FP
$collection->map(function($item) {return $item->field;});
$collection->map($item ~> $item->field);
$collection->map(function($item) { return $item->field; });
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Kolekcie v PHP - nedostatky
Problém | Kolekcie | PHP | Ukážky | FP
$collection->map(function($item) {return $item->field;});
$collection->map($item ~> $item->field);
$collection->map(function($item) { return $item->field; });
$collection->map(function($item) => $item->field);
RFC pre PHP 7.1
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Ako to vyzerá v reálnom kóde?
Problém | Kolekcie | PHP | Ukážky | FP
$oldRouteData = Collection::from($oldRoutes) ->map(function(array $oldRoute) { return toArray(only($oldRoute, ['title', 'url'])); });$routeData = Collection::from($routes) ->filter(function(Route $route) { $methods = $route->getMethods(); $isGet = empty($methods) || in_array('GET', $methods); $excludeFromSitemap = $route->getOption('excludeFromSitemap') === TRUE; return $isGet && !$excludeFromSitemap; }) ->indexBy(function(Route $route, $routeName) { return $route->getOption('routeTitle') ?: ucwords(str_replace('_', ' ', $routeName)); }) ->map(function (Route $route) { return $route->compile(); }) ->filter(function(CompiledRoute $compiledRoute) { return empty($compiledRoute->getPathVariables()); }) ->map(function(CompiledRoute $compiledRoute, $routeTitle) { return [ 'title' => $routeTitle, 'url' => $compiledRoute->getStaticPrefix() ]; }) ->concat($oldRoutes);
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Ako to vyzerá v reálnom kóde?
Problém | Kolekcie | PHP | Ukážky | FP
$file->setFlags(SplFileObject::READ_CSV);$parts = Collection::from($file)->splitAt(2);$header = $parts->first()->toArray();if ($header != $this->header) { throw InvalidCsvFormat::invalidHeader();} $packages = $parts ->second() ->reject( function (array $row) { return $this->isEmptyLine($row); } ) ->map( function ($row) use ($customer) { return $this->buildIncorporation($customer, $row); } ) ->realize() ->map( function (CompanyIncorporation $incorporation) use ($order, $packageId, $customer) { $this->saveIncorporation($incorporation); $package = $this->buildPackage($packageId, $incorporation->getCompany()); $this->savePackageToOrder($package, $order); $this->printedDocumentResolver ->resolveDocuments($package->getId(), $customer, $package->getCompanyEntity()); return $package; } ) ->toArray();
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Funkcionálne v PHP
Problém | Kolekcie | PHP | Ukážky | FP
• Collection functions
• github.com/DusanKasan/Knapsack
• Transducers
• github.com/mtdowling/transducers.php
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN
Viac info?
Problém | Kolekcie | PHP | Ukážky | FP
• Martin Fowler (martinfowler.com)
• Adam Wathan (adamwathan.me/refactoring-to-collections)
• Dokumentácia a testy ku knižniciam
ZREFAKTORUJ CYKLY NA KOLEKCIEDUŠAN KASAN