<?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>Softwareplaudertäschchen</title>
	<atom:link href="http://www.codeschneider.de/feed" rel="self" type="application/rss+xml" />
	<link>http://www.codeschneider.de</link>
	<description>Einer wird es schon cool finden</description>
	<lastBuildDate>Fri, 11 Nov 2011 18:41:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Daily Activity</title>
		<link>http://www.codeschneider.de/programmierereien/android/daily-activity</link>
		<comments>http://www.codeschneider.de/programmierereien/android/daily-activity#comments</comments>
		<pubDate>Fri, 17 Jun 2011 13:44:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://www.codeschneider.de/?p=575</guid>
		<description><![CDATA[Mein Ziel: Eine garantierte Activity pro Tag, nämlich wenn das Smartphone angeschaltet wird und die Activity zum Einschaltdatum noch nicht aufgerufen wurde. Solche Dinge sollte man natürlich sehr bewusst programmieren, um keinen Benutzer zu nerven. In diesem Fall bin ich aber der Benutzer.
In der Referenz des Android SDK finde ich ein Systemereignis, welches in Frage [...]]]></description>
			<content:encoded><![CDATA[<p>Mein Ziel: Eine garantierte Activity pro Tag, nämlich wenn das Smartphone angeschaltet wird und die Activity zum Einschaltdatum noch nicht aufgerufen wurde. Solche Dinge sollte man natürlich sehr bewusst programmieren, um keinen Benutzer zu nerven. In diesem Fall bin ich aber der Benutzer.<br />
In der Referenz des Android SDK finde ich ein Systemereignis, welches in Frage kommt, um von einem <em>Broadcast Receiver</em> empfangen zu werden: <code>ACTION_SCREEN_ON</code>. Während ich mittels der <em>AndroidManifest.xml</em> für viele Ereignisse ganz zentral Broadcast Receiver während der Installation einer Anwendung im Betriebssystem registrieren kann, ist dies aber ausgerechnet für dieses Ereignis nicht möglich. Ich habe einige Codebeispiele gesehen, in denen Broadcast Receiver in der <code>OnCreate</code> von Activities registriert wurden. Doch möchte ich den Receiver von der aufgerufenen Activity entkoppeln. Nach weiterer Suche entdecke ich das Ereignis <code>ACTION_USER_PRESENT</code>, welches auch ein mittels der AndroidManifest.xml registrierter Broadcast Receiver empfangen kann.</p>
<p>Wird das Ereignis mit nachfolgendem <code>ActivityLauncher</code> empfangen, wird das Datum des heutigen Tages mit dem eingelesenen Datum aus einer Datei verglichen. Unterscheiden sich die Angaben, wird das aktuelle Datum in die Datei geschrieben und die Activity wird aufgerufen.</p>
<pre class="brush: java;">
public class ActivityLauncher extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        if (! (intent.getAction().equals(Intent.ACTION_USER_PRESENT)))
          return;

        String date = GetDateFromFile(context);

        Date dateNow = new Date ();
        SimpleDateFormat dateformatYYYYMMDD = new SimpleDateFormat(&quot;yyyyMMdd&quot;);
        StringBuilder nowYYYYMMDD = new StringBuilder( dateformatYYYYMMDD.format( dateNow ) );
        String now = nowYYYYMMDD.toString();

        if (date.compareTo(now) != 0)
        {
          WriteCurrentDateToFile(context, now);

            Intent startActivity = new Intent();
            startActivity.setClass(context, MyActivity.class);
            startActivity.setAction(MyActivity.class.getName());
            startActivity.setFlags(
                    Intent.FLAG_ACTIVITY_NEW_TASK
                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
            context.startActivity(startActivity);
        }
    }
}
</pre>]]></content:encoded>
			<wfw:commentRss>http://www.codeschneider.de/programmierereien/android/daily-activity/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hallo, Shared SQLite DB</title>
		<link>http://www.codeschneider.de/programmierereien/android/hallo-shared-sqlite-db</link>
		<comments>http://www.codeschneider.de/programmierereien/android/hallo-shared-sqlite-db#comments</comments>
		<pubDate>Sat, 11 Jun 2011 10:13:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://www.codeschneider.de/?p=563</guid>
		<description><![CDATA[Nachdem ich nun die fundamentalen Dinge über die Android-Entwicklung gelesen habe, mache ich mir jetzt die Hände schmutzig. Ich habe die ersten Beispiele und Tutorials aus den einschlägigen Quellen, nämlich developer.android.com, Hello, Android von Ed Burnette und Professional Android Development von Reto Meier ausprobiert, und komme zu dem Ergebnis, dass ich meine Hände auch schmutzig [...]]]></description>
			<content:encoded><![CDATA[<p>Nachdem ich nun die fundamentalen Dinge über die Android-Entwicklung gelesen habe, mache ich mir jetzt die Hände schmutzig. Ich habe die ersten Beispiele und Tutorials aus den einschlägigen Quellen, nämlich <em><a rel="nofollow" href="http://developer.android.com">developer.android.com</a></em>, <em>Hello, Android</em> von <em>Ed Burnette</em> und <em>Professional Android Development</em> von <em>Reto Meier</em> ausprobiert, und komme zu dem Ergebnis, dass ich meine Hände auch schmutzig lassen kann. Schließlich geht es hier um Best Practices und die Beispiele haben vorbildlichen Character.<br />
Wie man schon am Hello World-Tutorial erkennen kann, trennt man das Layout seiner Oberfläche am Besten in Form von XML vom Inhalt ab. Ähnlich geht man in der Webentwicklung vor, wo man HTML von CSS trennt. In der Android-Entwicklung hat das den Vorteil, dass man verschiedene Layouts für verschiedene Bildschirme und Geräte entwickeln kann und dabei vom Android SDK auch unterstützt wird.<br />
Auch der Lokalisierung wird von Anfang an Rechnung getragen, indem Textstrings der Oberfläche nur per ID aus dem Layout referenziert werden. Für jede Sprache stellt Google eine Dateierweiterung bereit, so dass die Textstrings aus der richtigen Datei eingelesen werden.</p>
<p>Nun stelle ich mir die Frage, wie ich Daten zwischen Activities teilen kann. Mein erster Gedanke war, die Daten in Form einer XML-Datei zu speichern und für die Anwendung in eine Objektstruktur einzulesen, so dass eine schneller Zugriff möglich ist. Ein bevorzugter Weg, Persistenz in Android zu ermöglichen, ist aber die Verwendung einer SQLite-Datenbank. Auf <a rel="nofollow" href="http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/">reigndesign</a> habe ich einen Weg gefunden eine Datenbank von außen beizusteuern. Statt die DB von innen über das Android-SDK anlegen zu müssen, kann ich die Datenbank in das <code>assets</code>-Verzeichnis des Projekts legen.</p>
<p>Ich realisiere meinen von <code>SQLiteOpenHelper</code> abgeleiteten <code>DBHelper</code> als Singleton. Auch wenn es nichts kosten mag, in jeder Activity einen DBHelper zu initialisieren, muss ich mit einem Singleton nicht einmal über die Kosten von Objekterzeugungen nachdenken, denn ein paar Zeilen Code für die Erstellung eines Singleton kosten schon gar nichts. Ich spare mir auch die Mühe, in jeder Activity an jeder in Frage kommenden Stelle des Activity-Lebenszyklus die Datenbank öffnen und schließen zu müssen. Stattdessen stelle ich in meiner abgeleiteten <code>Application</code>-Klasse <code>MyApplication</code> eine Referenz auf eine <code>DBHelper</code>-Instanz bereit, über die ich von jeder Activity aus auf die Datenbank zugreifen kann.</p>
<p>Der Zugriff aus der Activity sieht dann für einen schreibenden Zugriff etwa so aus:</p>
<pre class="brush: csharp;">

package org.example.hellosqlite;

import static android.provider.BaseColumns._ID;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.widget.TextView;

public class HelloSQLite extends Activity
{
	private static final String TITLE = &quot;title&quot;;
	public static final String TABLE_NAME = &quot;books&quot;;
	private static String[] FROM = { _ID, TITLE, };

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		addBook(&quot;Hello, Android! 3e&quot;);
	}

	private DataBaseHelper DBH()
	{
		MyApplication application = ((MyApplication)getApplicationContext());
		return application.GetDataBaseHelper();
	}

	private void addBook(String string)
	{
		SQLiteDatabase sqlitedb = DBH().getWritableDatabase();
		ContentValues values = new ContentValues();
		values.put(TITLE, string);
		sqlitedb.insertOrThrow(TABLE_NAME, null, values);
	}
}
</pre>]]></content:encoded>
			<wfw:commentRss>http://www.codeschneider.de/programmierereien/android/hallo-shared-sqlite-db/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reich mit Amazon Product Advertising API?</title>
		<link>http://www.codeschneider.de/programmierereien/reich-mit-amazon-product-advertising-api</link>
		<comments>http://www.codeschneider.de/programmierereien/reich-mit-amazon-product-advertising-api#comments</comments>
		<pubDate>Sat, 30 Apr 2011 09:58:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programmierereien]]></category>

		<guid isPermaLink="false">http://www.codeschneider.de/?p=552</guid>
		<description><![CDATA[Unter der Amazon Product Advertising API wird dem Programmierer eine Untermenge der Funktionalität des Amazon-Shops zur Verfügung gestellt. Amazon-Produktdaten können nahtlos in die eigene Website integriert werden. Produkte können z.B. in einen Warenkorb gelegt werden und der Besucher kann sich umfangreich über die Produkte informieren. Die Bestellabwicklung übernimmt Amazon. Amazon stellt keine Reviews mehr zu [...]]]></description>
			<content:encoded><![CDATA[<p>Unter der Amazon Product Advertising API wird dem Programmierer eine Untermenge der Funktionalität des Amazon-Shops zur Verfügung gestellt. Amazon-Produktdaten können nahtlos in die eigene Website integriert werden. Produkte können z.B. in einen Warenkorb gelegt werden und der Besucher kann sich umfangreich über die Produkte informieren. Die Bestellabwicklung übernimmt Amazon. Amazon stellt keine Reviews mehr zu Verfügung. Die müssen auf der Eigentümersite gelesen werden. Auf diese Veränderung weist Amazon deutlich hin. Als weitere Änderung muss auf eine bestimmte Anzahl an Anfragen über die API auch ein gewisser Prozentsatz an Bestellungen erfolgen. Ich sehe die Veränderungen als Amazons Reaktion darauf, dass die Produktdaten in der Vergangenheit fleißig von Suchmaschinenoptimierern (SEO) missbraucht wurden, um Inhalte für Websites zu generieren. Wofür braucht das Internet millionenfach reproduzierten Content, der doch ursprünglich einzig und alleine Amazon gehört? So weisen die License Agreements zur Benutzung dieser API denn auch darauf hin, dass die API nur dazu benutzt werden soll, um Besucher zu Amazon umzuleiten.</p>
<p>Hier studiere ich ein C#-Codebeispiel, welches ich in der Amazonschen Dokumentation gefunden habe. Es handelt von einer REST-Anfrage an den Amazon-Server. Die Antwort kommt als XML zurück. Um den Eigentümer der Anfrage eindeutig zu identifizieren bietet Amazon verschiedene Verfahren an. Das Beispiel setzt ein Verfahren um, bei dem Amazon und der Programmierer den gleichen geheimen Schlüssen haben. Dieser Schlüssel kann auf Knopfdruck neu genieriert werden.</p>
<p>Das Beispiel benutzt die Klasse <code>HMACSHA256</code>. Instanzen dieser Klasse können einen <em>Hash-based Message Authentication Code (HMAC)</em> mit dem <em>SHA256</em>-Algorithmus erzeugen.</p>
<p>Zuerst wird eine Instanz von <code>HMACSHA256</code> mit dem geheimen Schlüssel als Argument erzeugt:</p>
<pre class="brush: csharp;">

string secretKey = &quot;XblaY&quot;
HMAC signer = new HMACSHA256(secretKey);
</pre>
<p>Danach wird der gesamte Query-String signiert:</p>
<pre class="brush: csharp;">

string queryString = &quot;Fertig formatierter String mit allen gewünschten Parametern, für Amazon präpariert&quot;;
byte[] sigBytes = signer.ComputeHash(queryString );
string signature = Convert.ToBase64String(sigBytes);
</pre>
<p>Diese Signatur wird dann als letzter Parameter der Anfrage angehängt.</p>
<p>Kann ich jetzt endlich durch die Benutzung der API reich werden? Meine Nachforschungen haben ergeben, dass weniger Programmieren mehr ist. Besucher einer Website wurden noch nie durch Programmierkunst beeindruckt, sondern durch handgemachten Inhalt. So habe ich denn auch unter denjenigen, die einen nennenswerten Verdienst durch das Partnerprogramm erzielten, nur solche gefunden, die vereinzelte Links auf Amazonprodukte gesetzt haben. Diese Links haben direkt etwas mit dem zu tun, was sie in mühsamer Arbeit gepostet haben. Hier wird es eine vollautomatische Generierung von Produktdaten schwer haben, zu Verdienst gemacht zu werden. Da besucht man doch lieber direkt den Amazon-Shop.</p>
<p>Also, keine Scham, das Partnerprogramm ohne API zu nutzen! Die einfachste Möglichkeit besteht darin, einen Link auf die Amazon-Homepage zu setzen. Damit Amazon nicht zu viele für Suchmaschinen sichtbare Links bekommt, können Links umgeleitet werden. In ASP.NET MVC habe ich das so gemacht:</p>
<pre class="brush: csharp;">
    public class AmazonLinkController : Controller
    {
        //
        // GET: /AmazonLink/

        public void Index()
        {
            Response.Redirect(&quot;http://www.amazon.de/exec/obidos/redirect-home?tag=meinTag-21&amp;site=home&quot;);
        }

    }
</pre>
<p>die Action <code>Index</code> meines Controllers ist eine <code>void</code>-Methode und leitet zu Amazon um.</p>]]></content:encoded>
			<wfw:commentRss>http://www.codeschneider.de/programmierereien/reich-mit-amazon-product-advertising-api/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>URL-Rewriting mit ASP.NET MVC</title>
		<link>http://www.codeschneider.de/programmierereien/url-rewriting-mit-asp-net-mvc</link>
		<comments>http://www.codeschneider.de/programmierereien/url-rewriting-mit-asp-net-mvc#comments</comments>
		<pubDate>Sat, 09 Apr 2011 08:57:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programmierereien]]></category>

		<guid isPermaLink="false">http://www.codeschneider.de/?p=539</guid>
		<description><![CDATA[Möchte man ASP.NET MVC einsetzen, um Internetanwendungen zu programmieren, kann man guten Inhalt direkt mit Suchmaschinenoptimierung verknüpfen. Öffentlich zugänglicher Inhalt kann auch Google möglichst gut zugänglich gemacht werden. Die Google-Roboter, die Websites abgrasen und Webseiten in den Index aufnehmen, scheuen vor URL mit Parametern zurück (z.B. www.wetter.de?PLZ=53127) und nehmen statisch erscheinende URL in den Index [...]]]></description>
			<content:encoded><![CDATA[<p>Möchte man ASP.NET MVC einsetzen, um Internetanwendungen zu programmieren, kann man guten Inhalt direkt mit Suchmaschinenoptimierung verknüpfen. Öffentlich zugänglicher Inhalt kann auch Google möglichst gut zugänglich gemacht werden. Die Google-Roboter, die Websites abgrasen und Webseiten in den Index aufnehmen, scheuen vor URL mit Parametern zurück (z.B. www.wetter.de?PLZ=53127) und nehmen statisch erscheinende URL in den Index auf (z.B. www.wetter/53127.html). Das ist ein triftiger Grund, URL statisch aussehen zu lassen. Zusätzlich sehen statische URL freundlicher aus, und können besser gemerkt werden.</p>
<p>Als Erstes definiere ich eine Zuordnung zwischen einem Konfigurationsabschnittshandler und einem Konfigurationsabschnitt. Aus diesem Grund füge ich dem <code>configSections</code>-Knoten in Web.config folgende <code>sectionGroup</code> hinzu:</p>
<pre class="brush: xml;">
&lt;configSections&gt;
  &lt;sectionGroup name=&quot;myModuleConfig&quot;&gt;
    &lt;section name=&quot;rewriteModule&quot; type=&quot;MyAssembly.RewriteModuleSectionHandler, MyAssembly&quot;/&gt;
  &lt;/sectionGroup&gt;
&lt;/configSections&gt;
</pre>
<p>Dementsprechend muss ich dann im <code>configuration</code>-Knoten den Konfigurationsabschnitt definieren:</p>
<pre class="brush: xml;">
&lt;myModuleConfig&gt;
  &lt;rewriteModule&gt;
    &lt;rewriteOn&gt;true&lt;/rewriteOn&gt;
    &lt;rewriteRules&gt;
      &lt;rule source=&quot;Keyword/(.+).aspx&quot; destination=&quot;Keyword?keyword=$1&quot;/&gt;
    &lt;/rewriteRules&gt;
  &lt;/rewriteModule&gt;
 &lt;/myModuleConfig&gt;
</pre>
<p>In diesem Abschnitt definiere ich, ob das URL-Rewriting stattfinden soll und ich definiere Rewrite-Rules, so wie man das unter PHP in einer .htaccess-Datei tun würde.</p>
<p>Nun muss ich den Konfigurationsabschnittshandler <code>RewriteModuleSectionHandler</code> denn auch in Code gießen:</p>
<pre class="brush: csharp;">
public class RewriteModuleSectionHandler : IConfigurationSectionHandler
{

    private XmlNode _XmlSection;
    private string _RewriteBase;
    private bool _RewriteOn;

    public XmlNode XmlSection
    {
        get { return _XmlSection; }
    }

    public string RewriteBase
    {
        get { return _RewriteBase; }
    }

    public bool RewriteOn
    {
        get { return _RewriteOn; }
    }
    public object Create(object parent, object configContext, System.Xml.XmlNode section)
    {
        _RewriteBase = HttpContext.Current.Request.ApplicationPath + &quot;/&quot;;

        try
        {
            _XmlSection = section;
            _RewriteOn = Convert.ToBoolean(section.SelectSingleNode(&quot;rewriteOn&quot;).InnerText);
        }
        catch (Exception ex)
        {
            throw (new Exception(&quot;Error while processing RewriteModule configuration section.&quot;, ex));
        }
        return this;
    }
}
</pre>
<p>Im Wesentlichen nimmt mein Handler bei Erzeugung seinen XML-Knoten in Empfang und dient mir dazu, den XML-Zugriff zu kapseln.</p>
<p>Zusätzlich definiere ich in der Web.config ein HTTP-Modul:</p>
<pre class="brush: xml;">
&lt;system.web&gt;
  &lt;httpModules&gt;
    &lt;add name=&quot;RewriteModule&quot; type=&quot;MyAssembly.RewriteModule, MyAssembly&quot;/&gt;
  &lt;/httpModules&gt;
&lt;/system.web&gt;
</pre>
<p>In C#-Code gegossen:</p>
<pre class="brush: csharp;">
class RewriteModule : IHttpModule
{

    public void Dispose() { }

    public void Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(RewriteModule_BeginRequest);
    }

    void RewriteModule_BeginRequest(object sender, EventArgs e)
    {
        RewriteModuleSectionHandler cfg = (RewriteModuleSectionHandler)ConfigurationManager.GetSection(&quot;myModuleConfig/rewriteModule&quot;);

        if (!cfg.RewriteOn) return;

        string path = HttpContext.Current.Request.Path;

        if (path.Length == 0) return;

        XmlNode rules = cfg.XmlSection.SelectSingleNode(&quot;rewriteRules&quot;);
        foreach (XmlNode xml in rules.SelectNodes(&quot;rule&quot;))
        {
            try
            {
                string attrsource = &quot;/&quot; + xml.Attributes[&quot;source&quot;].InnerText;

                Regex re = new Regex(attrsource, RegexOptions.IgnoreCase);

                Match match = re.Match(path);
                if (match.Success)
                {
                    path = re.Replace(path, xml.Attributes[&quot;destination&quot;].InnerText);
                    // new path to rewrite to
                    string rew = cfg.RewriteBase + path;

                    // rewrite
                    HttpContext.Current.RewritePath(rew);

                    return;
                }
            }
            catch (Exception ex)
            {
                throw (new Exception(&quot;Incorrect rule.&quot;, ex));
            }
        }
        return;
    }

}
</pre>
<p>in der <code>Init</code>-Methode, die mir das <code>IHttpModule</code>-Interface vorschreibt, bekomme ich eine Referenz auf die Anwendung übergeben. Ich füge dem Anwendungsevent <code>BeginRequest</code> als EventHandler einen Delegaten hinzu, der mir schließlich meine URL-Rewritefunktion aufruft:<br />
<code>void RewriteModule_BeginRequest(object sender, EventArgs e)</code></p>
<p>Nachdem ich meinen RewriteModuleSectionHandler instanziiert habe (über <code>RewriteModuleSectionHandler cfg = (RewriteModuleSectionHandler)ConfigurationManager.GetSection("myModuleConfig/rewriteModule")</code> findet die Instanziierung nur einmal statt), gehe ich alle Rewrite-Regeln durch und prüfe mit <code>Regex</code> und <code>Match</code>, ob der reguläre Ausdruck der Anfrage-URL mit dem der Regel übereinstimmt. Mit Regex.Replace(&#8230;) wird die URL endlich umgeschrieben.</p>]]></content:encoded>
			<wfw:commentRss>http://www.codeschneider.de/programmierereien/url-rewriting-mit-asp-net-mvc/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Design Patterns &#8211; Proxy</title>
		<link>http://www.codeschneider.de/programmierereien/design-patterns-proxy</link>
		<comments>http://www.codeschneider.de/programmierereien/design-patterns-proxy#comments</comments>
		<pubDate>Tue, 08 Mar 2011 20:35:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programmierereien]]></category>

		<guid isPermaLink="false">http://www.codeschneider.de/?p=528</guid>
		<description><![CDATA[Das Proxy-Pattern legt eine Zugriffskontrollschicht über ein Objekt (Subjekt). Da Originalobjekt wie Proxyobjekt das selbe Interface Subject implementieren, kann das Proxyobjekt als Stellvertreter (Proxy) verwendet werden.
So alltäglich der Zugriff auf Objekte für den Programmierer ist, so mannigfaltig können die Zugriffskontrollen des Proxy sein. Der Proxy kann etwa den Zugriff auf ein entferntes Objekt kapseln und [...]]]></description>
			<content:encoded><![CDATA[<p>Das Proxy-Pattern legt eine Zugriffskontrollschicht über ein Objekt (Subjekt). Da Originalobjekt wie Proxyobjekt das selbe Interface <code>Subject</code> implementieren, kann das Proxyobjekt als Stellvertreter (Proxy) verwendet werden.<br />
So alltäglich der Zugriff auf Objekte für den Programmierer ist, so mannigfaltig können die Zugriffskontrollen des Proxy sein. Der Proxy kann etwa den Zugriff auf ein entferntes Objekt kapseln und kann für den Client unsichtbar das Verbindungsmanagement übernehmen (<em>Remote Proxy</em>). Ohne es zu wissen, habe ich diese Art Proxy <a href="http://www.codeschneider.de/programmierereien/sgf-player-in-silverlight-teil-1-visual-studio-statt-monodevelop">verwendet</a>, um den Aktienwerte zurück gebenden Webservice zu testen. Anhand der WSDL generiert mir Visual Studio eine Servicereferenz, die als Proxy dient.<br />
Das Proxy kann auch zu dem Zweck existieren, das gekapselte Objekt erst bei Bedarf zu instanziieren <em>(Virtual Proxy</em>). Im GoF-Buch gibt es z.B. ein Dokument-Objekt, welches eine Vielzahl von primitiven Objekten wie Texte, geomentrische Elemente und Bilder enthält. Würde jedes Bildobjekt sofort instanziiert werden, könnte das sehr lange dauern und wäre in vielen Fällen unnötig.<br />
Ein <em>Schutzproxy</em> erlaubt nur autorisierte Zugriffe auf das Objekt. Hier kann der Objektzugang benutzer- oder gruppenspezifisch geregelt werden.<br />
Im Unterschied zum Decorator fügt der Proxy dem Subjekt keine Funktionalität hinzu. Es wird lediglich der Zugriff gesteuert.</p>]]></content:encoded>
			<wfw:commentRss>http://www.codeschneider.de/programmierereien/design-patterns-proxy/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Design Patterns &#8211; State</title>
		<link>http://www.codeschneider.de/programmierereien/design-patterns-state</link>
		<comments>http://www.codeschneider.de/programmierereien/design-patterns-state#comments</comments>
		<pubDate>Mon, 07 Mar 2011 16:09:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programmierereien]]></category>

		<guid isPermaLink="false">http://www.codeschneider.de/?p=523</guid>
		<description><![CDATA[Das Zustand-Muster erlaubt es einem Objekt zur Laufzeit zustandsabhängig sein Verhalten zu ändern. Im Zeitalter der Objektorientierung programmiert man nach diesem Muster Zustandsautomaten. Statt für jede Zustandswechselmethode eine umfangreiche if-else-Orgie zu veranstalten, wird jeder Zustand in eine Klasse gekapselt. Zustände können so wesentlich leichter hinzugefügt werden, ohne jedesmal die if-else-Anweisungen erneut verstehen zu müssen. Selbst [...]]]></description>
			<content:encoded><![CDATA[<p>Das Zustand-Muster erlaubt es einem Objekt zur Laufzeit zustandsabhängig sein Verhalten zu ändern. Im Zeitalter der Objektorientierung programmiert man nach diesem Muster Zustandsautomaten. Statt für jede Zustandswechselmethode eine umfangreiche if-else-Orgie zu veranstalten, wird jeder Zustand in eine Klasse gekapselt. Zustände können so wesentlich leichter hinzugefügt werden, ohne jedesmal die if-else-Anweisungen erneut verstehen zu müssen. Selbst bei einem sehr komplexen Zustandsautomaten bleibt die Wartung übersichtlich.</p>
<pre class="brush: php;">
&lt;?php
abstract class WindowState
{
	public function OpenWide($window)
	{
	    echo &quot;Keine Zustandsänderung&lt;br/&gt;&quot;;
	}
	public function Close($window)
	{
	    echo &quot;Keine Zustandsänderung&lt;br/&gt;&quot;;
	}
	public function Tilt($window)
	{
	    echo &quot;Keine Zustandsänderung&lt;br/&gt;&quot;;
	}
}

class WindowClosedState extends WindowState
{
	public function OpenWide(Window $window)
	{
	    echo &quot;Fenster wurde geöffnet&lt;br/&gt;&quot;;
	    $window-&gt;currentState=new WindowWideOpenedState();
	}
	public function Tilt(Window $window)
	{
	    echo &quot;Fenster wurde gekippt&lt;br/&gt;&quot;;
	    $window-&gt;currentState=new WindowTiltState();
	}
}

class WindowWideOpenedState extends WindowState
{
	public function Tilt(Window $window)
	{
	    echo &quot;Fenster wurde gekippt&lt;br/&gt;&quot;;
	    $window-&gt;currentState=new WindowTiltState();
	}
	public function Close(Window $window)
	{
	    echo &quot;Fenster wurde geschlossen&lt;br/&gt;&quot;;
	    $window-&gt;currentState=new WindowClosedState();
	}
}

class WindowTiltState extends WindowState
{
	public function Close(Window $window)
	{
	    echo &quot;Fenster wurde geschlossen&lt;br/&gt;&quot;;
	    $window-&gt;currentState=new WindowClosedState();
	}
	public function Open(Window $window)
	{
	    echo &quot;Fenster wurde geöffnet&lt;br/&gt;&quot;;
	    $window-&gt;currentState=new WindowOpenedState();
	}
}
class Window
{
	public $currentState;

	public function Window()
	{
		$this-&gt;currentState=new WindowClosedState();
	}

	public function OpenWide()
	{
		$this-&gt;currentState-&gt;OpenWide($this);
	}

	public function Close()
	{
		$this-&gt;currentState-&gt;Close($this);
	}

	public function Tilt()
	{
		$this-&gt;currentState-&gt;Tilt($this);
	}
}

$window = new Window();
$window-&gt;Close();

$window-&gt;OpenWide();
$window-&gt;Tilt();
$window-&gt;Tilt();
$window-&gt;OpenWide();
$window-&gt;Close();

?&gt;
</pre>]]></content:encoded>
			<wfw:commentRss>http://www.codeschneider.de/programmierereien/design-patterns-state/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Design Patterns &#8211; Composite</title>
		<link>http://www.codeschneider.de/programmierereien/design-patterns-composite</link>
		<comments>http://www.codeschneider.de/programmierereien/design-patterns-composite#comments</comments>
		<pubDate>Fri, 04 Mar 2011 20:16:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programmierereien]]></category>

		<guid isPermaLink="false">http://www.codeschneider.de/?p=516</guid>
		<description><![CDATA[Bei einer Komposition (HAS-A-Beziehung von Container/Komponenten) mag es vorkommen, dass Komponente wie Container gleich behandelt werden sollen. Ein GUI-Element kann beispielsweise ein Container oder ein primitives Element wie ein Control sein. Beide Arten, Container wie Control haben aber viele gleiche Eigenschaften und Methoden, wie Draw(), Size(), Move(x,y), usw. Für eine flexible Verwendung leitet man Container [...]]]></description>
			<content:encoded><![CDATA[<p>Bei einer Komposition (HAS-A-Beziehung von Container/Komponenten) mag es vorkommen, dass Komponente wie Container gleich behandelt werden sollen. Ein GUI-Element kann beispielsweise ein Container oder ein primitives Element wie ein Control sein. Beide Arten, Container wie Control haben aber viele gleiche Eigenschaften und Methoden, wie Draw(), Size(), Move(x,y), usw. Für eine flexible Verwendung leitet man Container und Komponente vom selben Interface ab. Sie verhalten sich damit nach außen gleich. Wenn nun z.B. Draw() auf dem Container aufgerufen wird, braucht dieser nur sich selbst zu zeichnen und danach auf seinen Komponenten Draw() aufzurufen, welche ihrerseits wieder beides sein können.</p>
<p>Hier ein Codeschnipsel in PHP:</p>
<pre class="brush: php;">
&lt;?php

interface IComponent
{
    public function GetSize();
    public function GetWeight();
}

class Component implements IComponent
{
	private $width;
	private $height;
	private $length;
	private $weight;

	public function __construct($width, $height, $length, $weight)
    {
        $this-&gt;width = $width;
        $this-&gt;height = $height;
        $this-&gt;length = $length;
        $this-&gt;weight = $weight;
    }

    public function GetSize()
    {
    	return $this-&gt;width * $this-&gt;height * $this-&gt;length;
    }

    public function GetWeight()
    {
    	return $this-&gt;weight;
    }
}

class Container extends Component implements IComponent
{
    private $components = array();
    public function __construct($width, $height, $length, $weight)
    {
        parent::__construct($width, $height, $length, $weight);
    }

    public function Add ($component)
    {
    	$this-&gt;components[] = $component;
    }

    public function GetSize()
    {
    	return parent::GetSize();
    }

    public function GetWeight()
    {
    	$weight = parent::GetWeight();
        foreach ($this-&gt;components as $info =&gt; $value )
        	$weight += $value-&gt;GetWeight();

        return $weight;
   	}
}

    $container1 = new Container(10,10,10,1000);
    $component2 = new Component(2,2,2,200);
    $container = new Container(100, 100, 100, 100000);
    $container-&gt;Add($container1);
    $container-&gt;Add($component2);

    $minicontainer = new Container (8,8,8,8);
	$minicomponent = new Component (2,2,2,2);
	$minicomponent2 = new Component (2,2,2,2);
	$minicontainer-&gt;Add($minicomponent);
	$minicontainer-&gt;Add($minicomponent2);
	$container1-&gt;Add($minicontainer);  

	echo &quot;Total Weight: &lt;br\&gt;&quot;;
   	echo $container-&gt;GetWeight();

?&gt;
</pre>
<p>Mein Beispiel stellt eine Schiffscontainerstruktur dar. <code>Container</code> wie  <code>Component</code> sind beide vom Typ <code>IComponent</code> und bieten die Methoden <code>GetSize()</code> und <code>GetWeight()</code> an. Statt bei der Gewichtsberechnung den Typ zu unterscheiden brauche ich nur <code>GetWeight()</code> aufzurufen.</p>]]></content:encoded>
			<wfw:commentRss>http://www.codeschneider.de/programmierereien/design-patterns-composite/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Design Patterns &#8211; Iterator</title>
		<link>http://www.codeschneider.de/programmierereien/design-pattern-iterator</link>
		<comments>http://www.codeschneider.de/programmierereien/design-pattern-iterator#comments</comments>
		<pubDate>Fri, 04 Mar 2011 20:08:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programmierereien]]></category>

		<guid isPermaLink="false">http://www.codeschneider.de/?p=510</guid>
		<description><![CDATA[Mit Hilfe des Iterator Patterns kann sequenziell auf die Elemente eines zusammengesetzten Objekts (Aggregat) zugegriffen werden, ohne die Struktur der Elemente offen zu legen. Ein Iterator erlaubt diesen Zugriff.
Es wird verwendet, wenn mehrere Iteratoren gleichzeitig ermöglicht werden sollen, wenn ein Iterator polymorph verwendet werden soll oder wenn Datenstrukturen sich ändern aber man kein Clientcode ändern [...]]]></description>
			<content:encoded><![CDATA[<p>Mit Hilfe des Iterator Patterns kann sequenziell auf die Elemente eines zusammengesetzten Objekts (Aggregat) zugegriffen werden, ohne die Struktur der Elemente offen zu legen. Ein Iterator erlaubt diesen Zugriff.<br />
Es wird verwendet, wenn mehrere Iteratoren gleichzeitig ermöglicht werden sollen, wenn ein Iterator polymorph verwendet werden soll oder wenn Datenstrukturen sich ändern aber man kein Clientcode ändern möchte. Außerdem kann ein Iteratorverhalten zur Laufzeit ausgetauscht werden. Das Muster beherzigt das Single Responsibility Principle. Eine Klasse soll nur eine Verantwortlichkeit haben.</p>
<p>Hier ein Codeschnipsel in PHP:</p>
<pre class="brush: php;">
&lt;?php

class Person
{
	private $name = &quot;&quot;;
    public function __construct($n)
    {
        $this-&gt;name = $n;
    }

    public function Name()
    {
    	return $this-&gt;name;
    }
}

class NameFilterIterator extends FilterIterator
{
    private $nameFilter;

    public function __construct(Iterator $iterator , $filter )
    {
        parent::__construct($iterator);
        $this-&gt;nameFilter = $filter;
    }

    public function accept()
    {
        $person = $this-&gt;getInnerIterator()-&gt;current();
        if( strcasecmp($person-&gt;Name(),$this-&gt;nameFilter) == 0) {
            return false;
        }
        return true;
    }
}

class ConcreteAggregateArray implements IteratorAggregate
{
    protected $_array = array();
	public function __construct()
    {
    	$this-&gt;_array[] = new Person(&quot;Hans&quot;);
    	$this-&gt;_array[] = new Person(&quot;Seppel&quot;);
        $this-&gt;_array[] = new Person(&quot;Dirk&quot;);
   	}

    public function getIterator()
    {
        return new ArrayIterator($this-&gt;_array);
    }
}

class ConcreteAggregateObjectStore implements IteratorAggregate
{
	protected $objectStore;

	public function __construct()
    {
    	$this-&gt;objectStore = new SplObjectStorage();
    	$this-&gt;objectStore-&gt;attach(new Person(&quot;Lilli&quot;));
    	$this-&gt;objectStore-&gt;attach(new Person(&quot;Eva&quot;));
        $this-&gt;objectStore-&gt;attach(new Person(&quot;Herta&quot;));
    }

    public function getIterator()
    {
        return $this-&gt;objectStore;
    }
}

class ConcreteAggregateFilteredArray implements IteratorAggregate
{
    protected $_array = array();
	public function __construct()
    {
    	$this-&gt;_array[] = new Person(&quot;Albert&quot;);
    	$this-&gt;_array[] = new Person(&quot;Adelheid&quot;);
        $this-&gt;_array[] = new Person(&quot;Anton&quot;);
   	}

    public function getIterator()
    {
        return new NameFilterIterator(new ArrayIterator($this-&gt;_array), &quot;Adelheid&quot;);
    }
}

function PrintPersons($iteratorAggregate)
{
    foreach ($iteratorAggregate-&gt;getIterator() as $info =&gt; $value )
    {
        echo $value-&gt;Name();
        echo &quot;&lt;br /&gt;&quot;;
    }
}

$aggregates = array(new ConcreteAggregateArray,
					new ConcreteAggregateObjectStore,
					new ConcreteAggregateFilteredArray);
foreach ($aggregates as $info =&gt; $value)
	PrintPersons($value)
?&gt;
</pre>
<p>Die Aggregate <code>ConcreteAggregateArray</code>, <code>ConcreteAggregateObjectStore</code> und <code>ConcreteAggregateObjectStore</code> implementieren das <code>IteratorAggregate</code>-Interface und geben jeweils einen konkreten Iterator, welcher von <code>Iterator</code> abgeleitet ist, zurück. Dadurch kann das Aggregat polymorph verwendet werden. Das beweist die Funktion <code>function PrintPersons($iteratorAggregate)</code>. Mittels <code>foreach</code> kann ungeachtet der konkreten Form über das Aggregat iteriert werden.</p>]]></content:encoded>
			<wfw:commentRss>http://www.codeschneider.de/programmierereien/design-pattern-iterator/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Design Patterns &#8211; Template Method</title>
		<link>http://www.codeschneider.de/programmierereien/design-patterns-template-method</link>
		<comments>http://www.codeschneider.de/programmierereien/design-patterns-template-method#comments</comments>
		<pubDate>Wed, 02 Mar 2011 18:19:03 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programmierereien]]></category>

		<guid isPermaLink="false">http://www.codeschneider.de/?p=504</guid>
		<description><![CDATA[Die Schablonenmethode (Template Method) definiert das Skelett eines Algorithmus und delegiert einzelne Schritte an Unterklassen weiter. Dadurch können Unterklassen bestimmte Schritte eines Algorithmus bestimmen, ohne die Struktur des Algorithmus zu verändern. Hier wird das Designprinzip &#8220;Don&#8217;t call us, we call you&#8221; verwirklicht.
Die Schablonenmethode sollte angewendet werden, um invariante Anteile eines Algorithmus  genau einmal zu [...]]]></description>
			<content:encoded><![CDATA[<p>Die Schablonenmethode (Template Method) definiert das Skelett eines Algorithmus und delegiert einzelne Schritte an Unterklassen weiter. Dadurch können Unterklassen bestimmte Schritte eines Algorithmus bestimmen, ohne die Struktur des Algorithmus zu verändern. Hier wird das Designprinzip &#8220;Don&#8217;t call us, we call you&#8221; verwirklicht.<br />
Die Schablonenmethode sollte angewendet werden, um invariante Anteile eines Algorithmus  genau einmal zu definieren und variierende Anteile an Unterklassen zu übergeben. Die Templatemethode ist eine häufig verwendete Refaktorisierngsmethode. Gemeinsame Teile werden aus Basisklassen in eine Templatemethode herausgezogen. Dadurch wird sichergestellt, dass doppelter Code vermieden wird. Durch Verwendung einer Schablonenmethode werden Unterklassen kontrolliert erweitert. Einschubmethoden, die in der abstrakten Klasse häufig leer implementiert sind, können in Unterklassen überschrieben werden. Die Verwendung der Einschubmethoden ist allerdings in der abstrakten Klasse geregelt.</p>
<p>Hier als Beispiel ein PHP-Schnipsel</p>
<pre class="brush: php;">
&lt;?php

abstract class KindergartenTrip
{
	protected function __construct($count)
	{
  		$this-&gt;memberCount = $count;
  	}

  	abstract protected function DoAntemeridianTrip();
  	abstract protected function DoPostmeridianTrip();

	private $memberCount = 0;
	private $collectedMembersCount = 0;

	public final function doTrip()
  	{
  		if ($this-&gt;memberCount == 0)
  		return;

  		if ($this-&gt;collectedMembersCount != $this-&gt;memberCount)
  			return;

  		$this-&gt;TravelToDestination();
  		$this-&gt;DoAntemeridianTrip();
  		$this-&gt;DoPostmeridianTrip();
		$this-&gt;TravelHome();

  	}

  	public final function SetCollectedChildren($count)
  	{
		$this-&gt;collectedMembersCount = $count;
  	}

  	public function TravelToDestination()
  	{
  		echo &quot;Normal Travel to Destination&lt;BR&gt;&quot;;
  	}
  	public function TravelHome()
  	{
  		echo &quot;Normal Hometravel&lt;BR&gt;&quot;;
  	}

}
class SchwimmbadTrip extends KindergartenTrip
{
	public function __construct($count)
	{
		parent::__construct($count);
  	}

  	public function DoAntemeridianTrip()
  	{
  		echo &quot;Go swimming&lt;BR&gt;&quot;;
  	}

  	public function DoPostmeridianTrip()
  	{
  		echo &quot;Go swimming once again&lt;BR&gt;&quot;;
  	}

  	public function TravelHome()
  	{
  		echo &quot;Few children were sick&lt;BR&gt;&quot;;
  	}
}

class SpecialFunTrip extends KindergartenTrip
{
	public function __construct($count)
	{
		parent::__construct($count);
  	}

  	public function DoAntemeridianTrip()
  	{
  		echo &quot;Go to circus&lt;BR&gt;&quot;;
  	}

  	public function DoPostmeridianTrip()
  	{
  		echo &quot;Go to cinema&lt;BR&gt;&quot;;
  	}

  	// Einschubmethode
  	public function TravelToDestination()
  	{
  		echo &quot;Children very excited&lt;BR&gt;&quot;;
  	}

  	// Einschubmethode
  	public function TravelHome()
  	{
  		echo &quot;Children very happy an exhausted&lt;BR&gt;&quot;;
  	}
}
?&gt;
</pre>
<p>Die abstrakte Klasse ist <code>KindergartenTrip</code> und die Templatemethode <code>doTrip()</code>. <code>doTrip()</code> ist als <code>public final</code> definiert, da die Methode nicht mehr überschrieben werden soll. Für alle Trips gilt die Invariante, dass die Anzahl der eingesammelten Kinder gleich der Anzahl der angemeldeten Kinder sein muss. Die öffentliche Methode <code>SetCollectedChildren($count)</code> soll ebenfalls in abgeleiteten Klassen nicht geändert werden können. Die Templatemethode legt als Invariante fest, dass der Trip erst losgeht, wenn die Anzahl der aufgelesenen Kinder gleich der Anzahl der angemeldeten Kinder ist.  Außerdem wird die Reihenfolge der Schritte des Tripalgorithmus festgelegt. <code>TravelToDestination()</code> und <code>TravelHome()</code> sind Einschubmethoden, die überschrieben werden können. Konkrete Klassen müssen die variablen Schritte <code>DoAntemeridianTrip()</code> und <code>DoPostmeridianTrip()</code> implementieren.</p>]]></content:encoded>
			<wfw:commentRss>http://www.codeschneider.de/programmierereien/design-patterns-template-method/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Design Patterns &#8211; Facade</title>
		<link>http://www.codeschneider.de/programmierereien/design-patterns-facade</link>
		<comments>http://www.codeschneider.de/programmierereien/design-patterns-facade#comments</comments>
		<pubDate>Mon, 28 Feb 2011 17:55:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programmierereien]]></category>

		<guid isPermaLink="false">http://www.codeschneider.de/?p=495</guid>
		<description><![CDATA[Die Fassade (Facade) dient dazu, ein einheitliches Interface zu einer Menge von Interfaces eines Subsystems bereit zu stellen. Dadurch wird die Komplexität aus dem Subsystem herausgenommen und die Benutzung vereinfacht. Die Interfaces des Subystems können auch weiter seperat genutzt werden. Die Fassade ist das wohl häufigste Entwurfsmuster, mindestens was die Benutzung betrifft. Wie oft habe [...]]]></description>
			<content:encoded><![CDATA[<p>Die Fassade (Facade) dient dazu, ein einheitliches Interface zu einer Menge von Interfaces eines Subsystems bereit zu stellen. Dadurch wird die Komplexität aus dem Subsystem herausgenommen und die Benutzung vereinfacht. Die Interfaces des Subystems können auch weiter seperat genutzt werden. Die Fassade ist das wohl häufigste Entwurfsmuster, mindestens was die Benutzung betrifft. Wie oft habe ich mich dabei ertappt, wie ich stundenlang nach dem einfachsten Weg suche. Hier gehts ums nackte Überleben, denn <em>complexity kills</em>.<br />
Dennoch einige Beispiele:</p>
<ul>
<li>Die MFC ist Microsofts Fassade um die komplizierte Windows-API, um die Erstellung von Windows-Anwendungen zu vereinfachen.</li>
<li>In Java sind viele manuelle Schritte nötig, nur um eine Messagebox mit den Low-Level-Klassen von Swing auf den Bildschirm zu werfen. Mit der Fassade <code>JOptionPane.showMessageDialog(...)</code> kann man sich viele Zeilen sparen und dies ist schnell erledigt.</li>
<li>Java Swing wiederum ist selbst eine Fassade, um nicht jede geometrische Figur einzeln zeichnen zu müssen.</li>
<li>Eine Computersprache selbst ist eine Fassade auf die nächst niedrigere Ebene. C#-Code ruft intern C-Code auf und dieser Assembler. Der Benutzer selbst hat die abstrakteste Fassade vor sich.</li>
</ul>
<p>Die Beispiele sind wohl unendlich. Ob es zu den wirklichen Fortschritten gehört, eine Fassade etwa um eine STL-Collection zu bauen, die die Methoden Count() und GetAt(int) anbietet, nur weil man die die letzten 20 Jahre so programmiert hat, darüber lässt sich streiten.</p>]]></content:encoded>
			<wfw:commentRss>http://www.codeschneider.de/programmierereien/design-patterns-facade/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

