Moderne Webentwicklung

408 Aufrufe

Veröffentlicht am

Vortrag von Sebastian Blum auf dem Online Karrieretag in München am 29.06.2016

Veröffentlicht in: Internet
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

Moderne Webentwicklung

  1. 1. MODERNE WEBENTWICKLUNG SEBASTIAN BLUM
  2. 2. ONLINE KARRIERETAG MÜNCHEN 2016 AGENDA MODERNE WEBENTWICKLUNG ▸ TEIL 1: TESTGETRIEBENE ENTWICKLUNG ▸ CODEBEISPIEL ▸ TEIL 2: SYMFONY ENVIRONMENT ▸ VERSAND EINER NEWSLETTER KAMPAGNE
  3. 3. TESTGETRIEBENE ENTWICKLUNG TEIL 1 …
  4. 4. BEISPIELCODE: DATA CLASS WAS MACHT DIESER CODE? 1 <?php 2 3 class data 4 { 5 private $data; 6 7 public function __construct($data) 8 { 9 $this->data = $data; 10 } 11 12 public function get() 13 { 14 $fp = array(); 15 foreach ($this->data as $o) { 16 if ($o->bList == 1) { // What is bList? 17 $fp[] = $o; 18 } 19 } 20 21 return $fp; 22 } 23 } 24 WAS PASSIERT, WENN … ▸ … kein Array von Objekten übergeben wird? ▸ … die Objekte nicht
 public $bList; enthalten? ▸ … du diese Klasse erweitern sollst? ?
  5. 5. WIR LIEBEN AUCH KAFFEE DANN BRAUCHEN WIR ERST EINMAL EINEN KAFFEE…
  6. 6. EXKURS: TESTGETRIEBENE ENTWICKLUNG RED » GREEN » REFACTOR - ZYKLUS TEST FEHLGESCHLAGEN TEST SCHREIBEN TEST ERFOLGREICH CODE HINZUFÜGEN ABLAUF STÄNDIG WIEDERHOLEN CODE VERBESSERN REFACTOR
  7. 7. ERSTER TEST PRODUCT LIST TEST 1 <?php 2 3 namespace TestsDemo; 4 5 use DemoProductList; 6 7 class ProductListTest extends PHPUnit_Framework_TestCase 8 { 9 public function testProductList() 10 { 11 $productList = new ProductList(); 12 } 13 } 14 FAILURES! Tests: 1, Assertions: 0, Errors: 1.
  8. 8. MINIMALE IMPLEMENTIERUNG IMPLEMENTIERUNG PRODUCT LIST 1 <?php 2 3 namespace Demo; 4 5 class ProductList 6 { 7 8 } 9 OK (1 test, 0 assertions)
  9. 9. EXKURS: WAS IST EIN INTERFACE INTERFACE: LISTBARES PRODUKT 1 <?php 2 3 namespace Demo; 4 5 interface ProductListInterface 6 { 7 /** 8 * Checks if the product is listed. 9 * 10 * @return bool 11 */ 12 public function isListed(); 13 } 14 Mit Hilfe des Interface schließen wir einen „Vertrag“, 
 dass die Methode „isListed“ vorhanden ist.
  10. 10. ERWEITERUNG DES TESTFALLS ERWEITERUNG PRODUCT LIST TEST 8 class ProductListTest extends PHPUnit_Framework_TestCase 9 { 10 public function testProductList() 11 { 12 $listedProduct = $this->prophesize(ProductListInterface::class); 13 $listedProduct->isListed()->willReturn(true); 14 $notListedProduct = $this->prophesize(ProductListInterface::class); 15 $notListedProduct->isListed()->willReturn(false); 16 17 $productList = new ProductList( 18 [ 19 $listedProduct->reveal(), 20 $notListedProduct->reveal(), 21 ] 22 ); 23 24 $this->assertCount(1, $productList->getListedProducts()); 25 $this->assertContains($listedProduct->reveal(), 26 $productList->getListedProducts()); 27 } 28 } 29 GELISTET NICHT 
 GELISTET BEIDE
 ÜBERGEBEN NUR 1 PRODUKT ERWARTET
  11. 11. FEHLERMELDUNG ERGEBNIS PRODUCT LIST TEST There was 1 error: 1) TestsDemoProductListTest::testProductList Error: Call to undefined method DemoProductList::getListedProducts() FAILURES! Tests: 1, Assertions: 0, Errors: 1.
  12. 12. FINALE IMPLEMENTIERUNG DER PRODUCT LIST KLASSE IMPLEMENTIERUNG PRODUCT LIST 5 class ProductList 6 { 7 private $products = []; 8 9 public function __construct(array $productList) 10 { 11 foreach ($productList as $product) { 12 $this->addProduct($product); 13 } 14 } 15 16 public function addProduct(ProductListInterface $product) 17 { 18 array_push($this->products, $product); 19 } 20 21 public function getListedProducts() 22 { 23 return array_filter( 24 $this->products, 25 function (ProductListInterface $product) { 26 return $product->isListed(); 27 } 28 ); 29 } 30 } 31 NUR ARRAY
 ERLAUBT INTERFACE IMPLEMENTIERT NUR GELISTETE
 PRODUKTE
  13. 13. 3 class data 4 { 5 private $data; 6 7 public function __construct($data) 8 { 9 $this->data = $data; 10 } 11 12 public function get() 13 { 14 $fp = array(); 15 foreach ($this->data as $o) { 16 if ($o->bList == 1) { 17 $fp[] = $o; 18 } 19 } 20 21 return $fp; 22 } 23 } 24 5 class ProductList 6 { 7 private $products = []; 8 9 public function __construct(array $productList) 10 { 11 foreach ($productList as $product) { 12 $this->addProduct($product); 13 } 14 } 15 16 public function addProduct(ProductListInterface $product) 17 { 18 array_push($this->products, $product); 19 } 20 21 public function getListedProducts() 22 { 23 return array_filter( 24 $this->products, 25 function (ProductListInterface $product) { 26 return $product->isListed(); 27 } 28 ); 29 } 30 } 31 GEGENÜBERSTELLUNG VERGLEICH: VORHER «–» NACHHER FAZIT: ▸ Einfacherer und sprechender Code▸ Code weniger fehleranfällig▸ Tests stetig wiederholbar
  14. 14. SYMFONY ENVIRONMENT TEIL 2
  15. 15. WAS IST DIE SYMFONY WELT? SYMFONY ▸ Komponenten ▸ 36 einzelne Bibliotheken 
 in PHP ▸ Open Source und in vielen Projekten oder Frameworks verwendet ▸ Full-Stack-Framework
 basierend auf den Komponenten bildet Symfony ein vollständiges Framework
  16. 16. BEISPIEL: VERSAND EINER NEWSLETTER KAMPAGNE
  17. 17. ÜBERSICHT DES ABLAUFS BEISPIEL: VERSAND EINER NEWSLETTER E-MAIL NEWSLETTER MAILER instanziiert Array an Empfängern jede Instanz sendet eine
 E-Mail an einen Empfänger
  18. 18. BEISPIEL EINER MÖGLICHEN IMPLEMENTIERUNG KLASSE: MAILER 1 <?php 2 3 class Mailer 4 { 5 private $fromEmail; 6 private $fromName; 7 private $header; 8 9 public function __construct($fromEmail, $fromName, $header) 10 { 11 $this->fromEmail = $fromEmail; 12 $this->fromName = $fromName; 13 $this->header = "From: $fromName <$fromEmail>n".$header; 14 } 15 16 public function send($to, $subject, $message) 17 { 18 mail($to, $subject, $message, $this->header); 19 } 20 } 21 NICHT TESTBAR!
  19. 19. BEISPIEL EINER MÖGLICHEN IMPLEMENTIERUNG KLASSE: NEWSLETTER 1 <?php 2 3 class Newsletter 4 { 5 private $mailer; 6 7 public function __construct() 8 { 9 $this->mailer = new Mailer('news@demo.de','Demo News','Reply-To: reply@demo.de'); 10 } 11 12 public function send($recipients, $subject, $message){ 13 foreach ($recipients as $to) { 14 $this->mailer->send($to, $subject, $message); 15 } 16 } 17 } 18 ▸ Nicht testbar, erweiterbar und wiederverwendbar ▸ Kein Fehlerhandling & kaum Chancen Fehler zu finden FAZIT: DIREKTE
 ABHÄNGIGKEIT
  20. 20. ENTWICKLUNG IM SYMFONY ENVIRONMENT „THE SYMFONY WAY“ ▸ Dependency Injection löst die Abhängigkeiten auf ▸ Kleine testgetriebene Klassen ▸ Config stellt einfache Konfiguration bereit ▸ Debug hilft beim Testen ▸ Framework integriert die Bibliothek SwiftMailer und stellt umfangreiche Konfiguration zur Verfügung
  21. 21. KONFIGURATION DES SERVICE CONTAINERS MIT HILFE VON YAML DEPENDENCY INJECTION KONFIGURATION parameters: mailer.transport: sendmail services: mailer: sendmail class: Mailer arguments: ['%mailer.transport%'] newsletter_manager: class: NewsletterManager calls: - [setMailer‚ ['@mailer']]
  22. 22. BEISPIEL: UNIT-TEST FÜR NEWSLETTER-MANAGER NEWSLETTER MANAGER TEST 1 <?php 2 3 namespace TestsDemo; 4 5 use DemoMailerInterface; 6 use DemoMessage; 7 use DemoNewsletterManager; 8 9 class NewsletterManagerTest extends PHPUnit_Framework_TestCase 10 { 11 public function testNewsletterManager() 12 { 13 $message = new Message('Test Betreff', 'Test-Inhalt Newsletter'); 14 $mailer = $this->prophesize(MailerInterface::class); 15 $mailer->send('max@mustermann.de', $message)->shouldBeCalled(); 16 17 $newsletterManager = new NewsletterManager(); 18 $newsletterManager->setMailer($mailer->reveal()); 19 $newsletterManager->sendMail(['max@mustermann.de'], $message); 20 } 21 } 22 STUB
  23. 23. IMPLEMENTIERUNG DES NEWSLETTER-MANAGERS NEWSLETTER-MANAGER 1 <?php 2 3 namespace Demo; 4 5 class NewsletterManager 6 { 7 private $mailer; 8 9 public function setMailer(MailerInterface $mailer) 10 { 11 $this->mailer = $mailer; 12 } 13 14 public function sendMail(array $recipients, Message $message) 15 { 16 foreach ($recipients as $recipient) { 17 $this->mailer->send($recipient, $message); 18 } 19 } 20 } 21
  24. 24. SYMFONY ENVIRONMENT: DEPENDENCY INJECTION VERWENDUNG DES NEWSLETTER-MANAGERS ▸ Im Controller oder Command kann nun der NewsletterManager mit Hilfe der Dependency Injection verwendet werden:
 
 ▸ Symfony liest die Konfiguration aus und erstellt den NewsletterManager mit allen Abhängigkeiten $newsletterManager = $this->get('newsletter_manager'); $newsletterManager->send($recipients, $message);
  25. 25. SYMFONY ENVIRONMENT: ERWEITERUNG ZUSÄTZLICHE ANFORDERUNGEN ▸ Im Test- & Entwicklungssystem sollen keine E-Mails versendet werden ▸ Einfache Konfiguration des Absenders ▸ Möglichkeit, über Gmail E-Mails zu versenden
 ▸ Bringt Symfony bereits alles mit
  26. 26. SWIFTMAILER BIBLIOTHEK KONFIGURATION E-MAIL-VERSAND ▸ Versand deaktivieren
 
swiftmailer: disable_delivery: true swiftmailer: delivery_address: me@example.com swiftmailer: transport: 'gmail' username: 'me@gmail.com' password 'myGmailPassword' ▸ Versand an Test-Empfänger
 
 ▸ Versand über Gmail
  27. 27. MODERNE WEBENTWICKLUNG DANKE FÜR DIE AUFMERKSAMKEIT ▸ Sebastian Blum
 sb@sblum.de ▸ Präsentation auf unserer Webseite
 lj https://www.sblum.de/treffen ▸ Café an unserem Stand

×