<?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; OOP</title>
	<atom:link href="http://blog.ebene7.com/schlagwort/oop/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>Programm to an Interface, Dude!</title>
		<link>https://blog.ebene7.com/2011/07/11/programm-to-an-interface-dude/</link>
		<comments>https://blog.ebene7.com/2011/07/11/programm-to-an-interface-dude/#comments</comments>
		<pubDate>Mon, 11 Jul 2011 04:00:12 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Qualitätssicherung]]></category>
		<category><![CDATA[Data Mapper]]></category>
		<category><![CDATA[Implementierung]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[Model]]></category>
		<category><![CDATA[OOP]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=2891</guid>
		<description><![CDATA[Heute mag ich mal ein einfaches Thema aufgreifen, welches jedoch noch nicht wirklich seinen Weg in die PHP-Welt gefunden hat. Es geht um Interfaces. Seit Version 5 kann man in PHP viele der lange vermissten OOP-Features nutzen, aber leider machen &#8230; <a href="https://blog.ebene7.com/2011/07/11/programm-to-an-interface-dude/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Heute mag ich mal ein einfaches Thema aufgreifen, welches jedoch noch nicht wirklich seinen Weg in die PHP-Welt gefunden hat. Es geht um Interfaces. Seit Version 5 kann man in PHP viele der lange vermissten OOP-Features nutzen, aber leider machen viele Entwickler dennoch einen großen Bogen darum.</p>
<p><span id="more-2891"></span>Als ich mich vor ein paar Jahren auf meine Java-Zertifizierung vorbereitet habe, ist mir ein Satz immer wieder begegnet: &#8220;Programm to an interface, not to an implementation!&#8221;. Klingt einfach, ist es auch.</p>
<p>Im Prinzip sagt das nur aus, dass man sich beim Entwickeln nur darauf verlassen sollte, was die jeweilig implementierten Interfaces an Funktionalität anbieten. Wie das ganze dann im Hintergrund implementiert ist, interessiert dann nicht mehr.</p>
<p>Ein kleines Beispiel aus der Praxis: In einem Shop (in dem Fall Magento) werden Bestellungen (Orders) gespeichert. Nun soll ein <a href="http://de.wikipedia.org/wiki/Enterprise_Resource_Planning" target="_blank">ERP-System</a> angebunden werden. Für beide Systeme gibt es entsprechende Models, mit denen die Daten verarbeitet werden können.</p>
<p>Soweit, so gut. Jetzt kommt der unbequeme Teil der Aufgabe. Das Magento-Order-Model erbt einfach nur von verschiedenen anderen Klassen, aber es existiert kein Interface, das dem Entwickler bestimmte Methoden garantiert. An vielen Stellen werden zudem die Parameter mit Type-Hinting überprüft, ob sie eine Magento-Order enthalten.</p>
<p>Das Model für die Anbindung an das ERP-System hat unter Umständen andere Elternklassen und somit auch erstmal keine Gemeinsamkeiten. Das bedeutet, dass wir theoretisch die Objekte gleich behandeln könnten, aber wir sie für das Type-Hinting doch wieder in Wrapper verpacken oder auf Magento-Order-Objekte mappen müssen.</p>
<p>Diese Arbeit könnte man sich komplett sparen, wenn man sich von Anfang an auf ein Interface verlassen hätte. Leider existiert dieses meines Wissens nicht und es für eigene Projekte zu nutzen würde Änderungen in den Magento-Core-Dateien fordern.</p>
<pre>&lt;?php
interface Mage_Sales_Model_Order_Interface
{
  /**
   * Retrieve customer model
   *
   * @return Mage_Customer_Model_Customer_Interface
   */
  public function getCustomer();

  // ...
}</pre>
<p>Damit könnte man sich auf verschiedene Methoden verlassen die der Typ Mage_Sales_Model_Order_Interface (!) zusagt.</p>
<pre>&lt;?php
class Mage_Sales_Model_Order
  extends Mage_Sales_Model_Abstract
  implements Mage_Sales_Model_Order_Interface
{
  // ...
}</pre>
<p>Die Klasse Mage_Sales_Model_Order könnte sich an diesen &#8220;Vertrag&#8221; halten,</p>
<pre>&lt;?php
class Erp_Sales_Model_Order
  extends Erp_Was_Auch_Immer_Model_Abstract
  implements Mage_Sales_Model_Order_Interface
{
  // ...
}</pre>
<p>sowie auch jede andere Klasse.</p>
<pre>&lt;?php
// ...
public function getEmailFromOrder(Mage_Sales_Model_Order_Interface $order)
{
  return $order-&gt;getCustomer()-&gt;getEmail();
}
// ...</pre>
<p>So können wir jede beliebige Klasse mit bestehenden Code weiterhin verarbeiten, ohne dass uns das Type-Hinting dabei im Weg steht. Was die Methode getCustomer() nun intern macht, ist uns egal, solange ein Objekt vom Typ Mage_Customer_Model_Customer_Interface zurückgegeben wird.</p>
<p>Es ist vielleicht auf den ersten Blick etwas umständlicher, für jeden Typ ein Interface zu schreiben, aber das spart man danach wieder locker ein und bleibt dazu auch in der weiteren Entwicklung seiner Anwendung flexibel.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2011/07/11/programm-to-an-interface-dude/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Wir brauchen echte Typen und keine Primitiven, oder?</title>
		<link>https://blog.ebene7.com/2011/01/05/wir-brauchen-echte-typen-und-keine-primitiven-oder/</link>
		<comments>https://blog.ebene7.com/2011/01/05/wir-brauchen-echte-typen-und-keine-primitiven-oder/#comments</comments>
		<pubDate>Wed, 05 Jan 2011 05:00:52 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Qualitätssicherung]]></category>
		<category><![CDATA[Datentypen]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[OOP]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=2408</guid>
		<description><![CDATA[Ich bin ein großer Fan objektorientierter Programmierung und wenn es nach mir ginge, würde ich auch nur Objekte verwenden. Aber nach mir geht es nicht, das Leben ist kein Ponyhof und ich habe mich so entschieden mein Geld mit PHP- &#8230; <a href="https://blog.ebene7.com/2011/01/05/wir-brauchen-echte-typen-und-keine-primitiven-oder/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Ich bin ein großer Fan objektorientierter Programmierung und wenn es nach mir ginge, würde ich auch nur Objekte verwenden.</p>
<p>Aber nach mir geht es nicht, das Leben ist kein Ponyhof und ich habe mich so entschieden mein Geld mit <a href="http://blog.ebene7.com/kategorie/entwicklung/php/" target="_self">PHP</a>- und nicht mit <a href="http://blog.ebene7.com/kategorie/entwicklung/java/" target="_self">Java</a>-Programmierung zu verdienen. Genug gejammert, worum geht es?<span id="more-2408"></span></p>
<p>In den letzten Tagen, Urlaub sei Dank, hatte ich etwas mehr Zeit mich durch die Blogwelt zu klicken und habe dabei einen älteren <a href="http://ajaveeb.de/string-klasse-version-1-0-1-331" target="_blank">Artikel von Benjamin</a> entdeckt, in dem er seine PHP-Stringklasse vorstellt. Etwas schmunzeln musste ich bei der Lizenz für die wenigen Zeilen Code, aber Ordnung muss sein. <img src='https://blog.ebene7.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Die Idee gefällt mir sehr gut keine primitiven Datentypen, sondern echte Objekte zu verwenden.</p>
<p>Inspiriert von der Idee, habe ich ein paar Minuten gebastelt und habe nun meine Custom_String-Klasse. Sie ist einfach umgesetzt, handlich und hat alles was <em>ich</em> brauche.</p>
<p>An der Stelle fiel mir dann auch gleich wieder ein, warum ich das bisher nicht umgesetzt habe.</p>
<p>Wer sich etwas mit Java auskennt, der weiß, dass sämtliche Objekte in gewisser Weise nach bestimmten Mustern funktionieren. Will ich meine <a href="http://blog.ebene7.com/2010/09/06/besser-sortieren-mit-php-dank-java-interfaces/" target="_self">Objekte sortieren</a> können, dann implementiere ich einfach das Interface Comparable und gut ist.</p>
<p>An dem Beispiel mit den Strings sollte das Problem klar werden. Benjamin hat eine Klasse für Strings geschrieben, wie er sie gerne hätte, ich habe das getan und viele andere vielleicht auch.</p>
<p>Jede für sich mag gut sein, aber auch etwas anders funktionieren und eine andere Schnittstelle bieten.</p>
<p>In großen Systemen kommen nun die Arbeiten vieler Entwickler zusammen, teilweise sogar aus verschiedenen Teams oder auch Firmen.</p>
<p>Um nun einheitlich mit allen Objekten arbeiten zu können, brauchen wir zwangsläufig <a href="http://blog.ebene7.com/2009/12/29/decorator-adapter-oder-proxy-was-bist-du-eigentlich/" target="_self">Adapter</a>-Klassen und haben damit weitere potentielle Schwachstellen im System. Wir müssten jedes Objekt an den Schnittstellen richtig verpacken und bauschen dadurch den Code auf und wir haben die Adapter-Klassen, die wir ebenfalls mit jeder Änderung der Originalklassen anpassen müssen.</p>
<p>Ich denke, solange PHP nicht im Kern ähnlich wie Java die entsprechenden Schnittstellen vorgibt, macht man sich das Entwicklerleben damit nicht wirklich leichter. Wie denkt ihr darüber?</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2011/01/05/wir-brauchen-echte-typen-und-keine-primitiven-oder/feed/</wfw:commentRss>
		<slash:comments>6</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>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>Response-Objekt vs. echo, die() und exit</title>
		<link>https://blog.ebene7.com/2010/06/17/response-objekt-vs-echo-die-und-exit/</link>
		<comments>https://blog.ebene7.com/2010/06/17/response-objekt-vs-echo-die-und-exit/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 05:00:15 +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[HTTP]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[Response]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=817</guid>
		<description><![CDATA[Eigentlich lohnt es sich ja fast nicht über etwas einfaches wie ein Response-Objekt einen Artikel zu schreiben. Fast, aber auch nur fast, denn die Praxis zeigt, dass es auch damit unerwartete Probleme geben kann. Alle, die bislang nur wenig oder &#8230; <a href="https://blog.ebene7.com/2010/06/17/response-objekt-vs-echo-die-und-exit/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Eigentlich lohnt es sich ja fast nicht über etwas einfaches wie ein Response-Objekt einen Artikel zu schreiben. Fast, aber auch nur fast, denn die Praxis zeigt, dass es auch damit unerwartete Probleme geben kann.</p>
<p><span id="more-817"></span>Alle, die bislang nur wenig oder keine Erfahrung mit MVC-Anwendungen gesammelt haben, werden sich vielleicht nun fragen, wofür dieses Objekt gut ist. Das Response-Objekt kontrolliert die komplette Ausgabe der Anwendung an den Client (z.B. einen Browser).</p>
<p>Während der kompletten Laufzeit können mit dem Objekt Ausgaben gesammelt und auch nachträglich verändert werden und auch die Reihenfolge spielt keine Rolle. So kann nun zuerst die Ausgabe gemacht werden und dann die Header gesetzt werden.</p>
<p>So müsste es klassisch mit PHP geschrieben werden:</p>
<pre><code>&lt;?php header('Content-type: text/xml'); echo $xml;</code></pre>
<p>Wenn wir nun die Reihenfolge vertauschen würden, hätte das eine Warning zur Folge.</p>
<pre><code>&lt;?php echo $xml; header('Content-type: text/xml');</code></pre>
<pre>Warning: Cannot modify header information - headers already sent by (output started at ####) in #### on line 3</pre>
<p>Wenn wir uns in einer MVC-Umgebung befinden, stellt diese Reihenfolge kein Problem dar, denn das Objekt verwaltet die Ausgabe und schickt alles zur rechten Zeit raus.</p>
<p>So könnte es dann z.B. in einer Action des Kontrollers aussehen:</p>
<pre><code>&lt;?php public function indexAction() { // ... $this-&gt;getResponse()-&gt;appendBody($xml); $this-&gt;getResponse()-&gt;setHeader('Content-type', 'text/xml'); } </code></pre>
<p>Neben den relativ harmlosen direkten Ausgaben mit echo oder print habe ich in den vergangenen Jahren auch Ausgaben mit die() gefunden. Die offensichtliche Arbeit verrichtet die Anwendung zwar in den Actions der Kontroller, aber es passiert unter Umständen auch vor- und nachher eine Menge. Letzteres würde dann unterbunden werden und evtl. wichtige Aufgaben nicht mehr abgearbeitet werden.</p>
<p>Ein Beispiel sah etwa so aus:</p>
<pre>&lt;?php
public function jsonAction()
{
  // ...
  header('Content-type: text/json');
  die($json);
  // ...
}</pre>
<p>Die Anwendung verliert so die Kontrolle über die Ausgabe und wird an der falschen Stelle beendet. Der richtige Weg führt auch hier zum Response-Objekt.</p>
<pre>&lt;?php
public function jsonAction()
{
  // ...
  $this-&gt;getResponse()-&gt;setHeader('COntent-type', 'text/json');
  $this-&gt;getResponse()-&gt;appendBody($json);
  return;  // &lt;== falls die Bearbeitung hier enden soll
  // ...
}</pre>
<p>So, nun gibt es in Zukunft keine Ausreden mehr, wenn irgendwo ein echo im Kontroller steht. Ich würde mich natürlich wie immer freuen eure Erfahrungen in den Kommentaren zu lesen.</p>
<p>Nebenbei bemerkt ist das mein 50. Artikel, also schon fast ein kleiner Grund zum Feiern. <img src='https://blog.ebene7.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2010/06/17/response-objekt-vs-echo-die-und-exit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
