<?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; Proxy</title>
	<atom:link href="http://blog.ebene7.com/schlagwort/proxy/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>Ausgelagerte Ablaufkontrolle dank Retry-Proxy</title>
		<link>http://blog.ebene7.com/2011/08/11/ausgelagerte-ablaufkontrolle-dank-retry-proxy/</link>
		<comments>http://blog.ebene7.com/2011/08/11/ausgelagerte-ablaufkontrolle-dank-retry-proxy/#comments</comments>
		<pubDate>Thu, 11 Aug 2011 04:00:09 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Qualitätssicherung]]></category>
		<category><![CDATA[Exception-Handling]]></category>
		<category><![CDATA[Funktion]]></category>
		<category><![CDATA[Methode]]></category>
		<category><![CDATA[Proxy]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=2910</guid>
		<description><![CDATA[Neulich bin ich während der Arbeit auf ein kleines Problem gestoßen, welches sich eigentlich sehr einfach lösen lies. Da ich diese Lösung aber nicht wirklich toll fand und ja auch schon länger keinen Artikel mehr geschrieben habe, habe ich mir &#8230; <a href="http://blog.ebene7.com/2011/08/11/ausgelagerte-ablaufkontrolle-dank-retry-proxy/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Neulich bin ich während der Arbeit auf ein kleines Problem gestoßen, welches sich eigentlich sehr einfach lösen lies. Da ich diese Lösung aber nicht wirklich toll fand und ja auch schon länger keinen Artikel mehr geschrieben habe, habe ich mir also ein paar Gedanken dazu gemacht und schreibe heute zum Thema <a href="http://blog.ebene7.com/2009/12/29/decorator-adapter-oder-proxy-was-bist-du-eigentlich/" target="_blank">Proxy</a>.<span id="more-2910"></span></p>
<p>Was ist aber eigentlich passiert? Für eine bestimmte Aufgabe musste ich Daten in der SimpleDB (Amazon Webservices) zwischengespeichern und dann an anderer Stelle weiter verarbeitet. Nun passiert es hin und wieder, dass meine Weiterleitung schneller als die Datenbank war und ich die Daten (noch) nicht lesen konnte.</p>
<p>Was macht man in diesem Fall? Abwarten, Tee trinken und nochmal probieren. In dem Fall kamen ein paar Zeilen Code dazu und alles lief wie gewünscht. Wirklich schick ist das jedoch so noch nicht.</p>
<p>Erstmal eine einfach Beipielklasse im PHP-Pseudocode zum besseren Verständnis:</p>
<pre>&lt;?php
class SomeWebResource
{
  public function load($key)
  {
    // do something
    return $data;
  }

  public function save($key, $data)
  {
    // do something
    return $flag;
  }

  public function delete($key)
  {
    // do something
    return $flag;
  }
}</pre>
<p>In diesem Beispiel hat unsere Klasse drei Methoden, in denen die selben oder zumindest ähnliche Probleme auftreten können. Die Daten haben das falsche Format, der Webservice ist nicht erreichbar oder was auch immer.</p>
<p>Für diesen Fall bauen wir dann nun die Wiederholung ein.</p>
<pre>&lt;?php
class SomeWebResource
{
  public function load($key)
  {
    $count = 0;
    do {
      try {
        // do something
        return $data;
      } catch (Exception $e) {
        sleep(1);
      }
    } while (3 &gt; $count++);
  }

  public function save($key, $data)
  {
    $count = 0;
    do {
      try {
        // do something
        return $flag;
      } catch (Exception $e) {
        sleep(1);
      }
    } while (3 &gt; $count++);
  }

  public function delete($key)
  {
    $count = 0;
    do {
      try {
        // do something
        return $flag;
      } catch (Exception $e) {
        sleep(1);
      }
    } while (3 &gt; $count++);
  }
}</pre>
<p>Spontan sollten nun jedem mindestens drei Dinge auffallen. Der Code ist gleich um etliche Zeilen länger und wiederholt sich, man könnte fast ein Muster (Pattern) erkennen. Der Code ist nicht wirklich flexibel, wenn es darum geht die Wartezeit oder die Anzahl der Versuche zu konfigurieren. Der Code ist immer da und lässt sich so nicht mehr ohne die Wiederholung ausführen und es ist nicht die Aufgabe dieser Klasse die Wiederholungen zu kontrollieren.</p>
<p>In dem Fall schreit es doch gerade danach, diesen Code recyclebar auszulagern, findet ihr nicht?</p>
<p>Dafür brauchen wir nur eine einfache Proxy-Klasse. Ok, bevor jetzt jemand protestiert, dass sei doch garnicht das Proxy-Pattern, stimmt! Wir leiten die Proxy-Klasse nicht von der Klasse &#8220;SomeWebResource&#8221; ab und haben dadurch eine andere Schnittstelle. In diesem Fall ist das aber egal, denn wir leiten ja auch nur den Methodenaufruf weiter.</p>
<p>Nun aber erstmal die <a href="http://blog.ebene7.com/download/code/E7/Tools/RetryProxy.txt" target="_blank">RetryProxy</a>-Klasse:</p>
<pre>&lt;?php
class E7_Tools_RetryProxy
{
  // some other methods

  public function call($callback)
  {
    $exception = null;
    $count = 0;
    $args = func_get_args();
    array_shift($args);

    do {
      try {
        return call_user_func_array($callback, $args);
      } catch (Exception $e) {
        $exception = $e;
        sleep($this-&gt;getDelay());
      }
    } while ($this-&gt;getRepititions() &gt; $count++);

    if ($exception instanceof Exception) {
      throw $exception;
    }
  }
}</pre>
<p>Auch hier lässt sich natürlich das selbe Muster erkennen, aber wir haben es von jeder weitern Logik entkoppelt und die gewünschten Werte lassen sich nun einfach über die Setter einstellen.</p>
<p>Die Verwendung ist später ebenfalls einfach.</p>
<pre>&lt;?php
$proxy = new E7_Tools_RetryProxy();
$swr   = new SomeWebResource();
$data  = $proxy-&gt;call(array($swr, 'load'), 42);</pre>
<p>Wer damit etwas experimentieren will, findet die komplette Klasse <a href="http://blog.ebene7.com/download/code/E7/Tools/RetryProxy.txt" target="_self">hier</a>. Wie immer freue ich mich natürlich über möglichst zahlreiche Kommentare.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ebene7.com/2011/08/11/ausgelagerte-ablaufkontrolle-dank-retry-proxy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Decorator, Adapter oder Proxy &#8211; Was bist du eigentlich?</title>
		<link>http://blog.ebene7.com/2009/12/29/decorator-adapter-oder-proxy-was-bist-du-eigentlich/</link>
		<comments>http://blog.ebene7.com/2009/12/29/decorator-adapter-oder-proxy-was-bist-du-eigentlich/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 09:00:49 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Entwicklung]]></category>
		<category><![CDATA[Adapter]]></category>
		<category><![CDATA[Decorator]]></category>
		<category><![CDATA[Dekorierer]]></category>
		<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[Entwurfsmuster]]></category>
		<category><![CDATA[Proxy]]></category>
		<category><![CDATA[Stellvertreter]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=101</guid>
		<description><![CDATA[Für alle denen beim Lesen des Titels nichts dazu eingefallen ist, es geht in diesem Artikel um Entwurfsmuster, genauer um die Strukturmuster Decorator, Adapter und Proxy. Häufig kommt es vor, dass diese drei Muster aufgrund gewisser oberflächlicher Ähnlichkeiten verwechselt oder &#8230; <a href="http://blog.ebene7.com/2009/12/29/decorator-adapter-oder-proxy-was-bist-du-eigentlich/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Für alle denen beim Lesen des Titels nichts dazu eingefallen ist, es geht in diesem Artikel um <a href="http://de.wikipedia.org/wiki/Entwurfsmuster" target="_blank">Entwurfsmuster</a>, genauer um die Strukturmuster <a href="http://de.wikipedia.org/wiki/Decorator" target="_blank">Decorator</a>, <a href="http://de.wikipedia.org/wiki/Adapter_(Entwurfsmuster)" target="_blank">Adapter</a> und <a href="http://de.wikipedia.org/wiki/Stellvertreter_(Entwurfsmuster)" target="_blank">Proxy</a>.</p>
<p>Häufig kommt es vor, dass diese drei Muster aufgrund gewisser oberflächlicher Ähnlichkeiten verwechselt oder pauschal zum Decorator gemacht werden.</p>
<p>Dabei verfolgen alle drei doch recht unterschiedliche Ziele und die will ich heute möglichst kurz gegenüberstellen.</p>
<p><span id="more-101"></span>Zunächst klären wir erstmal was die drei gemeinsam haben. Alle drei Muster kontrollieren den Zugriff auf ein Objekt.</p>
<h3>Decorator</h3>
<p>Das wichtigste Merkmal eines Decorators ist, dass er den Typ des zu dekorierenden Objektes nicht verändert. Wollen wir also ein Animalobjekt dekorieren, dann muss unser Dekorierer von Animal <a href="http://de.wikipedia.org/wiki/Vererbung_%28objektorientierte_Programmierung%29" target="_blank">erben</a> und alle Methodenaufrufe an das in ihm gekapselte Objekt delegieren.</p>
<p>Beim Weiterleiten der Methodenaufrufe kann nun das Verhalten verändert werden und das ohne <a href="http://de.wikipedia.org/wiki/Vererbung_%28objektorientierte_Programmierung%29" target="_blank">Vererbung</a> zur Laufzeit.</p>
<p>Methoden können quasi abgeschaltet werden, indem sie nicht weiterleiten. Andere Methoden könnten die Werte vor dem Weiterleiten verändern. Auch neue, zusätzliche Methoden sind möglich.</p>
<h4>Beispiele</h4>
<ul>
<li>Streams (in Java)</li>
<li>Verändern von GUI-Elementen</li>
</ul>
<h3>Adapter</h3>
<p>Im Gegensatz zum Decorator verändert der Adapter gewollt den Typ des gekapselten Objektes. Das Muster eignet sich, um bestehende Komponenten an eine neue Schnittstelle anzupassen.</p>
<p>Wenn sich die Katze also wie eine Kuh verhalten soll&#8230;</p>
<pre>class CatToCowAdapter extends Cow {
  private Cat cat;

  // andere Methoden

  public void muh() {
    this.cat.miau();
  }
}</pre>
<h3>Proxy</h3>
<p>Ein Proxy ist ein Stellvertreter für die &#8220;echten&#8221; Objekte, wenn diese zum Beispiel nicht sofort verfügbar sind oder nicht alle Ressourcen freigeben dürfen. Soll zum Beispiel ein Bild in einer GUI-Anwendung über das Netzwerk geladen werden, würde das ggf. die Anwendung während der Ladezeit ausbremsen.</p>
<p>Ein ImageProxy könnte in einem eigenen Thread auf das Bild warten und in der Zwischenzeit eine Ersatzgrafik anzeigen (animierte Sanduhr etc.).</p>
<p>Über Proxy-Objekte lässt sich auch der Zugriff auf Datenstrukturen kontrollieren. Dabei würde der Proxy kontrollieren, wem das Datenobjekt gehört und nur die dementsprechenden Lese- und Schreibzugriffe erlauben.</p>
<h4>Beispiele</h4>
<ul>
<li>Laden von Ressourcen</li>
<li>Kontrollieren von Daten</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.ebene7.com/2009/12/29/decorator-adapter-oder-proxy-was-bist-du-eigentlich/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
