kdyby/events #posobota

Post on 02-Jul-2015

249 Views

Category:

Technology

5 Downloads

Preview:

Click to see full reader

DESCRIPTION

The Kdyby/Events extension provides a robust events system for the Nette Framework.

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