PHP Design Patterns. Frank Kleine & Stephan Schmidt 1&1 Internet AG



Ähnliche Dokumente
Inhalt. Max Lini. ax. inie. Einleitung... VII

Factory Method (Virtual Constructor)

Fassade. Objektbasiertes Strukturmuster. C. Restorff & M. Rohlfing

Design Pattern - Strukturmuster. CAS SWE - OOAD Marco Hunziker Klaus Imfeld Frédéric Bächler Marcel Lüthi

Client-Server-Beziehungen

Programmieren in Java

Verhindert, dass eine Methode überschrieben wird. public final int holekontostand() {...} public final class Girokonto extends Konto {...

Session Beans & Servlet Integration. Ralf Gitzel ralf_gitzel@hotmail.de

Objektorientierte Programmierung OOP

Design Patterns 2. Model-View-Controller in der Praxis

Klassenentwurf. Wie schreiben wir Klassen, die leicht zu verstehen, wartbar und wiederverwendbar sind? Objektorientierte Programmierung mit Java

Software Engineering. Zur Architektur der Applikation Data Repository. Franz-Josef Elmer, Universität Basel, HS 2015

Daniel Warneke Ein Vortrag im Rahmen des Proseminars Software Pioneers

Objektorientierte Programmierung für Anfänger am Beispiel PHP

Vererbung & Schnittstellen in C#

Programmierkurs Java

Java: Vererbung. Teil 3: super()

Albert HAYR Linux, IT and Open Source Expert and Solution Architect. Open Source professionell einsetzen

Vorkurs C++ Programmierung

Objektorientierte Programmierung. Kapitel 12: Interfaces

Objektorientierte Programmierung

Objektorientiertes Software-Engineering

Log xmllog textlog Log() start(filename) add(message) end() instance() Abbildung 7-10: Die Protokollierungs-API mit einer einfachen Fassade

Prinzipien Objektorientierter Programmierung

Einführung in die Programmierung

Code wiederverwenden: Objektorientierte Programmierung (OOP) sinnvoll nutzen Roland Wagner Automatisierungstreff IT & Automation 2015

Objektorientierung: Klassen und Objekte

Datenbank-Verschlüsselung mit DbDefence und Webanwendungen.

Dokumentation. Black- und Whitelists. Absenderadressen auf eine Blacklist oder eine Whitelist setzen. Zugriff per Webbrowser

Komponententest. Testen von Software Systemen. Übung 02 SS 2009 Version:

Java Kurs für Anfänger Einheit 4 Klassen und Objekte

Einführung in die Java- Programmierung

Java Kurs für Anfänger Einheit 5 Methoden

Übung 1 mit C# 6.0 MATTHIAS RONCORONI

OP-LOG

SEP 114. Design by Contract

PHP Aufbaukurs. Tag 3. PHP5 & Klassen

PHP Kurs Online Kurs Analysten Programmierer Web PHP

Step by Step Webserver unter Windows Server von Christian Bartl

Fragen Arthur Zaczek. Apr 2015

Javakurs zu Informatik I. Henning Heitkötter

Musterlösung zur Vorlesung Modellbasierte Softwareentwicklung Wintersemester 2014/2015 Übungsblatt 9

Exchange Export. Mailbox Export

Innere Klassen in Java

Applet Firewall und Freigabe der Objekte

Autorisierung. Sicherheit und Zugriffskontrolle & Erstellen einer Berechtigungskomponente

Drei-Schichten-Architektur. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 16: 3-Schichten-Architektur 1 Fachkonzept - GUI

5. Abstrakte Klassen. Beispiel (3) Abstrakte Klasse. Beispiel (2) Angenommen, wir wollen die folgende Klassenhierarchie implementieren:

Neue Funktionen im GUI für PC-DMIS V3.x 4.x Seite 1 von 8

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag

Datenmanagement in Android-Apps. 16. Mai 2013

.NET Code schützen. Projekt.NET. Version 1.0

Architektur des agimatec-validation Frameworks

Acceptor-Connector. Acceptor-Connector

Einführung in die objektorientierte Programmierung mit Java. Klausur am 19. Oktober 2005

Installationsanleitung dateiagent Pro

Leitfaden zur Nutzung von binder CryptShare

Dieses Tutorial gibt eine Übersicht der Form Klassen von Struts, welche Besonderheiten und Unterschiede diese aufweisen.

Grundlagen von Python

am Beispiel von JUnit

Java Einführung Collections

Objektorientierte Programmierung

Übung: Verwendung von Java-Threads

WEBAPPLIKATIONEN MIT PHP. Wo gibt es Hilfe? Wie fang ich an?

Übungen zu Softwaretechnik

WPF Steuerelemente Listbox, ComboBox, ListView,

SAP NetWeaver Gateway. 2013

Das Model View Controller (MVC) Konzept

7. Objektorientierte Softwareentwicklung/3. Informatik II für Verkehrsingenieure

Kurzeinführung Excel2App. Version 1.0.0

8 Design Patterns. Events

IAWWeb PDFManager. - Kurzanleitung -

Objektorientiertes JavaScript

Xcode/Cocoa/Objective-C Crashkurs Programmieren unter Mac OS X

Software-Entwurfsmuster

3 Objektorientierte Konzepte in Java

5. Abstrakte Klassen

Java Einführung Umsetzung von Beziehungen zwischen Klassen. Kapitel 7

Einrichtung des Cisco VPN Clients (IPSEC) in Windows7

Große Übung Praktische Informatik 1

Ein Ausflug zu ACCESS

Facebook I-Frame Tabs mit Papoo Plugin erstellen und verwalten

4D Server v12 64-bit Version BETA VERSION

.htaccess HOWTO. zum Schutz von Dateien und Verzeichnissen mittels Passwortabfrage

WordPress. Dokumentation

Urlaubsregel in David

Software-Architektur Design Patterns

Unsere Webapplikation erweitern

Fachdidaktik der Informatik Jörg Depner, Kathrin Gaißer

Windows. Workshop Internet-Explorer: Arbeiten mit Favoriten, Teil 1

3. Konzepte der objektorientierten Programmierung

Agentur für Werbung & Internet. Schritt für Schritt: Newsletter mit WebEdition versenden

AGROPLUS Buchhaltung. Daten-Server und Sicherheitskopie. Version vom b

5.2 Neue Projekte erstellen

Ihre Interessentendatensätze bei inobroker. 1. Interessentendatensätze

Sichtbarkeit & statische Methoden. Einsatz von Sichtbarkeit Einsatz statischer Methoden programmatische Realisierung 2 Beispielaufgaben

Updatehinweise für die Version forma 5.5.5

Inhalt. 1 Einleitung AUTOMATISCHE DATENSICHERUNG AUF EINEN CLOUDSPEICHER

U08 Entwurfsmuster (II)

crm-now/ps Webforms Webdesigner Handbuch Erste Ausgabe

Transkript:

PHP Design Patterns Frank Kleine & Stephan Schmidt 1&1 Internet AG

Agenda OOP-Crashkurs Software-Design Erzeugungsmuster Strukturmuster Verhaltensmuster Enterprise-Patterns Datenschicht Business-Logik-Schicht Präsentationsschicht Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 2

Frank Kleine Senior Web-Developer bei der 1&1 PHP-Entwickler seit 2000 Lead Developer Stubbles Lead Developer XJConf for PHP Co-Autor "Exploring PHP" Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 3

Stephan Schmidt Leiter Web-Development bei der 1&1 PHP-Entwickler seit 1999 Entwickler in PEAR, PECL, pat, Stubbles Autor für verschiedene Fachmagazine Speaker auf internationalen Konferenzen Autor von PHP Design Patterns, erschienen im O'Reilly Verlag Leider heute krank Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 4

OOP Crashkurs Klassen und Objekte Vererbung kontrollieren Sichtbarkeiten Interfaces Fehlerbehandlung mit Exceptions Interzeptoren in PHP Was kommt in PHP 5.3 Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 5

Klassen Baupläne für Objekte Sammlung aller Eigenschaften und Operationen eines Objektes class Car { public $manufacturer; public $milage; public function construct($manufacturer) { $this->manufacturer = $manufacturer; public function moveforward($miles) { $this->milage = $this->milage + $miles; $bmw = new Car('BMW'); $bmw->moveforward(50); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 6

Vererbung Kopieren von Eigenschaften und Methoden aus der abgeleiteten Klasse class Convertible extends Car { public $roofopen = false; public function openroof() { $this->roofopen = true; $bmw = new Convertible('BMW'); $bmw->openroof(); $bmw->moveforward(50); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 7

Sichtbarkeiten Erlaubt den Zugriff auf Eigenschaften und Methoden zu beschränken class Car { private $manufacturer; protected $milage; public function getmanufacturer() { return $this->manufacturer; public function setmanufacturer($manufacturer) { $this->manufacturer = $manufacturer; private: nur diese Klasse protected: diese und abgeleitete Klassen Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 8

Finale Methoden und Klassen Verbietet des Überschreiben von Methoden class Car { public final function moveforward($miles) { $this->milage = $this->milage + $miles; Verbietet das Ableiten von Klassen final class Convertible extends Car { Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 9

Abstrakte Klassen Fordert das Implementieren von Methoden abstract class Convertible extends Car { public abstract function openroof(); Abstrakte Methoden haben keinen Rumpf Klassen mit einer oder mehr abstrakten Methoden sind auch abstrakt Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 10

Interfaces Summe aller öffentlichen Methoden, (Eigenschaften) und Konstanten interface Vehicle { public function startengine(); public function moveforward($miles); public function stopengine(); class Car implements Vehicle { class Bike implements Vehicle { Erhöht den Grad der Kapselung Vererbung analog zu Klassen Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 11

Type-Hints Verlangen einen bestimmten Typ für Parameter function move(vehicle $v, $miles) { $v->startengine(); $v->moveforward($miles); $v->stopengine(); $bmw = new Car('BMW'); move($bmw, 50); Typ kann Interface oder Klasse sein Vereinfacht Checks Seit 5.1 auch für Arrays Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 12

Exceptions Ermöglichen einfache Fehlerbehandlung class Car { public function moveforward($miles) { if (!$this->enginestarted) { throw new IllegalStateException(); $bmw = new Car('BMW'); try { $bmw->moveforward(50); catch (Exception $e) { // Fehlerbehandlung Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 13

Exceptions Sind normale Objekte Müssen von Exception abgeleitet werden Unterschiedliche Fehlertypen durch unterschiedliche Exceptionklassen Fehlertypen werden durch Klassenhierarchie feiner granuliert Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 14

class Car { public function moveforward($miles) { if (!$this->enginestarted) { throw new IllegalStateException(); if (0 > $miles) { throw new IllegalArgumentException(); $bmw = new Car('BMW'); try { $bmw->moveforward(50); catch (IllegalStateException $e) { // Fehlerbehandlung catch (IllegalArgumentException $e) { // andere Fehlerbehandlung Exceptions Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 15

Interzeptoren in PHP Greifen, bevor ein Fehler auftritt class Car { public function call($method, $args) { echo "Methode {$method aufgerufen\n"; $bmw = new Car('BMW'); $bmw->fly(); call() für Methoden get(), set(), isset() für Eigenschaften autoload() für Klassen Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 16

Sonstiges Automatisches Konvertieren in Strings class Car { public function tostring() { return "Auto vom Typ {$this->manufacturer\n"; $bmw = new Car('BMW'); echo $bmw; Statische Methoden class Car { public static function dosomething() {... Car::doSomething(); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 17

Neu in PHP 5.3 Namespaces car.php: namespace MyApp; class Car {... bmw.php: import MyApp::Car as MyCar; $bmw = new MyCar('BMW'); echo $bmw; Verhindern Namenskonflikte mit anderen Applikationen Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 18

Neu in PHP 5.3 callstatic() analog zu call() Late Static Binding: In statischen Methoden kann die Klasse zur Laufzeit referenziert werden ($this für statische Aufrufe) Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 19

Neu in PHP 5.3 class A { public static function who() { echo CLASS ; public static function test() { self::who(); class B extends A { public static function who() { echo CLASS ; PHP < 5.3: B::test(); // A PHP >= 5.3: B::test(); // B Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 20

Software-Design Namenswahl Kapselung von Daten Regeln guten Software-Designs Dependency Injection Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 21

Namenswahl Sinnvolle Klassen- und Methodennamen wählen Code sollte wie ein Satz lesbar sein if ($user->haspermission(perm::write) && $file->iswriteable()) { $user->write('foo')->to($file); Fluent-Interfaces machen Code lesbarer Getter mit booleschen Rückgabewerten mit is oder has beginnen Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 22

Kapselung von Daten Eigenschaften sollten immer private oder protected sein Getter- und Setter-Methoden zum Modifizieren/Auslesen anbieten Alternativ set() und get() verwenden und virtuelle Properties einsetzen Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 23

Regeln des Software- Design 1. Wiederverwendbarkeit von Code ist besser als Duplizierung. 2. Kapseln Sie den Zugriff auf Daten immer innerhalb einer Klasse. 3. Kapseln Sie auch Algorithmen in einer Klasse. 4. Programmieren Sie immer gegen eine Schnittstelle. 5. Entwickeln Sie erweiterbare Schnittstellen. Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 24

Regeln des Software- Design (2) 6.Vermeiden Sie monolithische Strukturen. Ersetzen Sie komplexe if/else Blöcke durch einzelne Klassen. 7.Verwenden Sie Objektkomposition statt Vererbung. 8.Vermeiden Sie feste Abhängigkeiten zwischen Klassen, sondern koppeln diese lose miteinander. Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 25

Dependency Injection "Rufen Sie uns nicht an, wir rufen Sie an" Objekte erstellen abhängige Objekte nicht selbst Abhängige Objekte werden von außen über Konstruktor oder Methoden injiziert Dedizierte Session, Mittwoch 8:30 Uhr Raum Tempelhof Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 26

Design Patterns Lösungsmuster für häufig auftretende Entwurfsaufgaben in der Software- Entwicklung Keine Code-Bibliothek Organisiert in Pattern-Katalogen (z.b. Gang-of-Four Buch) verschiedene Kategorien: Erzeugungsmuster, Strukturmuster, Verhaltensmuster, Enterprise-Patterns Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 27

Erzeugungsmuster Erzeugungsmuster werden verwendet, um Objekte zu konstruieren. Singleton-Pattern Factory-Method-Pattern Abstract-Factory-Pattern Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 28

Singleton Problem: es darf nicht mehr als eine Instanz einer Klasse geben, z.b. um Speicher zu sparen Debugger, Logger zentraler Zugriffspunkt benötigt, aber globaler Namensraum soll nicht durch eine Variable mit der Instanz verschmutzt werden Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 29

Singleton stellt einen zentralen Zugriffspunkt bereit sichert ab, dass von einer Klasse nur eine Instanz existiert Implementierung: statische Klasseneigenschaft speichert Instanz statische Methode gibt Instanz zurück bzw. erstellt sie bei Nichtexistenz Nutzung von construct() und clone von Außerhalb unterbinden Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 30

Singleton class Debugger { protected static $instance; public static function getinstance() { if (null === self::$instance) { self::$instance = new self(); return self::$instance; protected function construct() { private function clone() { $debugger = Debugger::getInstance(); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 31

Singleton globaler Namensraum nicht verschmutzt genaue Kontrolle, wie auf Klasse zugegriffen wird immer nur eine Instanz der Klasse vorhanden Variation: Instanz abhängig von Parameter der getinstance()-methode Vorsicht: Einfachheit führt zu übermäßiger Nutzung in unangebrachten Fällen Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 32

Factory Method Problem: Objekte werden überall im Code mit new erzeugt. Änderungen sind nicht einfach möglich Ändern der Konstruktor-Parameter Austauschen der konkreten Implementierung Widerspricht Regel 4 (Programmierung gegen Schnittstellen) Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 33

Factory Method Definiert eine Schnittstelle zur Erzeugung von Objekten Verlagert die eigentliche Instanziierung in Unterklassen Läßt Unterklassen entscheiden, welche konkrete Implementierung verwendet wird Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 34

Factory Method abstract class AbstractManufacturer { protected $name; public function construct($name) { $this->name = $name; public function sellvehicle() { $vehicle = $this->manufacturevehicle(); // weitere Operationen möglich return $vehicle; public abstract function manufacturevehicle(); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 35

Factory Method class CarManufacturer extends AbstractManufacturer { public function manufacturevehicle() { return new Car($this->name); $bmwmanufacturer = new CarManufacturer('BMW'); $bmw = $bmwmanufacturer->sellvehicle(); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 36

Factory Method Ermöglicht, dass Framework-Code nur gegen Schnittstellen arbeitet Konkrete Implementierungen werden durch anwendungsspezifische Fabriken integriert. Verwandt mit der statischen Fabrikmethode $con = MDB2::factory($dsn, $options); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 37

Composite-Pattern Adapter-Pattern Decorator-Pattern Proxy-Pattern Facade-Pattern Strukturmuster Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 38

Composite Problem: mehrere Objekte gleicher Art müssen kombiniert werden Diese Struktur soll jedoch wie ein einziges Objekt behandelt werden: Ignorieren der Unterschiede zwischen Komposition von Objekten und Einzelobjekten Lösung: Composite fügt mehrere Objekte gleicher Art in einer Baumstruktur zusammen Clients können die gesamte Struktur wie ein einziges Objekt behandeln Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 39

Composite eine Klasse hält alle Instanzen des gleichen Typs in einer Liste Klasse kann neue Instanzen dieses Typs zur Liste hinzufügen Methodenaufrufe werden an alle Instanzen in der Liste weiter geleitet Klasse implementiert das gleiche Interface wie die Instanzen beliebig tief in einer Baumstruktur schachtelbar Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 40

Composite class DebuggerLog implements Debugger {... class DebuggerMail implements Debugger {... class DebuggerComposite implements Debugger { protected $debuggers = array(); public function adddebugger(debugger $debugger) { $this->debuggers[] = $debugger; public function debug($message) { foreach ($this-debugger as $debugger) { $debugger->debug($message); $debuggercomposite = new DebuggerComposite(); $debuggercomposite->adddebugger(new DebuggerLog()); $debuggercomposite->adddebugger(new DebuggerMail()); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 41

Composite leicht erweiterbar: neue Klassen müssen lediglich das Interface implementieren und sind sofort hinzufügbar beliebig tief schachtelbar: einer Composite- Instanz können andere Composite- Instanzen hinzugefügt werden Vorsicht: Entwurf nicht zu allgemein werden lassen, da sonst Typen-Checks zur Laufzeit notwendig werden Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 42

Decorator Problem: Bildung von Unterklassen ist nicht (einfach) zur Laufzeit möglich Funktionalität kann nur zur Kompilierungszeit hinzugefügt werden Vererbung ist sehr statisch Selten genutzte Funktionalität muss trotzdem in jedem Objekt zur Verfügung stehen Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 43

Decorator Erweitert ein Objekt zur Laufzeit um neue Funktionalitäten Erweitert oder verändert die vorhandenen Methoden Flexible Alternative zur Bildung von Unterklassen Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 44

Decorator interface String { public function getvalue(); public function setvalue(); class StringImpl implements String { protected $value; public function _construct($value) { $this->value = $value; // Setter und Setter $s = new StringImpl('Hello!'); echo $s->getvalue(); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 45

Decorator class StringDecorator implements String { protected $target; public function _construct(string $target) { $this->target = $target; public function getvalue() { return $this->target->getvalue(); public function setvalue($value) { return $this->target->setvalue($value); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 46

Decorator class ReverseDecorator extends StringDecorator { public function reverse() { $v = $this->target->getvalue(); $this->target->setvalue(strrev($v)); $s = new StringImpl(); $decorated = new ReverseDecorator($s); $decorated->reverse(); echo $decorated->getvalue(); if ($decorated instanceof String) { echo "verhält sich auch wie ein String"; Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 47

Decorator Schafft größere Flexibilität als Vererbung Hält einzelne Klassen schlank, da nur wichtige Logik implementiert wird Verlangt, dass es zu Ihren Klassen auch Interfaces gibt Viele Decorator machen Code unübersichtlich Jeder Decorator macht den Code langsamer Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 48

Proxy Problem: eine Klasse soll nicht in der Form verfügbar gemacht werden wie ist: Einschränkung der Zugriffe zu teuer, um sie immer zu instantiieren konkretes Objekt liegt auf einem anderen Server Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 49

Proxy kontrolliert den Zugriff auf ein Objekt ist ein Stellvertreter oder Ersatz anstelle des eigentlichen Objekts verschiedene Ausprägungen: Schutz-Proxy kontrolliert, ob Zugriffe auf das echte Objekt gestattet sind Virtueller Proxy ist ein Ersatz für ein teures Objekt und erzeugt dieses erst wenn es nicht mehr ohne geht Remote Proxy: das eigentliche Objekt befindet sich auf einem anderen Server Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 50

Proxy class ImageReal implements Image { public function construct($imagepath) { // teuer: Bild in Speicher laden public function draw() {... class ImageProxy implements Image { protected $imgpath; protected $realimage; public function construct($imagepath) { $this->imgpath = $imagepath; public function draw() { if (null === $this->realimage) { $this->realimage = new ImageReal($this->imgPath); $this->realimage->draw(); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 51

Decorator vs. Proxy vs. Adapter Nicht verwechseln: Proxy kontrolliert Zugriff Decorator fügt zusätzliches Verhalten hinzu Adapter ändert das Interface der gewrappten Klasse, Decorator und Proxy implementieren das Interface der gewrappten Klasse Proxy instantiiert das eigentliche Objekt erst bei Bedarf Decorator und Adapter wrappen ein bereits existierendes Objekt Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 52

Facade Problem: Applikation besteht aus komplexen Objektkompositionen Subsysteme sollten nutzbar sein, ohne dass Wissen über Interna der Anwendung erlernt werden muss Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 53

Facade Bietet eine vereinheitlichte Schnittstelle für einen Satz von Schnittstellen Bietet eine hochstufigere Schnittstelle, die die Verwendung des Basissystems vereinfacht Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 54

Facade // ohne Facade $tagparser = new DefinitionParser(); $defs = $tagparser->parse($definitionfile); $conf = new XmlParser(); try { $conf->settagdefinitions($defs); $conf->parse($configfile); catch (Exception $e) { // Mit Facade $facade = new XJConfFacade(); $facade->adddefinitions($definitionfile); $facade->parse($configfile); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 55

Facade Vereinfacht bestehende Schnittstellen Mehrere Fassaden auf ein Subsystem möglich und oft auch sinnvoll Fördert das Prinzip der Verschwiegenheit "Halten Sie die Anzahl der Klassen, mit denen Ihre Objekte interagieren, möglichst gering." Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 56

Subject/Observer-Pattern Template-Method-Pattern Command-Pattern Visitor-Pattern Iterator-Pattern Verhaltensmuster Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 57

Template Method Problem: feste Abfolge von Schritten, aber unterschiedliche Implementierungen einzelner Schritte möglich class Recipe { public function prepare() { $this->collectingredients(); $this->prepareingedients(); $this->cook(); $this->serve();... Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 58

Template Method definiert die Schritte eines Algorithmus in einer Methode Implementierung der einzelnen Schritte bleibt Unterklassen vorbehalten Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 59

Template Method abstract class Recipe { public final function prepare() { $this->collectingredients(); $this->prepareingedients(); $this->cook(); $this->serve(); protected abstract function collectingredients(); protected abstract function prepareingredients(); protected abstract function cook(); protected abstract function serve(); class CheeseBurgerRecipe extends Recipe { protected function collectingredients() {...... Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 60

Template Method erhöht Wiederverwendbarkeit gemeinsames Verhalten muss nur einmal implementiert werden: Änderungen am Algorithmus nur an einer Stelle notwendig neue Unterklassen müssen nur die konkreten Schritte implementieren Achtung: Anzahl abstrakter Schritte nicht zu groß werden lassen, evtl. einige optional machen und Basisimplementation anbieten Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 61

Command Problem: Sie möchten verschiedene Aktion nacheinander ausführen, die beliebig miteinander kombiniert werden können. Beispiel: Waschprogramm einer Waschstrasse besteht aus einzelnen "Waschbefehlen", die miteinander kombiniert werden können. Erster Lösungsansatz - eine Klasse pro Waschprogramm? Besser nicht. Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 62

Command Das Command Pattern kapselt einen Auftrag als Objekt. Aufträge (Objekte) sind parametrisierbar Aufträge können in einer Queue nacheinander abgearbeitet werden Aufträge können rückgängig gemacht werden. Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 63

Command interface CarWashCommand { public function execute(car $car); class CarSimpleWashCommand implements CarWashCommand { public function execute(car $car) { echo "Das Auto wird gewaschen"; class CarDryingCommand implements CarWashCommand { public function execute(car $car) { echo "Das Auto wird getrocknet"; Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 64

Command class CarWash { protected $programmes = array(); public function addprogramme($name, array $commands) { $this->programmes[$name] = $commands; public function wash($prog, Car $car) { foreach ($this->programmes[$prog] as $command) { $command->execute($car) Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 65

Command $wash = new CarWash(); $wash->addprogramme('standard', array( new CarSimpleWashCommand(), new CarDryingCommand() )); $wash->addprogramme('komfort', array( new CarSimpleWashCommand(), new CarEngineWashCommand(), new CarDryingCommand(), new CarWaxingCommand() )); $wash->wash('standard', $bmw); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 66

Command Kapselt Aufträge als Objekte Erleichtert das Einfügen neuer Operationen Sehr beliebt für Installer Sehr gut mit Composite-Pattern kombinierbar Durch Hinzufügen einer undo() Methode können Aufträge auch wieder rückgängog gemacht werden Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 67

Iterator Problem: Sie möchten verschiedene Listen- Typen durchlaufen, ohne für jeden Typ anderen Schleifen-Code zu verwenden $arr = array(...); foreach ($arr as $val) {... $d = dir('path/to/dir'); while (false!== ($entry = $d->read())) {... Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 68

Iterator Ermöglicht, auf die Elemente eines zusammengesetzten Objekts sequentiell zuzugreifen, ohne die zu Grunde liegende Struktur zu offenbaren PHP bringt in der SPL bereits Interface und konkrete Implementierungen mit interface Iterator { public function current(); public function key(); public function next(); public function rewind(); public function valid(); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 69

Iterator $arr = array(...); $it = new ArrayIterator($arr); foreach ($it as $value) {... $it = new DirectoryIterator('path/to/dir'); foreach ($it as $value) {... Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 70

Iterator Sehr komplexes Pattern, in PHP 5 sehr einfach zu nutzen Gute Integration durch foreach SPL stellt auch IteratorAggregate zur Verfügung. Dies ermöglicht externe Iteration (mehrfache, parallele Iteration über das selbe Objekt möglich) FilterIterator überspringt manche Elemente (z.b. nur über XML-Dateien iterieren) Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 71

Enterprise-Patterns Schichten einer Applikation Model-View-Controller Patterns der Datenschicht Row-Data-Gateway-Pattern Active-Record-Pattern Data-Mapper-Pattern Registry-Pattern Patterns der Business-Logik-Schicht Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 72

Schichten einer Applikation Präsentationsschicht View-Schicht Command-Control-Schicht Business-Logik-Schicht Datenschicht Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 73

Model-View-Controller Buzzword #1 der letzten Jahre Set von Design Patterns, das eingesetzt wird, um die Schichten voneinander zu trennen View stellt die Daten des Models dar Model speichert die Daten der Applikation Controller nimmt die Aktion des Benutzers an und fordert Model oder View auf, den Zustand zu ändern Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 74

Datenschicht Kümmert sich um die Verwaltung der Daten Persistierung der Daten in einem Datenspeicher Selektieren der Daten aus diesem Datenspeicher Häufig durch RDBMS abgebildet, aber nicht darauf beschränkt Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 75

Row-Data-Gateway Problem: Sie möchten Daten der Autos in einer Datenbank persistieren, aber nicht darauf verzichten, diese als Objekte zu verwenden Jedes Auto soll in einer Zeile einer Tabelle gespeichert werden Mögliche Operationen sollen INSERT, UPDATE, SELECT und DELETE sein Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 76

Row-Data-Gateway Row-Data-Gateway dient als Repräsentation einer Zeile in einer Datenbanktabelle Eine Instanz pro Zeile, über die die Spalten der Zeile verändert werden Pro Tabelle wird eine Klasse benötigt Je Eigenschaft eine Getter- und Setter- Methode Zusätzliche Methoden zum Speichern der Daten in der Klasse Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 77

Row-Data-Gateway SQL Funktionalität wird meist durch abstrakte Basis-Klasse bereit gestellt Die Klassen sind reine Datencontainer, bieten keine zusätzliche Funktionalität Zusätzliche "Finder" Klasse zum Selektieren der Daten Propel ist bekannte Implementierung in PHP, generiert PHP Klassen für DB- Tabellen Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 78

Row-Data-Gateway $bmw = new Car('BMW'); $bmw->setcolor('blau'); $bmw->save(); $bmw = CarPeer::retrieveByPk(1); echo $bmw->getcolor(); $c = new Criteria(); $c->add(carpeer::manufacturer, 'BMW'); $bmws = CarPeer::doSelect($c); foreach ($bmws as $bmw) { echo $bmw->getcolor(); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 79

Row-Data-Gateway Kein SQL mehr in der Business-Logik Unabhängig von der gewählten Datenbank Führt zu Performance-Einbußen und Verzicht auf DB-spezifische Features Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 80

Active-Record Ähnelt Row-Data-Gateway Fügt den Klassen jedoch Domänenlogik hinzu Auch in Propel realisiert, da Unterklassen erstellt werden, die vom Entwickler modifiziert werden können Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 81

Data Mapper Row-Data-Gateway und Active Record nicht der Weisheit letzter Schluss Datenklassen sollten Modell wiederspiegeln, nicht wie sie selbst gespeichert werden Daten sollen unterschiedlich persistiert werden können: Datenbank, Datei, Application Server,... Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 82

Data Mapper Lösung: gesonderte Schicht, welche die Applikations-Objekte auf den Datenspeicher mappt Objekte und Mapper sind unabhängig voneinander Im Bestfall: Mapper kann jede Art von Objekt persistieren (soweit sinnvoll) Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 83

Data Mapper XML-Beschreibungen: Mapping wird in XML-Dateien definiert Mapper liest XML-Datei und behandelt Objekt entsprechend dieser Konfiguration Besser: Annotations Mapping steht als Annotation an/in der Klasse, ist aber kein Programmcode weniger Definitionsoverhead als mit XML Annotations an Methoden/Eigenschaften werden in Klassenhierarchie mit vererbt Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 84

Data Mapper /** * @Entity */ class Person { protected $name, $age; public function construct($name, $age) {... /** * @DBColumn(name='name') */ public function getname() { return $this->name; public function getage() { return $this->age; $entitymanager->save(new Person('mikey', 28)); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 85

Registry Konfiguration soll nur einmal eingelesen werden Konfigurationsobjekt wird jedoch in verschiedenen Schichten benötigt Durchreichen durch die Schichten führt zu unnötig langen Methodensignaturen, Objekte werden oftmals einfach nur durchgereicht Anwendung des Singleton-Pattern nicht sinnvoll, da mehrere verschiedene Instanzen benötigt globale Variablen sind böse :-) Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 86

Registry Registry speichert Objekte oder Informationen zur gemeinsamen Nutzung durch andere Objekte bietet zentralen Zugriffspunkt auf Objekte und Informationen Registry ist selbst ein Singleton (Alternative: komplett statische Implementierung) Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 87

Registry class Registry { protected $data = array(); // Singleton-Implementierung ausgelassen public function get($key) { if (isset($this->data[$key])) { return $this->data[$key]; return null; public function set($key, $value) { $this->data[$key] = $value; Registry::getInstance()->set('foo' => new Bar('baz')); Registry::getInstance()->get('foo'); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 88

Registry class Registry { protected static $data = array; public static function get($key) { if (isset(self::$data[$key])) { return self::$data[$key]; return null; public function set($key, $value) { self::$data[$key] = $value; Registry::set('foo' => new Bar('baz')); Registry::get('foo'); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 89

Business-Logik-Schicht Enthält die eigentliche Anwendungslogik Kaum spezielle Patterns Domain-Model-Pattern Value-Object-Pattern Alle klassischen Patterns werden in dieser Schicht eingesetzt Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 90

Enterprise-Patterns (2) Patterns der Command-Control-Schicht Front-Controller-Pattern Intercepting-Filter-Pattern Event-Dispatcher-Pattern Patterns der View-Schicht Template-View-Pattern View-Helper-Pattern Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 91

Command-Control-Schicht Kümmert sich im Interaktion mit dem Nutzer Nimmt die HTTP-Anfragen in Web- Anwendungen entgegen Analysiert Anfragen und steuert Business- Logik-Schicht an Geschäftslogik wird dadurch unabhängig vom Web-Umfeld Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 92

Front Controller Entkopplung der Applikation vom Webumfeld, um Teile auch in einem anderem Umfeld wiederverwenden zu können Hinzufügen neuer Seiten ermöglichen, ohne zentrale Logik zu duplizieren einfachere Sicherheitsüberprüfungen durch zentralen Einstiegspunkt ermöglichen Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 93

Front Controller nimmt alle Anfragen an die Webanwendung entgegen führt alle zentralen Arbeiten durch Weiterleitung der Anfrage an zuständige Objekte, welche die Antwort erzeugen erfordert gesonderte Klassen zur Kapselung der Daten von Anfrage (Request) und Antwort (Response) Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 94

Front Controller Viele verschiedene Implementierungen verfügbar: Zend Framework Symfony WACT Stubbles... Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 95

Intercepting Filter Problem: Sie möchten Logik hinzufügen, die bei jedem Request ausgeführt werden soll. Authentifizierung, Logging, URL-Rewriting, etc. Front-Controller soll jedoch nicht dafür modifiziert werden müssen Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 96

Intercepting Filter Intercepting Filter filtert Anfragen an eine Applikation. Kann als Prä- oder Post-Prozessor eingesetzt werden Kann damit sowohl Anfrage als auch Antwort filtern Kann in eine Filterkette integriert werden Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 97

Intercepting Filter interface Filter { public function execute(request $req, Response $resp); class AuthFilter implements Filter { public function execute(request $req, Response $resp) { $authdata = $req->gethttpauth(); if (!$this->authdatamatches($authdata)) { $request->cancel(); $response->senderror(); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 98

Intercepting Filter Intercepting Filter ist eine Spezialisierung des Command-Patterns Filterkette kann einfach als Composite oder Decorator implementiert werden Controller sollte zwei Filter-Ketten haben, eine vor und eine nach der Verarbeitung Fügt dem Controller eine einfache Plugin- Schnittstelle hinzu Filter sind unabhängig voneinander, kann manchmal Probleme bereiten Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 99

Event Dispatcher Subject/Observer für konkreten Anwendungsfall nicht geeignet: Subject besitzt keinen Zustand Zustandsänderung oder weitere Verarbeitung soll abhängig von Observer sein Subject sollte nicht alle Observer kennen und selbst benachrichtigen müssen Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 100

Event Dispatcher Vermittler für Nachrichten von einem Absender zu beliebig vielen Adressaten Objekte registrieren sich beim Dispatcher für Nachrichten eines bestimmten Typs Dispatcher informiert Objekte automatisch über neue Nachrichten Absender kann abfragen, ob das Ereignis abgebrochen wurde Nachrichten können Kontextinformationen beinhalten (z.b. das Objekt, welches das Ereignis ausgelöst hat) Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 101

Event Dispatcher class Auth { public function login($user, $password) { // authenticate user $this->username = $username; $this->isvalid = true; $event = EventDispatcher::getInstance() ->trigger('onlogin', $this); if ($event->iscancelled() == true) { $this->username = null; $this->isvalid = false; Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 102

Event Dispatcher class UserLoginLogging implements EventListener {.. public function handleevent(event $event) { $this->log($event->gettime(), $event->getname(), $event->getcontext()->getusername()); class BlackList implements EventListener {... public function handleevent(event $event) { $auth = $event->getcontext(); if ($this->isblacklisted($auth->getusername()) == true) { $event->cancel(); $this->log($event->gettime(), $auth- >getusername()); Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 103

Event Dispatcher $eventdispatcher = EventDispatcher::getInstance(); $eventdispatcher->register(new BlackList(), 'onlogin'); $eventdispatcher->register(new UserLoginLogging(), 'onlogin'); $auth = new Auth(); $auth->login('mikey'); // user mikey eingeloggt $auth->login('schst'); // user schst geblockt // im Logfile: 2007-01-30 11:35:45 onlogin mikey 2007-01-30 12:11:57 cancelledlogin schst Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 104

Event Dispatcher extrem lose Kopplung zwischen Klassen beliebig viele Nachrichten und damit Kopplungen möglich Aber: Anwendung wird schwerer durchschaubar, da nicht unbedingt klar ist welches Ereignis zu welchen Folgen führt bzw. wann ein Ereignis wo ausgelöst wird (Dokumentation!) Typsicherheit für Nachrichten-Kontext nicht möglich Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 105

View-Schicht Kümmert sich um die Darstellung der Daten aus der Datenschicht Entkoppelt die Commands aus der Command-Control-Schicht von der Darstellung der Daten Ermöglicht, dass Designer die Darstellung verändert, ohne mit Business-Logik in Berührung zu kommen Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 106

Template-View Problem: HTML Code soll nicht mit echo oder Methodenaufrufen auf dem Response- Objekt erzeugt werden. HTML-Code soll komplett von Business- Logik getrennt sein und von unabhängigen Personen gepflegt werden können Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 107

Template-View Ein Template-View trennt den HTML-Code für die Darstellung von der Logik. Dazu werden Platzhalter für die Daten im HTML- Code eingefügt. Platzhalter werden vom Template-Objekt durch die tatsächlichen Daten ersetzt Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 108

Template-View PHP selbst wurde als Template-View implementiert. Mittlerweile wird PHP für weitaus mehr genutzt und es gibt verschiedene Template- View-Implementierungen pattemplate Smarty Zend_View Kein Code-Beispiel, um religiöse Diskussionen zu vermeiden Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 109

View-Helper Problem: Daten, die an den View übergeben werden, müssen vom View nochmal verändert werden können Datumswerte müssen in das regional übliche Format konvertiert werden Abschneiden langer Texte Diese Konvertierungen sollen nicht die Business-Logik "verschmutzen" Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 110

View-Helper View-Helper bieten Funktionalität, die in den Template-Views benötigt wird. Sie entkoppeln die Business-Logik von der Darstellung. Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 111

View-Helper Ursprünglich waren alle PHP-Funktionen als View-Helper gedacht: <p> Heute ist der <?php echo date('d.m.y', $date)?>. </p> Jede Template-Engine bietet mittlerweile eine Implementierung für View-Helper Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 112

Ende Vielen Dank für Ihre Aufmerksamkeit. Noch Fragen? php@frankkleine.de me@schst.net Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 113

Zu schnell? PHP Design Patterns O'Reilly Verlag http://www.phpdesignpatterns.de Slides des Workshops http://www.stubbles.net Frank Kleine & Stephan Schmidt, 1&1 Internet AG PHP Design Patterns 114