Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

Moderne Webentwicklung

571 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

×