kdyby/events #posobota
Post on 02-Jul-2015
249 Views
Preview:
DESCRIPTION
TRANSCRIPT
Kdyby/Events@ProchazkaFilip
Co si povíme?● teorie kolem eventů● jak to funguje v Nette● eventy v komponentách● Kdyby/Events prakticky● diskuze? připravte si otázky!
Teorie kolem eventů
Co jsou eventy/hooky?● modulárnost● rozšiřitelnost● znovupoužitelnost
Eventy v Nette?class Circle extends Nette\Object{ public $onChange = []; public function setRadius($radius)
{ $this->radius = max(0, $radius);
$this->onChange($this, $this->radius); }
Eventy v Nette?$circle = new Circle;
$circle->onChange[] =function($circle, $newValue) { echo 'there was a change!';};
$circle->setRadius(10);
Nette magicclass Nette\Object{
public function __call($name, $args){
foreach ($this->{"on$name"} as $cb){
call_user_func_array($cb, $args);}
}
Eventyv komponentách
Co je problém?class MyControl extends UI\Control {
public function handleFoo() {
// logic
$this->presenter->flashMessage('Yatta!');$this->redirect('Foo:');
}
}
Řešení?class MyControl extends UI\Control {
public $onSuccess = [];public function handleFoo() {
// logic
$this->onSuccess($this, $arg);}
}
Řešení?$control->onSuccess[] = function () {
$this->presenter->flashMessage('Yatta!');
$this->redirect('Foo:');
};
Kdyby/Events
Naco další event systém?● není to lazy● kompatibilita s otatními systémy
○ doctrine\orm○ symfony\event-dispatcher
Lazy eventy?$circle->onChange[] =
function($arg) use ($foo) { $foo->hardWork($arg);};
$circle->onChange[] =function($arg) use ($bar) { $bar->hardWork($arg);};
Doctrine ORM?class Listener implements EventSubscriber {
function getSubscribedEvents() {
return ['onFoo', 'onBar'];}
function onFoo($args) {// ...
}
Doctrine ORM?
$evm = new EventManager();$evm->addEventSubscriber(new Listener()
);
Doctrine ORM?
$evm->dispatch('onFoo',new Args($foo, $radius)
);
Symfony?class Listener
implements EventSubscriberInterface{
function getSubscribedEvents() {return ['onFoo', 'onBar'];
}
function onFoo($args) {// ...
}
Symfony?
$evd = new EventDispatcher();$evd->addSubscriber(new Listener()
);
Symfony?
$evm->dispatch('onFoo',new Event($foo, $radius)
);
Co takhle, Kdyby se všechny systémy daly používat dohromady?
xkcd.com/927
Kdyby/Events= Nette events (+ Doctrine EventManager)?(+ Symfony EventDispatcher)?
Pojďme vyřešit problém z praxe
class OrderProcess{function openOrder();function addItem($item);function finish(Order $order);
Nějaké ty basic závislosti
public function __construct(EntityManager $em,Nette\Security\User $user,Nette\Http\Session $session
){
Požadavek:“Po dokončení objednávky
se bude posílat email”
Přidáme posílání emailů...
public function __construct(EntityManager $em,Nette\Security\User $user,Nette\Http\Session $session,Nette\Mail\IMailer $mailer
){
Požadavek:“Přidej mi tam kredity za
objednávky”
Přidáme kredity..public function __construct(EntityManager $em,Nette\Security\User $user,Nette\Http\Session $session,Nette\Mail\IMailer $mailer,My\CreditsRewarder $rewarder
){
Požadavek:“Jeden partner chce
objednávky posílat do svého pokladního systému”
Externí pokladní systém..public function __construct(
EntityManager $em,
Nette\Security\User $user,
Nette\Http\Session $session,
Nette\Mail\IMailer $mailer,
My\CreditsRewarder $rewarder,
Partner\CashRegisterClient $partner){
Požadavek:“Budeme posílat smsky”
Posílání smsek...public function __construct(
EntityManager $em,
Nette\Security\User $user,
Nette\Http\Session $session,
Nette\Mail\IMailer $mailer,
My\CreditsRewarder $rewarder,
Partner\CashRegisterClient $partner,
My\Sms\Sender $smsSender
){
Požadavek:“V příštích 6 hodinách vracej
50% hodnoty objednávkyv kreditech, za všechny
objednané burgery”
SRP(Single Responsibility Principle)
Vraťme se na začátek...public function __construct(EntityManager $em,Nette\Security\User $user,Nette\Http\Session $session
){
… a přidejme si jeden eventclass OrderProcesspublic $onFinish = [];function finish(Order $order) {// ...$this->onFinish($this, $order);
}
… a napíšeme si listeneryclass OrderMailerListenerimplements Subscriber {function getSubscribedEvents() {return ['OrderProcess::onFinish'
];}
… a napíšeme si listeneryclass OrderMailerListener
function __construct(IMailer $mailer);
function onFinish(Order $order) {// ..$this->mailer->send($message);
}
… a napíšeme si listeneryclass CreditsRewardListener
function __construct(Rewarder $r, User $user);
function onFinish(Order $order) {$this->rewarder->reward(
$this->user->id,
$order->price * 0.05);
}
… a napíšeme si listeneryclass SmsSenderListener
function __construct(Sms\Sender $sender);
function onFinish(Order $order) {// ..
$this->sender->send($message);
}
Nezapomenout registrovatevents:subscribers:- OrderMailerListener- CreditsRewardListener- SmsSenderListener
Profit!
Poslední nejasnosti● Jak se $onFinish dostane k
listenerům?● Nemělo to být lazy? ● Můžu naslouchat na více událostí v
jednom listeneru?
A co nějaké nevýhody?● Nevíme vůbec co se zavolá● IDE s tím neumí pracovat
PhpStorm❤
Kdyby/Events
Go follow@juznacz
& @matej_21
A co ty message queue?Dáme demo?
Závěrem?Eventy nejsou silver bullet,
užívejte s rozumem.
Dotazy?
Díky za pozornost!filip-prochazka.com
Follow me maybe? @ProchazkaFilip
top related