Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Laravel Design Patterns

8,067 views

Published on

Most of us use Design Patterns on a daily basis without noticing. Design patterns are commonly defined as solutions to recurring design problems. Frameworks like Laravel use Design Patterns throughout the codebase to keep structure and maintainability. In this talk we will explore the Design Patterns used in Laravel.

Published in: Software
  • DOWNLOAD FULL BOOKS, INTO AVAILABLE FORMAT ......................................................................................................................... ......................................................................................................................... ,DOWNLOAD FULL. PDF EBOOK here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ,DOWNLOAD FULL. EPUB Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ,DOWNLOAD FULL. doc Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ,DOWNLOAD FULL. PDF EBOOK here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ,DOWNLOAD FULL. EPUB Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ,DOWNLOAD FULL. doc Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Why in transport manager, than somethnig driver creates (createSendmailDriver), I does not see any complex steps? I think, In this example, Manager looks like factory, because it not contains any of complex step. Can you explain, why Did You see builder there. May be QueryBuilder is better example of using builder in laravel? Thank you.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Hi, Bobby, I just want to know why you use a key word with a colon between function prototype and starting brace ?
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Hi Bobby,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Laravel Design Patterns

  1. 1. Laravel Design Patterns
  2. 2. About Me Bobby Bouwmann @bobbybouwmann Enrise -Code Cuisine markdownmail.com Laracasts
  3. 3. Laravel Design Patterns
  4. 4. Daily Design Patterns
  5. 5. What are Design Patterns?
  6. 6. Design Patterns are ... Recipes for building maintainable code
  7. 7. Be your own Chef Using the boundaries of Design Pattern
  8. 8. Why use Design Patterns? — Provides a way to solve issues related to software development using a proven solution — Makes communication between developer more efficient
  9. 9. Why use Design Patterns? — There is no"silver bullet"for using design pattern,each project and situation is different
  10. 10. Maintainable Code
  11. 11. Maintainable Code — Understandable — Intuitive — Adaptable — Extendable — Debuggable
  12. 12. Maintainable Code — Don't Repeat Yourself — Keep It Simple Stupid
  13. 13. Design Pattern Time
  14. 14. Design Pattern types — Creational Patterns — Structural Patterns — Behavioural Patterns
  15. 15. Creational Patterns — Class instantiation — Hiding the creation logic — Examples: Factory,Builder,Prototype,Singleton
  16. 16. Structural Patterns — Composition between objects — Usages of interfaces,abstract classes — Examples: Adapter,Bridge,Decorator,Facade,Proxy
  17. 17. Behavioural Patterns — Communication between objects — Usages of mostly interfaces — Examples: Command,Iterator,Observer,State,Strategy
  18. 18. Design Patterns in Laravel — Factory Pattern — Builder (Manager) Pattern — Strategy Pattern — Provider Pattern — Repository Pattern — Iterator Pattern — Singleton Pattern — Presenter Pattern
  19. 19. Design Patterns in Laravel — Factory Pattern — Builder (Manager) Pattern — Strategy Pattern — Provider Pattern
  20. 20. Factory Pattern
  21. 21. Factory Pattern Provides an interface for creating objects without specifying their concrete classes.
  22. 22. Factory Pattern — Decouples code — Factory is responsible for creating objects,not the client — Multiple clients call the same factory,one place for changes — Easier to test,easy to mock and isolate
  23. 23. Factory Pattern Example interface PizzaFactoryContract { public function make(array $toppings = []): Pizza; } class PizzaFactory implements PizzaFactoryContract { public function make(array $toppings = []): Pizza { return new Pizza($toppings); } } $pizza = (new PizzaFactory)->make(['chicken', 'onion']);
  24. 24. Factory Pattern Laravel Example class PostsController { public function index(): IlluminateViewView { $posts = Post::all(); return view('posts.index', ['posts' => $posts]); } }
  25. 25. // IlluminateFoundationhelpers.php /** * @return IlluminateViewView|IlluminateContractsViewFactory */ function view($view = null, $data = [], $mergeData = []) { $factory = app(ViewFactory::class); if (func_num_args() === 0) { return $factory; } return $factory->make($view, $data, $mergeData); }
  26. 26. /** * Get the evaluated view contents for the given view. * * @return IlluminateContractsViewView */ public function make($view, $data = [], $mergeData = []) { $path = $this->finder->find( $view = $this->normalizeName($view) ); $data = array_merge($mergeData, $this->parseData($data)); return tap($this->viewInstance($view, $path, $data), function ($view) { $this->callCreator($view); }); } /** * Create a new view instance from the given arguments. * * @return IlluminateContractsViewView */ protected function viewInstance($view, $path, $data) { return new View($this, $this->getEngineFromPath($path), $view, $path, $data); }
  27. 27. /** * Create a new Validator instance. * * @return IlluminateValidationValidator */ public function make(array $data, array $rules, array $messages = [], array $customAttributes = []) { $validator = $this->resolve( $data, $rules, $messages, $customAttributes ); $this->addExtensions($validator); return $validator; } /** * Resolve a new Validator instance. * * @return IlluminateValidationValidator */ protected function resolve(array $data, array $rules, array $messages, array $customAttributes) { if (is_null($this->resolver)) { return new Validator($this->translator, $data, $rules, $messages, $customAttributes); } return call_user_func($this->resolver, $this->translator, $data, $rules, $messages, $customAttributes); }
  28. 28. Builder (Manager) Pattern
  29. 29. Builder (Manager) Pattern Builds complex objects step by step.It can return different objects based on the given data.
  30. 30. Builder (Manager) Pattern — Decouples code — Focuses on building complex objects step by step and returns them — Has functionality to decide which objects should be returned
  31. 31. Builder Pattern Example class PizzaBuilder { public function make(PizzaBuilderInterface $pizza): Pizza { // Returns object of type Pizza } }
  32. 32. class PizzaBuilder { public function make(PizzaBuilderInterface $pizza): Pizza { $pizza->prepare(); $pizza->applyToppings(); $pizza->bake(); return $pizza; } }
  33. 33. interface PizzaBuilderInterface { public function prepare(): Pizza; public function applyToppings(): Pizza; public function bake(): Pizza; }
  34. 34. class MargarithaBuilder implements PizzaBuilderInterface { protected $pizza; public function prepare(): Pizza { $this->pizza = new Pizza(); return $this->pizza; } public function applyToppings(): Pizza { $this->pizza->setToppings(['cheese', 'tomato']); return $this->pizza; } public function bake(): Pizza { $this->pizza->setBakingTemperature(180); $this->pizza->setBakingMinutes(8); return $this->pizza; } }
  35. 35. class PizzaBuilder { public function make(PizzaBuilderInterface $pizza): Pizza { return $pizza ->prepare(); ->applyToppings(); ->bake(); } } // Create a PizzaBuilder $pizzaBuilder = new PizzaBuilder; // Create pizza using Builder which returns Pizza instance $pizza = $pizzaBuilder->make(new MargarithaBuilder());
  36. 36. class ChickenBuilder implements PizzaBuilderInterface { protected $pizza; public function prepare(): Pizza { $this->pizza = new Pizza(); return $this->pizza; } public function applyToppings(): Pizza { $this->pizza->setToppings(['cheese', 'tomato', 'chicken', 'corn']); return $this->pizza; } public function bake(): Pizza { $this->pizza->setBakingTemperature(200) $this->pizza->setBakingMinutes(8); return $this->pizza; } }
  37. 37. class PizzaBuilder { public function make(PizzaBuilderInterface $pizza): Pizza { return $pizza ->prepare() ->applyToppings() ->bake(); } } $pizzaBuilder = new PizzaBuilder; $pizzaOne = $pizzaBuilder->make(new MargarithaBuilder()); $pizzaTwo = $pizzaBuilder->make(new ChickenBuilder());
  38. 38. Builder Pattern Laravel
  39. 39. class PizzaManager extends IlluminateSupportManager { public function getDefaultDriver() { return 'margaritha'; } public function createMargarithaDriver(): PizzaBuilderInterface { return new MargarithaBuilder(); } public function createChickenPizzaDriver(): PizzaBuilderInterface { return new ChickenPizzaBuilder(); } }
  40. 40. public function driver($driver = null) { $driver = $driver ?: $this->getDefaultDriver(); // If the given driver has not been created before, we will create the instances // here and cache it so we can return it next time very quickly. If there is // already a driver created by this name, we'll just return that instance. if (! isset($this->drivers[$driver])) { $this->drivers[$driver] = $this->createDriver($driver); } return $this->drivers[$driver]; }
  41. 41. protected function createDriver($driver) { // We'll check to see if a creator method exists for the given driver. If not we // will check for a custom driver creator, which allows developers to create // drivers using their own customized driver creator Closure to create it. if (isset($this->customCreators[$driver])) { return $this->callCustomCreator($driver); } else { $method = 'create' . Str::studly($driver) . 'Driver'; if (method_exists($this, $method)) { return $this->$method(); } } throw new InvalidArgumentException("Driver [$driver] not supported."); }
  42. 42. class PizzaManager extends IlluminateSupportManager { public function getDefaultDriver() { return 'margaritha'; } public function createMargarithaDriver(): PizzaBuilderInterface { return new MargarithaBuilder(); } } $manager = new PizzaManager(); // MargarithaBuilder implementing PizzaBuilderInterface $builder = $manager->driver('margaritha'); $pizza = $builder->make(); // Pizza
  43. 43. // IlluminateMailTransportManager class TransportManager extends Manager { protected function createSmtpDriver() { // Code for building up a SmtpTransport class } protected function createMailgunDriver() { // Code for building up a MailgunTransport class } protected function createSparkpostDriver() { // Code for building up a SparkpostTransport class } protected function createLogDriver() { // Code for building up a LogTransport class } }
  44. 44. class TransportManager extends Manager { public function getDefaultDriver() { return $this->app['config']['mail.driver']; } // All create{$driver}Driver methods }
  45. 45. // config/mail.php 'driver' => env('MAIL_DRIVER', 'smtp'),
  46. 46. // config/mail.php 'driver' => env('MAIL_DRIVER', 'smtp'), // IlluminateMailTransportManager createSmtpDriver()
  47. 47. // config/mail.php 'driver' => env('MAIL_DRIVER', 'smtp'), // IlluminateMailTransportManager createSmtpDriver() // app/Http/Controllers/RegisterController Mail::to($user) ->send(new UserRegistered($user));
  48. 48. Laravel Manager Pattern Examples IlluminateAuthAuthManager IlluminateBroadcastingBroadcastManager IlluminateCacheCacheManager IlluminateFilesystemFilesystemManager IlluminateMailTransportManager IlluminateNotificationsChannelManager IlluminateQueueQueueManager IlluminateSessionSessionManager
  49. 49. Strategy Pattern
  50. 50. Strategy Pattern Defines a familiy of algorithms that are interchangeable
  51. 51. Strategy Pattern Program to an interface, not an implementation.
  52. 52. Strategy Pattern Example interface DeliveryStrategy { public function deliver(Address $address); }
  53. 53. interface DeliveryStrategy { public function deliver(Address $address); } class BikeDelivery implements DeliveryStrategy { public function deliver(Address $address): { $route = new BikeRoute($address); echo $route->calculateCosts(); echo $route->calculateDeliveryTime(); } }
  54. 54. class PizzaDelivery { public function deliverPizza(DeliveryStrategy $strategy, Address $address) { return $strategy->deliver($address); } } $address = new Address('Meer en Vaart 300, Amsterdam'); $delivery = new PizzaDelivery(); $delivery->deliver(new BikeDelivery(), $address);
  55. 55. class DroneDelivery implements DeliveryStrategy { public function deliver(Address $address): { $route = new DroneRoute($address); echo $route->calculateCosts(); echo $route->calculateFlyTime(); } }
  56. 56. class PizzaDelivery { public function deliverPizza(DeliveryStrategy $strategy, Address $address) { return $strategy->deliver($address); } } $address = new Address('Meer en Vaart 300, Amsterdam'); $delivery = new PizzaDelivery(); $delivery->deliver(new BikeDelivery(), $address); $delivery->deliver(new DroneDelivery(), $address);
  57. 57. Strategy Pattern Laravel Example
  58. 58. <?php namespace IlluminateContractsEncryption; interface Encrypter { /** * Encrypt the given value. * * @param string $value * @param bool $serialize * @return string */ public function encrypt($value, $serialize = true); /** * Decrypt the given value. * * @param string $payload * @param bool $unserialize * @return string */ public function decrypt($payload, $unserialize = true); }
  59. 59. namespace IlluminateEncryption; use IlluminateContractsEncryptionEncrypter as EncrypterContract; class Encrypter implements EncrypterContract { /** * Create a new encrypter instance. */ public function __construct($key, $cipher = 'AES-128-CBC') { $this->key = (string) $key; $this->cipher = $cipher; } /** * Encrypt the given value. */ public function encrypt($value, $serialize = true) { // Do the encrypt part and return the encrypted value } /** * Decrypt the given value. */ public function decrypt($payload, $unserialize = true) { // Do the decrypt part and return the original value } }
  60. 60. use IlluminateContractsEncryptionEncrypter as EncrypterContract; class MD5Encrypter implements EncrypterContract { const ENCRYPTION_KEY = 'qJB0rGtIn5UB1xG03efyCp'; /** * Encrypt the given value. */ public function encrypt($value, $serialize = true) { return base64_encode(mcrypt_encrypt( MCRYPT_RIJNDAEL_256, md5(self::ENCRYPTION_KEY), $value, MCRYPT_MODE_CBC, md5(md5(self::ENCRYPTION_KEY)) )); } /** * Decrypt the given value. */ public function decrypt($payload, $unserialize = true) { return rtrim(mcrypt_decrypt( MCRYPT_RIJNDAEL_256, md5(self::ENCRYPTION_KEY), base64_decode($payload), MCRYPT_MODE_CBC, md5(md5(self::ENCRYPTION_KEY)) ), "0"); } }
  61. 61. Laravel Strategy Pattern Examples IlluminateContractsAuthGaurd IlluminateContractsCacheStore IlluminateContractsEncryptionEncrypter IlluminateContractsEventsDispatcher IlluminateContractsHashingHasher IlluminateContractsLoggingLog IlluminateContractsSessionSession IlluminateContractsTranslationLoader
  62. 62. Provider Pattern
  63. 63. Provider Pattern Sets a pattern for providing some essential service
  64. 64. Provider Pattern Example class DominosServiceProvider extends ServiceProvider { public function register() { // Register your services here } }
  65. 65. use AppDominosPizzaManager; class PizzaServiceProvider extends ServiceProvider { public function register() { $this->app->bind('pizza-manager', function ($app) { return new PizzaManager(); }); } }
  66. 66. // Using instantiation $pizzaManager = new AppDominosPizzaManager(); // Using the provider pattern and the container $pizzaManager = app('pizza-manager'); $margaritha = $pizzaManager->driver('margaritha'); $chicken = $pizzaManager->driver('chicken-pizza');
  67. 67. Provider Pattern Laravel Example
  68. 68. class DebugbarServiceProvider extends ServiceProvider { public function register() { $this->app->singleton('debugbar', function ($app) { $debugbar = new LaravelDebugbar($app); if ($app->bound(SessionManager::class)) { $sessionManager = $app->make(SessionManager::class); $httpDriver = new SymfonyHttpDriver($sessionManager); $debugbar->setHttpDriver($httpDriver); } return $debugbar; }); } }
  69. 69. Factory Pattern Recap Factory translates interface to an instance
  70. 70. Builder Pattern Recap Builder Pattern can do the configuration for a new object without passing this configuration to that object
  71. 71. Strategy Pattern Recap Strategy pattern provides one place where the correct strategy (algorithm) is called
  72. 72. Provider Pattern Recap Provider Pattern let you extend the framework by registering new classes in the container
  73. 73. Wrapping up
  74. 74. Wrapping up use AppDominosPizzaManager; class PizzaServiceProvider extends ServiceProvider { public function register() { $this->app->bind('pizza-manager', function ($app) { return new PizzaManager(); }); } }
  75. 75. Design Pattern Fever
  76. 76. Want to learn more? More Design Patterns: http://goo.gl/sHT3xK Slideshare: https://goo.gl/U3YncS
  77. 77. Thank youBobby Bouwmann @bobbybouwmann Feedback: https://joind.in/talk/25af5
  78. 78. Thank youBobby Bouwmann @bobbybouwmann Feedback: https://joind.in/talk/25af5

×