<?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; Factory</title>
	<atom:link href="http://blog.ebene7.com/schlagwort/factory/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>Array als Parameterliste an den Konstruktor übergeben</title>
		<link>https://blog.ebene7.com/2011/03/21/array-als-parameterliste-an-den-konstruktor-uebergeben/</link>
		<comments>https://blog.ebene7.com/2011/03/21/array-als-parameterliste-an-den-konstruktor-uebergeben/#comments</comments>
		<pubDate>Mon, 21 Mar 2011 05:00:51 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tipps und Tricks]]></category>
		<category><![CDATA[Callback]]></category>
		<category><![CDATA[Factory]]></category>
		<category><![CDATA[Parameter]]></category>
		<category><![CDATA[Reflection]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=2797</guid>
		<description><![CDATA[In verschiedenen Fällen kann/muss man, z.B. Callback-Funktionen/Methoden mit einer variablen Parameterliste aufrufen. Was aber, wenn wir ein Objekt durch eine Factory erstellen wollen und der Konstruktor Parameter erwartet? Die Funktionen call_user_func() oder call_user_func_array() fallen leider aus, da wir noch kein &#8230; <a href="https://blog.ebene7.com/2011/03/21/array-als-parameterliste-an-den-konstruktor-uebergeben/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In verschiedenen Fällen kann/muss man, z.B. Callback-Funktionen/Methoden mit einer variablen Parameterliste aufrufen. Was aber, wenn wir ein Objekt durch eine Factory erstellen wollen und der Konstruktor Parameter erwartet?</p>
<p>Die Funktionen <a href="http://de2.php.net/manual/de/function.call-user-func.php" target="_blank">call_user_func()</a> oder <a href="http://de2.php.net/manual/de/function.call-user-func-array.php" target="_blank">call_user_func_array()</a> fallen leider aus, da wir noch kein Callback-Objekt haben. Es gibt aber einen sehr einfachen Weg mit Reflections.<span id="more-2797"></span></p>
<p>Zuerst ein paar einfache Klassen zum Testen. Von der Klasse Foo soll ein Objekt erstellt werden und diese erwartet je ein Objekt vom Typ Bar und Baz als Parameter im Konstruktor.</p>
<pre>&lt;?php
class Bar {}
class Baz {}

class Foo
{
  public function __construct(Bar $bar, Baz $baz)
  {
    echo '&lt;pre&gt;' . print_r(func_get_args(), true) . '&lt;/pre&gt;';
  }
}</pre>
<p>Nun wird das Objekt über eine sehr einfache Factory-Methode erzeugt und dabei wird die Parameterliste von create() an den Konstruktor weitergegeben.</p>
<pre>&lt;?php
class Factory
{
  public static function create($type)
  {
    $args = func_get_args();
    array_shift($args);
    $class = new ReflectionClass($type);
    return $class-&gt;newInstanceArgs($args);
  }
}

$foo = Factory::create('Foo', new Bar(), new Baz());</pre>
<p>So einfach ist es. Über die Reflection-Klasse wird ein neues Objekt erzeugt.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2011/03/21/array-als-parameterliste-an-den-konstruktor-uebergeben/feed/</wfw:commentRss>
		<slash:comments>2</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>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>
		<item>
		<title>Einfache UnitTests für Magento</title>
		<link>https://blog.ebene7.com/2010/08/24/einfache-unittests-fur-magento/</link>
		<comments>https://blog.ebene7.com/2010/08/24/einfache-unittests-fur-magento/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 05:00:39 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Qualitätssicherung]]></category>
		<category><![CDATA[AutoLoader]]></category>
		<category><![CDATA[Factory]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[PHPUnit]]></category>
		<category><![CDATA[Reflection]]></category>
		<category><![CDATA[Shop]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Zend_CodeGenerator]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=1118</guid>
		<description><![CDATA[Seit nun knapp fünf Monaten stelle ich mich der Herausforderung saubere Softwareentwicklung und Magento in Einklang zu bringen. Ein kleiner Schritt in diese Richtung war der Einsatz von UnitTests, um mögliche Fehler während der Entwicklung schneller zu finden. Viele Fehler &#8230; <a href="https://blog.ebene7.com/2010/08/24/einfache-unittests-fur-magento/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Seit nun knapp fünf Monaten stelle ich mich der Herausforderung saubere Softwareentwicklung und Magento in Einklang zu bringen. Ein kleiner Schritt in diese Richtung war der Einsatz von UnitTests, um mögliche Fehler während der Entwicklung schneller zu finden.</p>
<p><span id="more-1118"></span>Viele Fehler treten bei Magento schon durch eine fehlerhafte Konfiguration auf, was zur Folge haben kann, dass wir keine Instanz unser lokalisierten Klasse bekommen, sondern ein standard Magento-Objekt oder einen Fehler, weil keine passende Klasse gefunden wird.</p>
<p>So habe ich also angefangen, die Existenz der zu prüfenden Klassen zu testen und ob die Mage-Factory das gewünschte Objekt zurück gibt. Bei einigen Klassen ist es zudem auch noch wichtig, dass sie von der richtigen Elternklasse abgeleitet sind.</p>
<p>Da sich diese Tests immer wiederholten, zeichnete sich schnell ein Muster ab. Ebenso erfolgt auch die Namesgebung der Magentoklassen nach einem gewissen Muster. Was wäre also naheliegender, als beides miteinander zu verbinden und so in Zukunft eine Menge unnützer Schreibarbeit zu sparen?</p>
<p>Als erstes habe ich dafür einen erweiteren TestCase vom PHPUnit-TestCase abgeleitet, der mir weitere vereinfachte Asserts zur Verfügung stellt und die Tests dadurch auch etwas lesbarer macht.</p>
<pre>$this-&gt;assertClassExists($classname);</pre>
<p>statt</p>
<pre>$this-&gt;assertTrue(class_exists($classname));</pre>
<p>Auf diesem Wege lassen sich dann auch z.B. Getter und Setter einfach auf das gewünschte Standardverhalten prüfen.</p>
<p>Im nächsten Schritt habe ich einen Entity-TestCase abgeleitet, der als Basis für alle weiteren TestCases für Models, Blocks und Helper dienen soll. Dieser ist in sich schon ein wenig intelligenter und erkennt anhand des Namens der Test-Klasse, welche Klasse getestet werden soll, welchen Typ diese hat und welche die Standard-Elternklasse ist.</p>
<p>Diese Informationen werden, nebenbei bemerkt, durch protected Methoden ermittelt und könnten zu jeder Zeit durch noch speziellere TestCases wieder überschrieben werden.</p>
<p>Mit den nun vorliegenden Informationen ist diese TestCase-Klasse mächtig genug, um alleine durch Vererbung die grundlegenden Tests durchzuführen.</p>
<p>Für die jeweiligen Typen, z.B. Model habe ich dann noch weitere TestCases abgeleitet, um dort noch spezielle Methoden implementieren zu können.</p>
<p>Ein sehr einfacher Test für die Model-Klasse &#8220;Mein_Customer_Model_Customer&#8221; sähe dann beispielsweise so aus:</p>
<pre>class Mein_Customer_Model_CustomerTest extends Mein_Model_TestCase
{
}</pre>
<p>Dadurch würde nun automatisch getestet werden, ob der Autoloader die Klasse &#8220;Mein_Customer_Model_Customer&#8221; finden kann, diese von der Magento-Model-Klasse erbt und ob die Factory aufgrund der Konfiguration auch das richtige Objekt liefert.</p>
<p>Ich denke, dass es viel einfacher nicht mehr geht und das Argument gegen Tests damit dann auch aus der Welt sein sollte.</p>
<p>Kleiner Tipp: Wenn man es nun noch etwas konfortabler mag, dann kann man sich seine Models auch mit dem Zend_CodeGenerator bauen lassen und die Tests gleich mit.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2010/08/24/einfache-unittests-fur-magento/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
