Your SlideShare is downloading. ×
0
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

What is this DI and AOP stuff anyway...

1,202

Published on

AOP and DI can make your PHP far more elegant and can help avoid spagetti code.

AOP and DI can make your PHP far more elegant and can help avoid spagetti code.

Published in: Technology, Business
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,202
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
0
Likes
6
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. What is this DI and AOP stuff anyway...Friday, June 7, 13
  • 2. About MeCurrently BBC Sport (Freelancer)Lived in Japan for 15 years - love sushiLove frameworks - not just PHP onesInvolved in Lithium and BEAR.Sunday projectsRichard McIntyre - @mackstarFriday, June 7, 13
  • 3. Dependency InjectionFriday, June 7, 13
  • 4. Most Basic Example - Problemclass Mailer{private $transport;public function __construct(){$this->transport = sendmail;}// ...}Friday, June 7, 13
  • 5. Expensivenew Zend_Config_Ini($path, ENV);Friday, June 7, 13
  • 6. Easily becomes an inheritance messSport_Lib_Builder_GenericStatsAbstractSport_Lib_Builder_GenericStats_Cricket_TableSport_Lib_Builder_GenericStats_Cricket_NarrowTableSport_Lib_Builder_GenericStats_CricketAbstractSport_Lib_API_GenericStats_CricketSport_Lib_API_GenericStatsAbstractSport_Lib_Service_SportsData_CricketSport_Lib_Service_SportsDataSport_Lib_ServiceAbstractFriday, June 7, 13
  • 7. DI for a 5 year oldWhen you go and get things out of the refrigerator for yourself, you cancause problems. You might leave the door open, you might get somethingMommy or Daddy doesnt want you to have. You might even be lookingfor something we dont even have or which has expired.What you should be doing is stating a need, "I need something to drinkwith lunch," and then we will make sure you have something when yousit down to eat.Friday, June 7, 13
  • 8. Something like this...Application needs Foo, which needs Bar, which needs Bim, so:Application creates BimApplication creates Bar and gives it BimApplication creates Foo and gives it BarApplication calls FooFoo calls BarBar does somethingFriday, June 7, 13
  • 9. The Service ContainerDependency Injection Round 1Friday, June 7, 13
  • 10. class Mailer{private $transport;public function __construct($transport){$this->transport = $transport;}// ...}Symfony2 ExampleFriday, June 7, 13
  • 11. class Mailer{private $transport;public function __construct($transport){$this->transport = $transport;}// ...}use SymfonyComponentDependencyInjectionContainerBuilder;$container = new ContainerBuilder();$container->register(mailer, Mailer);Symfony2 ExampleFriday, June 7, 13
  • 12. class Mailer{private $transport;public function __construct($transport){$this->transport = $transport;}// ...}use SymfonyComponentDependencyInjectionContainerBuilder;$container = new ContainerBuilder();$container->register(mailer, Mailer);use SymfonyComponentDependencyInjectionContainerBuilder;$container = new ContainerBuilder();$container->register(mailer, Mailer)->addArgument(sendmail);Symfony2 ExampleFriday, June 7, 13
  • 13. class NewsletterManager{private $mailer;public function __construct(Mailer $mailer){$this->mailer = $mailer;}// ...}Friday, June 7, 13
  • 14. class NewsletterManager{private $mailer;public function __construct(Mailer $mailer){$this->mailer = $mailer;}// ...}use SymfonyComponentDependencyInjectionContainerBuilder;use SymfonyComponentDependencyInjectionReference;$container = new ContainerBuilder();$container->setParameter(mailer.transport, sendmail);$container->register(mailer, Mailer)->addArgument(%mailer.transport%);$container->register(newsletter_manager, NewsletterManager)->addArgument(new Reference(mailer));Friday, June 7, 13
  • 15. use SymfonyComponentDependencyInjectionContainerBuilder;$container = new ContainerBuilder();$newsletterManager = $container->get(newsletter_manager);Friday, June 7, 13
  • 16. Inversion Of ControlPatternThe control of the dependencies is inversed from onebeing called to the one calling.Friday, June 7, 13
  • 17. ContainerNewsletter ManagerMailertransport = sendmailFriday, June 7, 13
  • 18. ContainerNewsletter ManagerMailer# src/Acme/HelloBundle/Resources/config/services.ymlparameters:# ...mailer.transport: sendmailservices:mailer:class: Mailerarguments: [%mailer.transport%]newsletter_manager:class: NewsletterManagercalls:- [ setMailer, [ @mailer ] ]transport = sendmailFriday, June 7, 13
  • 19. Decoupled CodeFriday, June 7, 13
  • 20. TipsTest first in isolationDon’t need to wire together to test (Eg Environment etc)integration tests are expensive.When you do wire together with test/mock classes as neededDuck Type your code / Use interfacesFriday, June 7, 13
  • 21. Friday, June 7, 13
  • 22. $container = new Pimple();// define some parameters$container[cookie_name] = SESSION_ID;$container[session_storage_class] = SessionStorage;Friday, June 7, 13
  • 23. $container = new Pimple();// define some parameters$container[cookie_name] = SESSION_ID;$container[session_storage_class] = SessionStorage;// define some objects$container[session_storage] = function ($c) {return new $c[session_storage_class]($c[cookie_name]);};$container[session] = function ($c) {return new Session($c[session_storage]);};Friday, June 7, 13
  • 24. Clever DI with BindingsFriday, June 7, 13
  • 25. Laravel 4 exampleclass MyConcreteClass implements MyInterface{Friday, June 7, 13
  • 26. Laravel 4 exampleclass MyConcreteClass implements MyInterface{class MyClass{public function __construct(MyInterface $my_injection){$this->my_injection = $my_injection;}}App::bind(MyInterface, MyConcreteClass);Friday, June 7, 13
  • 27. Cleverer DI with InjectionPoints & BindingsFriday, June 7, 13
  • 28. Google GuiceGuice alleviates the need for factories and the use of ‘new’ inyour ‘Java’a codeThink of Guices @Inject as the new new. You will still needto write factories in some cases, but your code will notdepend directly on them. Your code will be easier to change,unit test and reuse in other contexts.Ray.DIFriday, June 7, 13
  • 29. interface MailerInterface {}PHP Google Guice CloneRay.DIFriday, June 7, 13
  • 30. class Mailer implements MailerInterface{private $transport;/*** @Inject* @Named("transport_type")*/public function __construct($transport){$this->transport = $transport;}}interface MailerInterface {}PHP Google Guice CloneRay.DIFriday, June 7, 13
  • 31. class Mailer implements MailerInterface{private $transport;/*** @Inject* @Named("transport_type")*/public function __construct($transport){$this->transport = $transport;}}interface MailerInterface {}class NewsletterManager{public $mailer;/*** @Inject*/public function __construct(MailerInterface $mailer){$this->mailer = $mailer;}}PHP Google Guice CloneRay.DIFriday, June 7, 13
  • 32. class NewsletterModule extends AbstractModule{protected function configure(){$this->bind()->annotatedWith(transport_type)->toInstance(sendmail);$this->bind(MailerInterface)->to(Mailer);}}Friday, June 7, 13
  • 33. class NewsletterModule extends AbstractModule{protected function configure(){$this->bind()->annotatedWith(transport_type)->toInstance(sendmail);$this->bind(MailerInterface)->to(Mailer);}} $di = Injector::create([new NewsletterModule]);$newsletterManager = $di->getInstance(NewsletterManager);Friday, June 7, 13
  • 34. class NewsletterModule extends AbstractModule{protected function configure(){$this->bind()->annotatedWith(transport_type)->toInstance(sendmail);$this->bind(MailerInterface)->to(Mailer);}} $di = Injector::create([new NewsletterModule]);$newsletterManager = $di->getInstance(NewsletterManager);$works = ($newsletterManager->mailer instanceof MailerInterface);Friday, June 7, 13
  • 35. Problems?/Gochas1. Overly abstracted code2. Easy to go crazy with it3. Too many factory classes4. Easy to loose what data is where5. Container is like super global variableFriday, June 7, 13
  • 36. Many otherimplementationsFriday, June 7, 13
  • 37. Aspect OrientatedProgrammingFriday, June 7, 13
  • 38. The Problemfunction addPost() {$log->writeToLog("Entering addPost");// Business Logic$log->writeToLog("Leaving addPost");}Friday, June 7, 13
  • 39. The Problemfunction addPost() {$log->writeToLog("Entering addPost");// Business Logic$log->writeToLog("Leaving addPost");}function addPost() {$authentication->validateAuthentication($user);$authorization->validateAccess($user);// Business Logic}Friday, June 7, 13
  • 40. Core Class Aspect ClassAOP FrameworkProxy ClassContinue ProcessFriday, June 7, 13
  • 41. Lithium Example -Logging in your modelnamespace appmodels;use lithiumutilcollectionFilters;use lithiumutilLogger;Filters::apply(appmodelsPost, save, function($self, $params, $chain) {Logger::write(info, $params[data][title]);return $chain->next($self, $params, $chain);});Friday, June 7, 13
  • 42. Dispatcher::applyFilter(run, function($self, $params, $chain) {$key = md5($params[request]->url);if($cache = Cache::read(default, $key)) {return $cache;}$result = $chain->next($self, $params, $chain);Cache::write(default, $key, $result, +1 day);return $result;});Lithium Example -CachingFriday, June 7, 13
  • 43. Friday, June 7, 13
  • 44. FindFriday, June 7, 13
  • 45. CacheFindFriday, June 7, 13
  • 46. LogCacheFindFriday, June 7, 13
  • 47. LogCacheFindFriday, June 7, 13
  • 48. LogCacheFindFriday, June 7, 13
  • 49. LogCacheFindFriday, June 7, 13
  • 50. Ray.AOPGuice AOP CloneFriday, June 7, 13
  • 51. /*** NotOnWeekends** @Annotation* @Target("METHOD")*/final class NotOnWeekends{}Create AnnotationCreate Real Class - Billing serviceFriday, June 7, 13
  • 52. /*** NotOnWeekends** @Annotation* @Target("METHOD")*/final class NotOnWeekends{}Create Annotationclass RealBillingService{/*** @NotOnWeekends*/chargeOrder(PizzaOrder $order, CreditCard $creditCard){Create Real Class - Billing serviceFriday, June 7, 13
  • 53. class WeekendBlocker implements MethodInterceptor{public function invoke(MethodInvocation $invocation){$today = getdate();if ($today[weekday][0] === S) {throw new RuntimeException($invocation->getMethod()->getName() . " not allowed on weekends!");}return $invocation->proceed();}}Interception LogicFriday, June 7, 13
  • 54. $bind = new Bind;$matcher = new Matcher(new Reader);$interceptors = [new WeekendBlocker];$pointcut = new Pointcut($matcher->any(),$matcher->annotatedWith(RayAopSampleAnnotationNotOnWeekends),$interceptors);$bind->bind(RayAopSampleAnnotationRealBillingService, [$pointcut]);$billing = new Weaver(new RealBillingService, $bind);try {echo $billing->chargeOrder();} catch (RuntimeException $e) {echo $e->getMessage() . "n";exit(1);}Binding on AnnotationFriday, June 7, 13
  • 55. $bind = new Bind;$bind->bindInterceptors(chargeOrder, [new WeekendBlocker]);$billingService = new Weaver(new RealBillingService, $bind);try {echo $billingService->chargeOrder();} catch (RuntimeException $e) {echo $e->getMessage() . "n";exit(1);}Explicit Method BindingFriday, June 7, 13
  • 56. GochasFriday, June 7, 13
  • 57. BEAR.SundayFriday, June 7, 13

×