<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ebene7 &#187; Entwurfsmuster</title>
	<atom:link href="http://blog.ebene7.com/schlagwort/entwurfsmuster/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.ebene7.com</link>
	<description></description>
	<lastBuildDate>Tue, 04 Jun 2013 18:57:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>TemplateMethod vs. method_exists()-Prüfung</title>
		<link>https://blog.ebene7.com/2012/01/11/templatemethod-vs-method-exists-pruefung/</link>
		<comments>https://blog.ebene7.com/2012/01/11/templatemethod-vs-method-exists-pruefung/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 07:00:07 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Qualitätssicherung]]></category>
		<category><![CDATA[Benchmark]]></category>
		<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[Entwurfsmuster]]></category>
		<category><![CDATA[Template Method]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=3295</guid>
		<description><![CDATA[Das Entwurfsmuster TemplateMethod kennen und nutzen sicherlich viele von euch. Spätestens, wenn irgendein Framework im Einsatz ist, hat man in der Regel damit zu tun, um z.B. an verschiedenen Stellen im Code eigene Funktionen in einen Ablauf einzuhängen. Das Prinzip &#8230; <a href="https://blog.ebene7.com/2012/01/11/templatemethod-vs-method-exists-pruefung/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Das Entwurfsmuster <a href="http://de.wikipedia.org/wiki/Template_Method" target="_blank">TemplateMethod</a> kennen und nutzen sicherlich viele von euch. Spätestens, wenn irgendein Framework im Einsatz ist, hat man in der Regel damit zu tun, um z.B. an verschiedenen Stellen im Code eigene Funktionen in einen Ablauf einzuhängen.<span id="more-3295"></span></p>
<p>Das Prinzip ist einfach: in der (abstrakten) Basisklasse wird eine leere Methode definiert, die durch eine konkrete Klasse überschrieben werden kann.</p>
<p>Der Vorteil ist recht offensichtlich. Die Methode kann ohne vorherige Prüfung verwendet werden und das spart an vielen Stellen unnötigen Code. Aus meinem ästhetischem Empfinden der richtige Weg.</p>
<p>Aber auch den anderen Weg habe ich auch schon desöfteren gesehen und mein Bauchgefühl hat ja auch nicht immer recht. Vielleicht ist der schöne Weg ja auch der langsamere?</p>
<p>Gefühl ist gut, Zahlen sind besser! Also habe ich schnell drei Testklassen geschrieben und probiere die verschiedenen Möglichkeiten durch.</p>
<p>Variante 1: Wir verlassen uns darauf, dass die Methode aufgerufen werden kann.</p>
<pre>&lt;?php
class Test1 {
    public function machWas() {
        $this-&gt;machWasAnderes();
    }

    public function machWasAnderes() {
    }
}</pre>
<p>Variante 2: Wir prüfen, ob die Methode existiert und finden nichts.</p>
<pre>&lt;?php
class Test2 {
    public function machWas() {
        if (method_exists($this, 'machWasAnderes')) {
            $this-&gt;machWasAnderes();
        }
    }
}</pre>
<p>Variante 3: Wir prüfen, ob die Methode existiert und rufen sie auf.</p>
<pre>&lt;?php
class Test3 {
    public function machWas() {
        if (method_exists($this, 'machWasAnderes')) {
            $this-&gt;machWasAnderes();
        }
    }

    public function machWasAnderes() {
    }
}</pre>
<p>Zum Vergleich habe ich das folgende Script verwendet.</p>
<pre>&lt;?php
foreach (array('Test1', 'Test2', 'Test3') as $class) {
    $object = new $class();
    $start = microtime(true);

    for($i=0; $i&lt;100000; $i++) {
        $object-&gt;machWas();
    }
    echo $class . ' = ' . round(microtime(true) - $start, 5) . '&lt;br/&gt;';
}</pre>
<p>Ausgabe:</p>
<pre>Test1 = 0.44767
Test2 = 0.48588
Test3 = 0.70881</pre>
<p>In mehreren Durchläufen waren &#8220;Test1&#8243; und &#8220;Test2&#8243; immer fast gleich auf, nur &#8220;Test3&#8243; brauchte etwas länger, weil in der Klasse die Prüfung und die Ausführung der Methode stattfindet.</p>
<p>Fazit: Der Einsatz von Schablonenmethoden lohnt sich doppelt, da der Code übersichtlich bleibt und auch die Geschwindigkeit etwas besser ist.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2012/01/11/templatemethod-vs-method-exists-pruefung/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Faule Models und große Datenmengen</title>
		<link>https://blog.ebene7.com/2010/12/13/faule-models-und-grosse-datenmengen/</link>
		<comments>https://blog.ebene7.com/2010/12/13/faule-models-und-grosse-datenmengen/#comments</comments>
		<pubDate>Mon, 13 Dec 2010 05:00:46 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[CustomLibrary]]></category>
		<category><![CDATA[Custom_Model]]></category>
		<category><![CDATA[Data Mapper]]></category>
		<category><![CDATA[Datenbank]]></category>
		<category><![CDATA[Entwurfsmuster]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[Model]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[OOP]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=1536</guid>
		<description><![CDATA[Unter verschiedenen Umständen kann es vorteilhaft sein, wenn Models nicht vollständig geladen und mit Daten befüllt werden, weil das Lesen zu komplex ist (Stichwort EAV-Model) oder wir mit sehr vielen Datensätzen arbeiten und dabei Speicherplatz sparen wollen/müssen. Gleichzeitig wollen wir &#8230; <a href="https://blog.ebene7.com/2010/12/13/faule-models-und-grosse-datenmengen/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Unter verschiedenen Umständen kann es vorteilhaft sein, wenn Models nicht vollständig geladen und mit Daten befüllt werden, weil das Lesen zu komplex ist (Stichwort EAV-Model) oder wir mit sehr vielen Datensätzen arbeiten und dabei Speicherplatz sparen wollen/müssen.</p>
<p>Gleichzeitig wollen wir aber zu jeder Zeit sicherstellen, dass wir das Model wie gewohnt vollständig abfragen und verwenden können. An dieser Stelle kommt eine Technik namens LazyLoading (lazy = engl. faul, träge) zum Einsatz.</p>
<p><span id="more-1536"></span></p>
<p>Nun konstruiere ich einfach ein Beispiel, um den Ablauf besser erklären zu können. In unserer Anwendung brauchen wir ein Model &#8220;Person&#8221;, das Informationen wie Name, Geburtstag und diverse andere speichern kann. Den Namen und den Geburtstag brauchen wir immer (z.B. in der Listenansicht) und die restlichen Felder nur wenn wir eine Detailansicht erstellen.</p>
<p>Wie kommt unser Model nun an die Daten? In der Regel wird sicherlich load() auf dem Modelobjekt aufgerufen oder eine vergleichbare Methode auf der jeweiligen Collection, dann werden die Daten über ein Resourcemodel geladen und letztendlich komplett auf die einzelnen Modelobjekte kopiert.</p>
<p>Um unser Vorhaben umzusetzen müssen wir das etwas abändern. Die Methode load() des Models funktioniert wie gewohnt und lädt alle Daten und die Collection nur die Nötigsten. Um nun sicherzustellen, dass wir trotzdem immer alles abrufen können, muss das Model etwas intelligenter werden.</p>
<p>Die Entwicklung des <a href="http://blog.ebene7.com/schlagwort/custom_model/" target="_self">Custom_Model</a>s hat der eine oder andere ja vielleicht mitbekommen und kennt den grundlegenden Aufbau. Relativ neu ist die Klasse Custom_Model_Persistent, durch die eine weitere Unterscheidung zwischen einfachen Datencontainern und speicherbaren Models möglich wird.</p>
<p>Für das automatische Nachladen muss die Modelklasse nun erweitert werden.</p>
<pre>&lt;?php
class Custom_Model_Persistent extends Custom_Model
{
  private $_isLoaded;

  // ...

  public function load($value = null, $field = 'id')
  {
    if (null === $value &amp;&amp; $this-&gt;_isset($field)) {
      $value = $this-&gt;_get($field);
    }

    $this-&gt;getResource()
         -&gt;loadModel($this, $value, $this-&gt;_mapKey($field))
         -&gt;markLoaded();

    return $this;
  }

  public function isLoaded()
  {
    return $this-&gt;_isLoaded;
  }

  public function markLoaded()
  {
    $this-&gt;_isLoaded = true;
    return $this;
  }

  protected function _get($key, $default = null)
  {
    if (!$this-&gt;_isset($key) &amp;&amp; !$this-&gt;isLoaded()) {
      $this-&gt;load();
    }
    return parent::_get($key, $default);
  }
}</pre>
<p>Die entscheidenen Stellen sind hier der überschriebene zentrale Getter, der ein das &#8220;Default-Load()&#8221; auslöst, wenn der Wert nicht gesetzt ist und die Daten auch noch nicht vollständig geladen wurden und die Methode load() mit optionalen Parameter $value.</p>
<p>Im Beispiel verlasse ich mich darauf, dass das Standardfeld schon gesetzt ist. Eine ordentliche Fehlerbehandlung muss aber unbedingt her, wenn wir das ganze produktiv einsetzen wollen.</p>
<p>Die Methoden isLoaded() bzw markLoaded() sind absichtlich public, damit sie z.B. aus einer Collection aufgerufen werden können, wenn das Model komplett geladen wurde. Eine weitere Möglichkeit wäre ein Vergleich mit einer Liste die gesetzt sein sollten.</p>
<p>Im Moment ist das noch etwas im Entwurf und sogar ungetestet. Wenn euch nun noch was dazu einfällt, dann schreibt einen Kommentar. Wo seht ihr für euch die Vor- oder evtl. auch die Nachteile?</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2010/12/13/faule-models-und-grosse-datenmengen/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>SPL: Iterator vs. IteratorAggregate</title>
		<link>https://blog.ebene7.com/2010/12/01/spliterator-vs-iteratoraggregate/</link>
		<comments>https://blog.ebene7.com/2010/12/01/spliterator-vs-iteratoraggregate/#comments</comments>
		<pubDate>Wed, 01 Dec 2010 05:00:58 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Entwurfsmuster]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[Iterator]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[Schleife]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=2224</guid>
		<description><![CDATA[PHP bietet mit der SPL (StandardPHPLibrary) eine Vielzahl fertiger Iteratoren an, mit denen Daten in Schleifen verarbeitet werden können, aber auch zwei Interfaces durch die eigene Objekte iterierbar werden. Ganz klar, es handelt sich um die Interfaces Iterator und IteratorAggregate. &#8230; <a href="https://blog.ebene7.com/2010/12/01/spliterator-vs-iteratoraggregate/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>PHP bietet mit der <a href="http://www.php.net/~helly/php/ext/spl/" target="_blank">SPL (StandardPHPLibrary)</a> eine Vielzahl fertiger Iteratoren an, mit denen Daten in Schleifen verarbeitet werden können, aber auch zwei Interfaces durch die eigene Objekte iterierbar werden.</p>
<p>Ganz klar, es handelt sich um die Interfaces Iterator und IteratorAggregate. Was aber unterscheidet die beiden?</p>
<p><span id="more-2224"></span></p>
<p>Um den Aufbau der beiden Klassen gegenüberzustellen habe ich zwei einfache Beispiel-Klassen geschrieben, mit denen wir ein Array in einer foreach-Schleife auslesen können.</p>
<h3>Iterator</h3>
<p>Das Interface Iterator schreibt fünf Methoden vor, die zur Verarbeitung des Objektes in einer Schleife benötigt werden: <code>current(), next(), key(), valid()</code> und <code>rewind()</code>.</p>
<pre>&lt;?php
class TestA implements Iterator
{
  private $_items;

  public function __construct(array $items = array())
  {
    $this-&gt;_items = $items;
  }

  public function current()
  {
    return current($this-&gt;_items);
  }

  public function next()
  {
    next($this-&gt;_items);
  }

  public function key()
  {
    return key($this-&gt;_items);
  }

  public function valid()
  {
    return false !== current($this-&gt;_items);
  }

  public function rewind()
  {
    reset($this-&gt;_items);
  }
}</pre>
<p>Auf den ersten Blick lässt sich erkennen, dass relativ viel Code benötigt benötigt wird und dieser starr am Objekt hängt. Ok, für diesen Zweck hätte man auch den ArrayIterator nehmen können, aber dann gäbe es weniger zu gucken.</p>
<h3>IteratorAggregate</h3>
<p>Das zweite Iterface ist dagegen wesentlich schlanker, denn es kommt mit der einzigen Methode <code>getIterator()</code> aus.</p>
<pre>&lt;?php
class TestB implements IteratorAggregate
{
  private $_items;

  public function __construct(array $items = array())
  {
    $this-&gt;_items = $items;
  }

  public function getIterator()
  {
    return new ArrayIterator($this-&gt;_items);
  }
}</pre>
<p>Die Methode erzeugt einen externen Iterator und lagert damit die Funktionalität in eine andere Klasse aus. Dadurch bleibt unsere Klasse übersichtlich und das Iterator-Verhalten lässt sich einfach austauschen.</p>
<h3>Fazit</h3>
<p>Für einfache Strukturen würde ich das IteratorAggregate-Interface vorziehen, da es sehr einfach aufgebaut ist und unseren Code schlank und übersichtlich hält. Die Funktionalität ist zudem durch verschiedene externe Klassen variabel und viele Standardfälle können mit den SPL-Klassen abgedeckt werden.</p>
<p>Lässt sich eine Struktur aus irgendeinem Grund nicht an einen externen Iterator übergeben, bzw. will man für diesen speziellen Fall schreiben, dann kommt das Iterator-Interface zum Einsatz.</p>
<p>Genaugenommen lässt sich das mit den beiden Beispielklassen schon gut testen. Einfach in der Klasse TestB</p>
<pre>public function getIterator()
{
  return new ArrayIterator($this-&gt;_items);
}</pre>
<p>gegen</p>
<pre>public function getIterator()
{
  return new TestA($this-&gt;_items);
}</pre>
<p>austauschen und etwas damit rumspielen.</p>
<p>In der Anwendung sind beide später identisch:</p>
<pre>&lt;?php
$a = new TestA(array('A','B','C','D','E'));

foreach ($a as $k =&gt; $v) {
  echo "$k = $v &lt;br/&gt;";
}

$b = new TestB(array('A','B','C','D','E'));

foreach ($b as $k =&gt; $v) {
  echo "$k = $v &lt;br/&gt;";
}</pre>
<p>Viel Spaß damit! Eure Erkenntnisse zu dem Thema könnt ihr wie immer gerne in den Kommentaren verewigen&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2010/12/01/spliterator-vs-iteratoraggregate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fluently self-contained Factory Method</title>
		<link>https://blog.ebene7.com/2010/09/29/fluently-self-contained-factory-method/</link>
		<comments>https://blog.ebene7.com/2010/09/29/fluently-self-contained-factory-method/#comments</comments>
		<pubDate>Wed, 29 Sep 2010 05:00:02 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Grundlagen]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Qualitätssicherung]]></category>
		<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[Entwurfsmuster]]></category>
		<category><![CDATA[Factory]]></category>
		<category><![CDATA[Singleton Pattern]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=1510</guid>
		<description><![CDATA[Nein, wir spielen nicht Buzzword-Bingo. Heute geht es darum, Objekt-Instanzen durch einfache Factory Methoden zu erzeugen und sie im Weiteren als Fluent Interface direkt zu nutzen, ohne den Stolperstein &#8220;new&#8221; und ob das in der Form überhaupt sinnvoll ist. Der &#8230; <a href="https://blog.ebene7.com/2010/09/29/fluently-self-contained-factory-method/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Nein, wir spielen nicht Buzzword-Bingo. Heute geht es darum, Objekt-Instanzen durch einfache Factory Methoden zu erzeugen und sie im Weiteren als Fluent Interface direkt zu nutzen, ohne den Stolperstein &#8220;new&#8221; und ob das in der Form überhaupt sinnvoll ist.</p>
<p><span id="more-1510"></span>Der herkömmliche Weg eine Instanz einer Klasse zu erzeugen ist die Verwendung des new-Operators.</p>
<pre>&lt;?php
$meinObject = new MeineKlasse();
$meineKlasse-&gt;machWas();</pre>
<p>Leider funktioniert Methodenverkettung in PHP nicht wie in Java direkt nach &#8220;new&#8221; und wir müssen uns mit einer statischen Methode behelfen. Das Prinzip ähnelt dem Singleton-Muster, jedoch wollen wir in diesem Fall bei jedem Aufruf eine neue Instanz bekommen. Wer schonmal mit (Borland-)Delphi gearbeitet hat, der kennt das sicher schon.</p>
<pre>&lt;?php
class MeineKlasse
{
  public static function create()
  {
    return new self();
  }
}</pre>
<p>Der Vorteil ist nun ganz klar der, dass sich Instanzen in einer Zeile benutzen lassen.</p>
<pre>&lt;?php
MeineKlasse::create()-&gt;machWas();</pre>
<p>Leider fallen mir aber auch spontan zwei Nachteile ein: Bis PHP 5.3 ist die Methode nicht vererbbar, das bedeutet, dass wir die Methode mit jeder Ableitung erneut überschreiben müssten. Ab Version 5.3 kann statt &#8220;self&#8221; dann &#8220;static&#8221; instanziiert werden. Genaueres findet sich auch in den Links in meinem <a href="http://blog.ebene7.com/2010/08/30/vererbbares-singleton-pattern-dank-late-static-binding-ab-php-5-3/">Singleton-Artikel</a>.</p>
<p>Der zweite Nachteil ist genau der, warum man auch &#8220;new&#8221; nicht verwenden sollte. Beides schafft an vielen Stellen im Code Abhängigkeitet zu einer bestimmten Klasse. Wenn nun irgendwann eine abgeleitete Klasse benötigt wird müssen viele Änderungen gemacht werden.</p>
<p>Im Zweifelsfall sollte auf eine klassische, externe Factory zurückgegriffen werden, um derartigen Problemen im Voraus aus dem Weg zu gehen.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2010/09/29/fluently-self-contained-factory-method/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Besser Sortieren mit PHP dank Java Interfaces</title>
		<link>https://blog.ebene7.com/2010/09/06/besser-sortieren-mit-php-dank-java-interfaces/</link>
		<comments>https://blog.ebene7.com/2010/09/06/besser-sortieren-mit-php-dank-java-interfaces/#comments</comments>
		<pubDate>Mon, 06 Sep 2010 05:00:46 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Dekorierer]]></category>
		<category><![CDATA[Entwurfsmuster]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[Sortierung]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=1344</guid>
		<description><![CDATA[PHP und Java haben aus meiner Sicht vieles gemeinsam, sei es nun die ähnliche Syntax oder der zu unrecht schlechte Ruf beider Sprachen. Spätestens jedoch wenn es um die Sortierung von beliebigen Objekten geht zeigt sich deutlich, dass Java die &#8230; <a href="https://blog.ebene7.com/2010/09/06/besser-sortieren-mit-php-dank-java-interfaces/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>PHP und Java haben aus meiner Sicht vieles gemeinsam, sei es nun die ähnliche Syntax oder der zu unrecht schlechte Ruf beider Sprachen. Spätestens jedoch wenn es um die Sortierung von beliebigen Objekten geht zeigt sich deutlich, dass Java die Nase vorn hat.</p>
<p>Ein Grund mehr mal über den PHP-Tellerrand zu spicken und einen kleine Ausflug in die Java-Welt zu machen.<span id="more-1344"></span></p>
<p>PHP bietet zwar mit diversen Array-Funktionen schon einige Möglichkeiten der Sortierung an, diese sind aber doch recht starr und man stößt schnell an gewisse Grenzen, wenn man mehr als nur einfache Datentypen sortieren will, da sowohl die Sortierlogik, wie auch der Vergleich der Objekte sind nach außen in einer Funktion zusammengefasst sind.</p>
<p>Wie funktioniert das denn nun in der Java-Welt? In Java müssen Objekte durch das Interface &#8220;Comparable&#8221; als sortierbar gekennzeichnet werden. Die meisten Standardklassen implementieren das bereits.</p>
<p>Das Interface schreibt die Methode &#8216;compareTo&#8221; vor, die es dem Objekt erlaubt, sich mit anderen Objekten zu vergleichen. Der Rückgabewert kann 1, 0 oder -1 sein.</p>
<p>Dazu ein kleines Beispiel:</p>
<p>Leider gibt ist in der SPL noch kein derartiges Interface vorhanden, also schreibe ich es einfach mal selbst.</p>
<pre>&lt;?php
interface Custom_Compareable
{
  public function compareTo($object);
}</pre>
<p>Dann brauchen wir noch ein Objekt zum Vergleichen.</p>
<pre>&lt;?php
class Person implements Custom_Comparable
{
  private $_id;
  private $_vorname;
  private $_nachname;
  private $_geburtsdatum;

  public function __construct($id)
  {
    $this-&gt;_id = $id;
  }

  //  Getter und Setter...

  public function compareTo($object)
  {
    if (!$object instanceof Person) {
      throw new InvalidArgumentException();
    }

    if ($this-&gt;_id &lt; $object-&gt;_id) {
      return -1;
    } else if ($this-&gt;_id == $object-&gt;_id) {
      return 0;
    } else {
      return 1;
    }
  }
}</pre>
<p>Damit können nun Objekte vom Typ Person standardmäßig nach ihrer Id unabhängig vom Suchalgorithmus sortiert werden.</p>
<pre>&lt;?php
$p1 = new Person(3);
$p2 = new Person(2);

if ($p1-&gt;compareTo($p2) &lt; 0) {
  // swap($p1, $p2)
}</pre>
<p>Bis jetzt haben wir zwar schon die Sortierlogik vom Vergleich der Objekte lösen können, aber trotzdem noch nicht viel gewonnen, da nur die Ids verglichen werden. Für abweichende Sortierungen lässt sich der Vergleich nun auch noch vom Personen-Objekt lösen. Dafür bietet Java das Interface &#8220;Comparator&#8221; an, bei uns wird es nun das Custom_Comparator-Interface.</p>
<pre>&lt;?php
interface Custom_Comparator
{
  public function compare($object1, $object2);
}</pre>
<p>Die Methode &#8220;compare()&#8221; hat die gleichen Rückgabewerte wie &#8220;compareTo()&#8221; und kann dadurch genauso verwendet werden.</p>
<pre>&lt;?php
class PersonComparatorVorname implements Custom_Comparator
{
  public function compare($object1, $object2)
  {
    if (!$object1 instanceof Person || !$object2 instanceof Person) {
      throw new InvalidArgumentException();
    }

    if ($object1-&gt;getVorname() &lt; $object2-&gt;getVorname()) {
      return -1;
    } else if ($object1-&gt;getVorname() == $object2-&gt;getVorname()) {
      return 0;
    } else {
      return 1;
    }
  }
}</pre>
<p>Durch diese beiden Interfaces haben wir nun die Möglichkeit, unsere Objekte beliebig sortieren zu lassen. Über die Wertigkeit der Objekte entscheidet nun das Objekt selbst, bzw. ein passender Comparartor. Wie die Objekte letztendlich sortiert werden ist egal, da die Logik an einer anderen Stelle implementiert wird und nun für alle Objekte gleich funktioniert, wenn diese &#8220;Comparable&#8221; sind.</p>
<pre>&lt;?php
$listeMitPersonen = array(new Person(1), new Person(2));
$comparator = new PersonComparatorVorname();

// die Funktionen stehen als Pseudocode
bubblesort($listeMitPersonen);
bubblesort($listeMitPersonen, $comparator);

quicksort($listeMitPersonen);
quicksort($listeMitPersonen, $comparator);</pre>
<p>Und auch die Logik für auf- oder absteigende Reihenfolge lässt sich komplett getrennt dank Dekorator-Pattern auslagern.</p>
<pre>&lt;?php
class ReverseComparator implements Custom_Comparator
{
  private $_comparator;

  public function __construct(Custom_Comparator $comparator)
  {
    $this-&gt;_comparator = $comparator;
  }

  public function compare($object1, $object2)
  {
    return $this-&gt;_comparator-&gt;compare($object1, $object2) * (-1);
  }
}</pre>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2010/09/06/besser-sortieren-mit-php-dank-java-interfaces/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Vererbbares Singleton-Pattern dank Late Static Binding ab PHP 5.3</title>
		<link>https://blog.ebene7.com/2010/08/30/vererbbares-singleton-pattern-dank-late-static-binding-ab-php-5-3/</link>
		<comments>https://blog.ebene7.com/2010/08/30/vererbbares-singleton-pattern-dank-late-static-binding-ab-php-5-3/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 05:00:54 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[Entwurfsmuster]]></category>
		<category><![CDATA[Late Static Binding]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[Singleton Pattern]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=1310</guid>
		<description><![CDATA[Ob man das Singleton-Pattern nun mag oder nicht, es ist einfach in gewissen Situationen recht handlich und aus meiner Sicht auch nicht wirklich so böse wie es oft dargestellt wird, vorausgesetzt natürlich man weiß was man tut. Wirklich störend war &#8230; <a href="https://blog.ebene7.com/2010/08/30/vererbbares-singleton-pattern-dank-late-static-binding-ab-php-5-3/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Ob man das Singleton-Pattern nun mag oder nicht, es ist einfach in gewissen Situationen recht handlich und aus meiner Sicht auch nicht wirklich so böse wie es oft dargestellt wird, vorausgesetzt natürlich man weiß was man tut.</p>
<p>Wirklich störend war aus meiner Sicht bislang nur, dass sich das Singleton nicht vererben ließ. Dank <a href="http://php.net/manual/de/language.oop5.late-static-bindings.php" target="_blank">Late Static Binding</a> seit PHP Version 5.3 ist nun auch das möglich.</p>
<p>Dazu habe ich vor ein paar Tagen einen guten <a href="http://blog.gi-project.de/2010/08/singleton-dank-late-static-binding-vererbbar/" target="_blank">Artikel von Julian</a> gefunden und auch noch einen englischsprachigen im <a href="http://www.brandonsavage.net/a-lesson-in-static-methods-and-late-static-binding/" target="_blank">Blog von Brandon</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2010/08/30/vererbbares-singleton-pattern-dank-late-static-binding-ab-php-5-3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Weniger Code-Redundanz durch Design Patterns</title>
		<link>https://blog.ebene7.com/2010/08/27/weniger-code-redundanz-durch-design-patterns/</link>
		<comments>https://blog.ebene7.com/2010/08/27/weniger-code-redundanz-durch-design-patterns/#comments</comments>
		<pubDate>Fri, 27 Aug 2010 05:00:27 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Qualitätssicherung]]></category>
		<category><![CDATA[CustomLibrary]]></category>
		<category><![CDATA[Custom_Model]]></category>
		<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[Entwurfsmuster]]></category>
		<category><![CDATA[Factory]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[Strategy Pattern]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=1287</guid>
		<description><![CDATA[Heute habe ich eine Artikel für euch, der mir besonders gefällt, weil er auf einfache Weise mehrere interessante Themen vereint. Und, wie sollte es auch anders sein, geht es wieder um unsere Models, um Entwurfsmuster und den Weltfrieden. *hust* Bevor &#8230; <a href="https://blog.ebene7.com/2010/08/27/weniger-code-redundanz-durch-design-patterns/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Heute habe ich eine Artikel für euch, der mir besonders gefällt, weil er auf einfache Weise mehrere interessante Themen vereint. Und, wie sollte es auch anders sein, geht es wieder um unsere Models, um Entwurfsmuster und den Weltfrieden. *hust*</p>
<p>Bevor ich aber nun der Miss World 2010 die Scherpe streitig mache, fange ich lieber mal an&#8230;</p>
<p><span id="more-1287"></span>Stellen wir uns mal vor, wir haben ein Meta-Model, welches verschiedene allgemeine Daten zu einem anderen Objekt speichern kann.</p>
<pre>&lt;?php
class MetaModel extends Custom_Model
{
  protected $_ownerId;
  protected $_creatorId;
  protected $_modifierId;
  protected $_createDate;
  protected $_modifyDate;

  // Weitere Felder und Getter/Setter
}</pre>
<p>Die ersten drei Felder sind jeweils UserIds und die anderen zwei Datumswerte, die wir über gewöhnliche Getter und Setter verändern können. Damit können wir schonmal mit den Daten arbeiten, jedoch leider nicht objektorientiert navigieren.</p>
<p>Mit Navigation meine ich einen einfachen und für Menschen leicht lesbaren Zugriff auf die Objekte. Im Prinzip nur eine einfache Methodenverkettung.</p>
<pre>&lt;?php
$ownerName = $object-&gt;getMeta()-&gt;getOwner()-&gt;getName();</pre>
<p>Anders herum will ich vielleicht auch die Möglichkeit haben ein Datum als String oder als Objekt zu setzen und will ganz sicher nicht in jedem einzelnen Setter die Unterscheidung implementieren.</p>
<p>Die Lösung ist denkbar einfach. Wir lagern den benötigten Code einfach aus! Wer sich etwas mit Design Patterns beschäftigt, der erkennt sicher das <a href="http://de.wikipedia.org/wiki/Strategy_Pattern" target="_blank">Strategy Pattern</a> wieder.</p>
<p>Als erstes definieren wir eine einfache Schnittstelle und bauen uns dannach einen &#8220;Accessor&#8221;.</p>
<pre>&lt;?php
interface Custom_Model_Access_Interface
{
  public function get($value);
  public function set($value);
}</pre>
<pre>&lt;?php
class Custom_Model_Access_User implements Custom_Model_Access_Interface
{
  /**
   * @param int $value
   * @return UserModel
  public function get($value)
  {
    // UserModel laden ($value==ID)
  }

  /**
   * @param mixed int|UserModel
   * @return int (UserId)
   */
  public function set($value)
  {
    // $value-&gt;getId() zurückgeben, wenn $value ein UserModel ist, sonst $value
  }
}</pre>
<p>Damit haben wir, wenn auch stark vereinfacht, die Logik ausgelagert und können sie nun in der Modelklasse nutzen. Für viele dieser Access-Objekte reicht eine Instanz aus, die wir am besten über eine einfache <a href="http://de.wikipedia.org/wiki/Factory_Pattern" target="_blank">Factory</a> erzeugen.</p>
<p>In unserem Model sieht das dann wie folgt aus.</p>
<pre>&lt;?php
class MetaModel extends Custom_Model
{
  // ...
  private $_accessUser;

  public function init()
  {
    $this-&gt;_accessUser = Custom_Model_Access_Factory::singleton('User');
  }

  public function getOwner()
  {
    return $this-&gt;_accessUser-&gt;get( $this-&gt;getOwnerId() );
  }

  public function setOwner($owner)
  {
    return $this-&gt;setOwnerId( $this-&gt;_accessUser-&gt;set($owner) );
  }
}</pre>
<p>Nach diesem Muster würden nun auch die Methoden für creator und modifier geschrieben werden. An dieser Stelle wäre auch ein einfacher Cache möglich, damit das Objekt nicht bei jedem Aufruf erneut instanziiert werden muss.</p>
<p>Das Access-Objekt für das Datum könnte unter Umständen etwas umfangreicher werden.</p>
<p>Der Getter sollte uns ein Datums-Objekt zurückgeben anhand des in der Datenbank (oder wo auch immer) gespeicherten Werten, egal in welchem Format dieser vorliegt.</p>
<p>Der Setter auf der andern Seite könnte z.B. sämtlichen gängigen Datums-Objekte und Stringformate kennen und diese in das übliche Y-m-d H:i:s-Format übersetzen.</p>
<p>Zusammenfassend lässt sich festhalten, dass sich diese Technik für alle möglichen Bereiche geeignet ist, wenn man Objekte zu den Ids haben möchte oder auch Formate umwandeln will oder muss (Datum, IP-Adressen etc.).</p>
<p>Wenn euch noch etwas sinnvolles zur Verwendung einfällt oder einfach noch Fragen oder Kritik offen sind, dann freue ich mich über Kommentare.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2010/08/27/weniger-code-redundanz-durch-design-patterns/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
