<?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; Interface</title>
	<atom:link href="http://blog.ebene7.com/schlagwort/interface/feed/" rel="self" type="application/rss+xml" />
	<link>http://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>Sortieren mit PHP5 Closures und dem Java Comparator Pattern</title>
		<link>http://blog.ebene7.com/2012/08/31/sortieren-mit-php5-closures-und-dem-java-comparator-pattern/</link>
		<comments>http://blog.ebene7.com/2012/08/31/sortieren-mit-php5-closures-und-dem-java-comparator-pattern/#comments</comments>
		<pubDate>Fri, 31 Aug 2012 04:00:13 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Callback]]></category>
		<category><![CDATA[Closure]]></category>
		<category><![CDATA[Comparator]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Sortierung]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=3421</guid>
		<description><![CDATA[Was mich schon oft bei PHP ein wenig störte ist, dass es zum Sortieren nicht so schöne Comparatoren wie in Java gibt. Nun habe ich in der Vergangenheit ja schon das eine oder andere über Closures in PHP und Java &#8230; <a href="http://blog.ebene7.com/2012/08/31/sortieren-mit-php5-closures-und-dem-java-comparator-pattern/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Was mich schon oft bei PHP ein wenig störte ist, dass es zum Sortieren nicht so schöne Comparatoren wie in Java gibt.</p>
<p>Nun habe ich in der Vergangenheit ja schon das eine oder andere über <a href="http://blog.ebene7.com/2012/01/30/closures-in-php/">Closures in PHP</a> und <a href="http://blog.ebene7.com/2010/09/06/besser-sortieren-mit-php-dank-java-interfaces/">Java Comparatoren für PHP</a> geschrieben und wollte das nun mal zusammenbringen.</p>
<p><span id="more-3421"></span>Einige PHP-Sortierfunktionen erlauben Callbacks, um die Reihenfolge zu bestimmen. Da ich das Ganze aber gerne in gut testbaren OOP-Einheiten hätte, müssen wir einen kleinen Umweg gehen.</p>
<p>Zunächst das obligatorische Interface.</p>
<pre>namespace E7;

interface Comparator {
  public function compare($a, $b);
}</pre>
<p>Diese Schnittstelle implementieren wir mit einer abstrakten Klasse.</p>
<pre>namespace E7;

class BaseComparator implements Comparator {
  public function compare($a, $b) {
    if ($a == $b) { return 0; }
    return $a &lt; $b ? -1 : 1;
  }

  public function __invoke() {
    return call_user_func_array(array($this, 'compare'), func_get_args());
  }
}</pre>
<p>Und schon haben wir einen einfachen, und zugegebenermaßen nicht typsicheren, Comparator.</p>
<p>Durch die magische Methode __invoke() kann ein Objekt nun wie eine Callbackfunktion verwendet werden.</p>
<p>Für die Sortierung von Objekten kann das dann einfach erweitert werden.</p>
<pre>class PersonComparator extends BaseComparator {
  public function compare($a, $b) {
    // hier Prüfung auf Typ etc.
    return parent::compare($a-&gt;getId(), $b-&gt;getId());
  }    
}</pre>
<p>Um die Sortierreihenfolge negieren zu können, können wir einen einfachen Wrapper nutzen.</p>
<pre>class ReverseOrder implements Comparator {
  private $_comparator;

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

  public function compare($a, $b) {
    return $this-&gt;_comparator-&gt;compare($a, $b) * -1;
  }
}</pre>
<p>Beispiel&#8230;</p>
<pre>//--
$people = array();
for ($i = 0; $i &lt; 10; $i ++) {
  $people[] = new Person();
}

echo 'BEFORE&lt;br/&gt;';
foreach($people as $person) {
  echo "$person&lt;br/&gt;";
}

$comparator = new ReverseOrder( new PersonComparator() );

uasort($people, function($a, $b) use ($comparator) {
    return $comparator-&gt;compare($a, $b);
});

// oder

uasort($people, $comparator);

echo 'AFTER&lt;br/&gt;';
foreach($people as $person) {
  echo "$person&lt;br/&gt;";
}</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ebene7.com/2012/08/31/sortieren-mit-php5-closures-und-dem-java-comparator-pattern/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Closures in PHP</title>
		<link>http://blog.ebene7.com/2012/01/30/closures-in-php/</link>
		<comments>http://blog.ebene7.com/2012/01/30/closures-in-php/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 05:00:58 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Callback]]></category>
		<category><![CDATA[Closure]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[SPL]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=3364</guid>
		<description><![CDATA[Ab der Version 5.3 bietet auch PHP, wie auch schon viele andere Sprachen, die Möglichkeit mit anonymen Funktionen zu arbeiten. Dadurch können z.B. Callback-Funktionen zur Filterung o.Ä. implementiert werden, ohne dass man sich dafür tolle Namen ausdenken muss. Aber was &#8230; <a href="http://blog.ebene7.com/2012/01/30/closures-in-php/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Ab der Version 5.3 bietet auch PHP, wie auch schon viele andere Sprachen, die Möglichkeit mit <a href="http://www.php.net/manual/de/functions.anonymous.php" target="_blank">anonymen Funktionen</a> zu arbeiten. Dadurch können z.B. Callback-Funktionen zur Filterung o.Ä. implementiert werden, ohne dass man sich dafür tolle Namen ausdenken muss. Aber was kann man damit noch machen?</p>
<p><span id="more-3364"></span>Bislang musste man Callback-Funktionen gewöhnlich definieren, bevor man sie verwenden konnte.</p>
<pre>&lt;?php
function myCallback($output) {
  return '##' . $output . '##';
}

echo call_user_func('myCallback', 'Hallo Welt');

// Ausgabe:
##Hallo Welt##</pre>
<p>Als Closure geschrieben sähe das dann so aus:</p>
<pre>&lt;?php
echo call_user_func(
  function($output) { return '##' . $output . '##'; },
  'Hallo Welt');

// Ausgabe:
##Hallo Welt##</pre>
<p>Zugegeben, dieses Beispiel hätte man durch einfache Stringverkettung wesentlich einfacher schreiben können und eigentlich war das mit <a href="http://de2.php.net/manual/de/function.create-function.php" target="_blank">create_function()</a> auch schon unter PHP4 möglich.</p>
<p>Wir können die Funktion natürlich wie früher auch schon in einer Variablen speichern und dann weiter verwenden.</p>
<pre>&lt;?php
$myFunction = function($output) {
  return '##' . $output . '##';
};

echo call_user_func($myFunction, 'Hallo Welt') . '&lt;br/&gt;';
echo $myFunction('Hallo Welt') . '&lt;br/&gt;';

//Ausgabe:
##Hallo Welt##
##Hallo Welt##</pre>
<p>Und auch das ist ja noch nichts Neues. Mit Closures haben wir nun aber auch die Möglichkeit, teile unserer &#8220;Umgebung&#8221; zum Zeitpunkt der Funktionsdefinition zu konservieren.</p>
<p>Dazu müssen wir nur die Definition etwas erweitern.</p>
<pre>&lt;?php
$before = '&gt;';
$after = '&lt;';

$myFunction = function($output) use ($before, $after) {
    return $before . $output . $after;
};

echo $myFunction('Hallo Welt') . '&lt;br/&gt;';

//Ausgabe:
&gt;Hallo Welt&lt;</pre>
<p>An dieser Stelle frieren wir mit &#8220;use&#8221; sozusagen die Werte für $before und $after innerhalb unserer Funktion ein. Spätere Änderungen der beiden Variablen haben keine Auswirkungen auf die Funktion.</p>
<pre>$before = 'foo';
$after = 'bar';
echo $myFunction('Hallo Welt') . '&lt;br/&gt;';

//Ausgabe:
&gt;Hallo Welt&lt;</pre>
<p>In PHP wir mittlerweile sehr viel mit Standardinterfaces und -klassen (SPL) abgedeckt und so ist es auch in diesem Fall. In der Variablen $myFunction ist ein Objekt vom Typ &#8220;<a href="http://de2.php.net/manual/en/class.closure.php" target="_blank">Closure</a>&#8221; gespeichert.</p>
<pre>&lt;?php
echo '&lt;pre&gt;' . print_r($myFunction, true) . '&lt;/pre&gt;';

//Ausgabe:
Closure Object
(
  [static] =&gt; Array
    (
      [before] =&gt; &gt;
      [after] =&gt; &lt;
    )
  [parameter] =&gt; Array
    (
      [$output] =&gt;
    )
)</pre>
<p>Will man eigene Objekte wie Funktionen aufrufen, dann geht das mit der magischen Methode <a href="http://de2.php.net/manual/de/language.oop5.magic.php#language.oop5.magic.invoke" target="_blank">__invoke()</a>, die auch hier verwendet wird.</p>
<p>Anfangs erwähnte ich, dass Closure-Callbacks zur Filterung, aber auch zur Manipulation von Array verwendet werden können.</p>
<p>Wenn nur der Inhalt interessant ist, dann kommen wir mit array_map() und einem Parameter aus.</p>
<pre>&lt;?php
$values = array(
  array(
    'a' =&gt; array(
      'b' =&gt; 'foo'
    )
  ),
  array(
    'a' =&gt; array(
      'b' =&gt; 'bar'
    )
  ),
);

$filtered = array_map(
  function ($item) { return $item['a']['b']; },
  $values
);
echo '&lt;pre&gt;' . print_r($filtered, true) . '&lt;/pre&gt;';

// Ausgabe:
Array
(
  [0] =&gt; foo
  [1] =&gt; bar
)</pre>
<p>Wollen wir aber Werte im Array in Abhängigkeit zum Key/Index verändern, dann geht das mit array_walk und einem zweiten Parameter im Callback. Bei beiden kann natürlich auch &#8220;use&#8221; verwendet werden. Der Parameter $value wird dabei als Referenz übernommen.</p>
<pre>$values = array(
  'a' =&gt; 100,
  'b' =&gt; 200,
  'c' =&gt; 300,
);

array_walk(
  $values,
  function (&amp;$value, $key) {
    if ('b' == $key) {
      $value = 42;
    }
  }
);

echo '&lt;pre&gt;' . print_r($values, true) . '&lt;/pre&gt;';

// Ausgabe:
Array
(
  [a] =&gt; 100
  [b] =&gt; 42
  [c] =&gt; 300
)</pre>
<p>Ich hoffe, dass ich ein wenig Licht ins Dunkel bringen konnte und &#8220;Closure&#8221; nun kein geheimnisvolles Zauberwort mehr ist.</p>
<p>Wenn ihr noch gute Ergänzungen oder Anwendungbeispiele habt, dann immer her damit und bitte fleissig kommentieren. <img src='http://blog.ebene7.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ebene7.com/2012/01/30/closures-in-php/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Programm to an Interface, Dude!</title>
		<link>http://blog.ebene7.com/2011/07/11/programm-to-an-interface-dude/</link>
		<comments>http://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="http://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>http://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>http://blog.ebene7.com/2011/01/05/wir-brauchen-echte-typen-und-keine-primitiven-oder/</link>
		<comments>http://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="http://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='http://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>http://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>SPL: Iterator vs. IteratorAggregate</title>
		<link>http://blog.ebene7.com/2010/12/01/spliterator-vs-iteratoraggregate/</link>
		<comments>http://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="http://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>http://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>http://blog.ebene7.com/2010/09/06/besser-sortieren-mit-php-dank-java-interfaces/</link>
		<comments>http://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="http://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>http://blog.ebene7.com/2010/09/06/besser-sortieren-mit-php-dank-java-interfaces/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Weniger Code-Redundanz durch Design Patterns</title>
		<link>http://blog.ebene7.com/2010/08/27/weniger-code-redundanz-durch-design-patterns/</link>
		<comments>http://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="http://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>http://blog.ebene7.com/2010/08/27/weniger-code-redundanz-durch-design-patterns/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
