<?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>Delphi400’s Weblog &#187; Entwurfsmuster</title>
	<atom:link href="http://delphi400.neusath.de/category/entwurfsmuster/feed" rel="self" type="application/rss+xml" />
	<link>http://delphi400.neusath.de</link>
	<description>Ein weiteres tolles WordPress-Blog</description>
	<lastBuildDate>Tue, 02 Feb 2010 09:37:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Das Singleton – Ein Muster zum streiten?</title>
		<link>http://delphi400.neusath.de/das-singleton-%e2%80%93-ein-muster-zum-streiten.html</link>
		<comments>http://delphi400.neusath.de/das-singleton-%e2%80%93-ein-muster-zum-streiten.html#comments</comments>
		<pubDate>Sun, 28 Sep 2008 19:43:41 +0000</pubDate>
		<dc:creator>Delphi400</dc:creator>
				<category><![CDATA[Entwurfsmuster]]></category>

		<guid isPermaLink="false">http://delphi400.neusath.de/?p=269</guid>
		<description><![CDATA[Das Singleton soll sicher stellen, das es von einer Klasse zur Programmlaufzeit nur eine Instanz gibt. Ich persönlich nutze es zum Beispiel als Fehlerprotokollobjekt oder um eine Datenbankverbindung vorrätig zu halten. Manche Entwickler sind der Meinung, das das Singleton schlechter Programmierstil sei, ein Hinweis auf Designschwächen. Ich sehe das anders. Es gibt nun mal manchmal [...]]]></description>
			<content:encoded><![CDATA[<p>Das Singleton soll sicher stellen, das es von einer Klasse zur Programmlaufzeit nur eine Instanz gibt. Ich persönlich nutze es zum Beispiel als Fehlerprotokollobjekt oder um eine Datenbankverbindung vorrätig zu halten.</p>
<p>Manche Entwickler sind der Meinung, das das <strong>Singleton</strong> schlechter Programmierstil sei, ein Hinweis auf Designschwächen. Ich sehe das anders. Es gibt nun mal manchmal die Notwendigkeit, dass man nur eine Instanz von einem Objekt haben darf. Wenn dem so ist, dann ist dass Singleton die beste Lösung.</p>
<p>Der grundsätzliche Lösungsansatz ist folgender:<br />
<span id="more-269"></span></p>
<ol>
<li>Der Constructor wird als <em>private</em> deklariert, damit von dem Objekt nicht mehr „von Außen“ eine Instanz erstellt werden kann.</li>
<li>Dafür wird eine Methode <em>GetInstance</em> eingeführt, welche bei Bedarf (also beim ersten Aufruf) das Objekt erstellt und zurück gibt. Existiert bereits diese Instanz, wird sie lediglich zur Verfügung gestellt.</li>
</ol>
<p>Hier ein Beispiel:</p>
<pre><code><span style="font-size: x-small; font-family: Courier New;"><span style="color: #000000;"><em>{ *********************************************************************** }
{                                                                         }
{ Delphi Entwursmustersammlung  -- Singleton                              }
{                                                                         }
{ Autor: Thomas Gröschke                                                  }
{ Erstellt: 23.09.2008                                                    }
{                                                                         }
{ *********************************************************************** }
</em><strong>unit </strong>Unit1;

<strong>interface

type

  </strong>TSingleton = <strong>class</strong>(TObject)
  <strong>protected
    </strong>Counter: Integer;
    <strong>constructor </strong>Create;
    <strong>class var </strong>FInstance: TSingleton;
  <strong>public
    class function </strong>GetInstance: TSingleton;
    <strong>procedure </strong>HalloWorld;
  <strong>end</strong>;

<strong>implementation

uses </strong>SysUtils, Dialogs;

<em>{
********************************** TSingleton **********************************
}
</em><strong>constructor </strong>TSingleton.Create;
<strong>begin
  </strong>Counter := 0;
  <strong>inherited</strong>;
<strong>end</strong>;

<strong>class function </strong>TSingleton.GetInstance: TSingleton;
<strong>begin
  If </strong>FInstance = <strong>nil then
  begin
    </strong>FInstance := TSingleton.Create();
  <strong>end</strong>;
  Result := FInstance;
<strong>end</strong>;

<strong>procedure </strong>TSingleton.HalloWorld;
<strong>begin
  </strong>inc(Counter);
  ShowMessage('Hallo Welt! Das ist der Aufruf #' + IntToStr(Counter) + '.');
<strong>end</strong>;

<strong>end</strong>.
</span>
</span>
</code></pre>
<p>Testen zum Beispiel mit zwei Buttons auf einem Formular:</p>
<pre><code><span style="font-size: x-small; font-family: Courier New;"><span style="color: #000000;"><strong>procedure </strong>TForm1.Button1Click(Sender: TObject);
<strong>var
  </strong>FObj : TSingleton;
<strong>begin
  </strong>FObj := TSingleton.GetInstance;
  FObj.HalloWorld;
<strong>end</strong>;

<strong>procedure </strong>TForm1.Button2Click(Sender: TObject);
<strong>begin
  </strong>TSingleton.GetInstance.HalloWorld;
<strong>end</strong>;
</span>
</span>
</code></pre>
<p>Anzumerken ist noch, dass dieser Ansatz nicht Threadsicher ist. Da ich noch nie mit Threads gearbeitet habe und ich deswegen von dem Thema keine Ahnung habe, lass ich es an dieser Stelle so stehen.</p>
<p>Weblinks:</p>
<p><a title="DP" href="http://www.delphipraxis.net/topic141747_was+bringt+mir+ein+singleton.html&amp;highlight= ">delphipraxis: was bringt mir ein singleton?</a></p>
<p><a title="DP" href="http://de.wikipedia.org/wiki/Singleton_(Entwurfsmuster)">Wikipedia Man beachte die Nachteile!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://delphi400.neusath.de/das-singleton-%e2%80%93-ein-muster-zum-streiten.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Das Strategy-Muster</title>
		<link>http://delphi400.neusath.de/das-strategy-muster.html</link>
		<comments>http://delphi400.neusath.de/das-strategy-muster.html#comments</comments>
		<pubDate>Sun, 24 Aug 2008 18:15:27 +0000</pubDate>
		<dc:creator>Delphi400</dc:creator>
				<category><![CDATA[Entwurfsmuster]]></category>

		<guid isPermaLink="false">http://delphi400.neusath.de/?p=164</guid>
		<description><![CDATA[Beim Strategy-Muster geht es darum verschiedene Verhaltensweisen (Algorithmen) zu kapseln, um sie dann den Client über eine Schnittstelle zur Verfügung zu stellen. Dadurch ist es möglich dem Client ein neues Verhalten leicht hinzuzufügen oder zur Laufzeit zu ändern. Im Buch „Entwurfsmuster von Kopf bis Fuß“ ist das sehr schön mit verschiedenen Enten und ihren unterschiedlichen [...]]]></description>
			<content:encoded><![CDATA[<p>Beim <strong>Strategy-Muster</strong> geht es darum verschiedene Verhaltensweisen (Algorithmen) zu kapseln, um sie dann den Client über eine Schnittstelle zur Verfügung zu stellen. Dadurch ist es möglich dem Client ein neues Verhalten leicht hinzuzufügen oder zur Laufzeit zu ändern.<br />
<span id="more-164"></span></p>
<p>Im Buch „Entwurfsmuster von Kopf bis Fuß“ ist das sehr schön mit verschiedenen Enten und ihren unterschiedlichen Flug- und Quakverhalten erklärt. Ich versuche es hier, wiederum inspiriert aus dem Buch, mit einem Computerspiel. Ich möchte zwei Varianten beschreiben. Ein mal mit Hilfe eines Interfaces und ein mal mit einer Klasse.</p>
<p>Gegeben seine Spielfiguren (Ritter, Bauer Troll) mit ihren Waffen (Schwert und Messer). Die Spielfiguren verhalten sich abhängig von Ihren Waffen im Kampf unterschiedlich.</p>
<p><strong>Variante1:</strong></p>
<p><a href="http://delphi400.neusath.de/wp-content/uploads/2008/08/strategy-interface.jpg"><img class="size-full wp-image-167" title="strategy-interface" src="http://delphi400.neusath.de/wp-content/uploads/2008/08/strategy-interface.jpg" alt="" width="738" height="305" /></a></p>
<pre><code><span style="font-size: x-small; font-family: Courier New;"><span style="color: #000000;"><em>{ *********************************************************************** }
{                                                                         }
{ Delphi Entwursmustersammlung  -- Strategy (mit Interface)               }
{                                                                         }
{ Autor: Thomas Gröschke                                                  }
{ Erstellt: 24.08.2008                                                    }
{                                                                         }
{ *********************************************************************** }
</em><strong>unit </strong>Strategy01;

<strong>interface

uses </strong>Dialogs;

<strong>type

</strong><em>// ---------------
// Waffenverhalten
// ---------------

  </em>IWaffenVerhalten = <strong>interface</strong>(IInterface)
    <strong>procedure </strong>VerwendeWaffe;
  <strong>end</strong>;

  TAxtVerhalten = <strong>class</strong>(TInterfacedObject, IWaffenVerhalten)
    <strong>procedure </strong>VerwendeWaffe;
  <strong>end</strong>;

  TMesserVerhalten = <strong>class</strong>(TInterfacedObject, IWaffenVerhalten)
    <strong>procedure </strong>VerwendeWaffe;
  <strong>end</strong>;

<em>// ---------------
// Figuren
// ---------------

  </em>TFigur = <strong>class</strong>(TObject)
  <strong>private
    </strong>FWaffenVerhalten: IWaffenVerhalten;
    Name: <strong>string</strong>;
  <strong>public
    constructor </strong>Create(iName: <strong>string</strong>; iActWaffenVerhalten: IWaffenVerhalten);
    <strong>destructor </strong>Destroy; <strong>override</strong>;
    <strong>procedure </strong>Kaempfen; <strong>virtual</strong>; <strong>abstract</strong>;
    <strong>procedure </strong>SetWaffe(iActWaffenVerhalten: IWaffenVerhalten);
  <strong>end</strong>;

  TRitter = <strong>class</strong>(TFigur)
    <strong>procedure </strong>Kaempfen; <strong>override</strong>;
  <strong>end</strong>;

  TBauer = <strong>class</strong>(TFigur)
  <strong>public
    procedure </strong>Kaempfen; <strong>override</strong>;
  <strong>end</strong>;

  TTroll = <strong>class</strong>(TFigur)
    <strong>procedure </strong>Kaempfen; <strong>override</strong>;
  <strong>end</strong>;

<strong>implementation

</strong><em>// ---------------
// Waffenverhalten
// ---------------

</em><strong>procedure </strong>TAxtVerhalten.VerwendeWaffe;
<strong>begin
  </strong>ShowMessage('Axt wird geschwungen');
<strong>end</strong>;

<strong>procedure </strong>TMesserVerhalten.VerwendeWaffe;
<strong>begin
  </strong>ShowMessage('Mit Messer wird gestochen');
<strong>end</strong>;

<em>// ---------------
// Basisklasse Figur
// ---------------

</em><strong>constructor </strong>TFigur.Create(iName: <strong>string</strong>; iActWaffenVerhalten: IWaffenVerhalten);
<strong>begin
  inherited </strong>create;
  Name := iName;
  FWaffenVerhalten := iActWaffenVerhalten;
<strong>end</strong>;

<strong>destructor </strong>TFigur.Destroy;
<strong>begin
  </strong><em>// Das Verhalten darf nicht freigegeben werden, da es ja
  // von außen "reingereicht" worden ist.
  </em><strong>inherited</strong>;
<strong>end</strong>;

<strong>procedure </strong>TFigur.SetWaffe(iActWaffenVerhalten: IWaffenVerhalten);
<strong>begin
  </strong>FWaffenVerhalten := iActWaffenVerhalten;
<strong>end</strong>;

<em>// ---------------
// Figuren
// ---------------

</em><strong>procedure </strong>TRitter.Kaempfen;
<strong>begin
  if </strong>FWaffenVerhalten &lt;&gt; <strong>nil then
    </strong>FWaffenVerhalten.VerwendeWaffe;
  <em>// weitere Aktionen...
</em><strong>end</strong>;

<strong>procedure </strong>TTroll.Kaempfen;
<strong>begin
  if </strong>FWaffenVerhalten &lt;&gt; <strong>nil then
    </strong>FWaffenVerhalten.VerwendeWaffe;
  <em>// weitere Aktionen...
</em><strong>end</strong>;

<strong>procedure </strong>TBauer.Kaempfen;
<strong>begin
  if </strong>FWaffenVerhalten &lt;&gt; <strong>nil then
     </strong>FWaffenVerhalten.VerwendeWaffe
  <em>// weitere Aktionen...
</em><strong>end</strong>;

<strong>end</strong>.
</span></span>
</code></pre>
<p>Etwas Quellcode zum Testen:</p>
<pre><code><span style="font-size: x-small; font-family: Courier New;"><span style="color: #000000;"><strong>procedure </strong>TForm1.Button1Click(Sender: TObject);
<strong>var
  </strong>Messer : IWaffenVerhalten;
  Axt : IWaffenVerhalten;
  Ritter1 : TFigur;
  Ritter2 : TFigur;
  Bauer : TFigur;
  Troll : TFigur;
<strong>begin
  </strong><em>// -----------
  // Nur hier, beim Erzeugen der konkreten Objekte, wird der tatsächliche
  // Typ (TMesser, TAxt, TRitter u.s.w. genannt.
  // -----------
  // Verhalten
  </em>Messer := TMesserVerhalten.Create;
  Axt := TAxtVerhalten.Create;
  <em>// Der Client
  </em>Ritter1 := TRitter.Create('Gerhard, der Stolze',Messer);
  Ritter2 := TRitter.Create('Otto, der Dumme',<strong>nil</strong>);
  Bauer := TBauer.Create('Josef',<strong>nil</strong>);
  Troll := TTroll.Create('Rumpel<span id="google-navclient-highlight" style="background-color: #50ccc5;">stiel</span>zchen',Axt);

  Troll.Kaempfen;
  Ritter1.Kaempfen;
  Ritter2.Kaempfen;
  Bauer.Kaempfen;
  Troll.Kaempfen;

  <em>// Ritter2 bekommt Messer
  </em>Ritter2.SetWaffe(Messer);
  Ritter2.Kaempfen;

  Troll.Free;
  Bauer.Free;
  Ritter2.Free;
  Ritter1.Free;

<strong>end</strong>;
</span>
</span>
</code></pre>
<p><strong>Variante2:</strong></p>
<p><a href="http://delphi400.neusath.de/wp-content/uploads/2008/08/strategy-klasse.jpg"><img class="alignnone size-full wp-image-166" title="strategy-klasse" src="http://delphi400.neusath.de/wp-content/uploads/2008/08/strategy-klasse.jpg" alt="" width="744" height="310" /></a></p>
<pre><code><span style="font-size: x-small; font-family: Courier New;"><span style="color: #000000;"><em>{ *********************************************************************** }
{                                                                         }
{ Delphi Entwursmustersammlung  -- Strategy (mit Klasse)                  }
{                                                                         }
{ Autor: Thomas Gröschke                                                  }
{ Erstellt: 24.08.2008                                                    }
{                                                                         }
{ *********************************************************************** }
</em><strong>unit </strong>Strategy02;

<strong>interface

uses </strong>Dialogs;

<strong>type

</strong><em>// ---------------
// Waffenverhalten
// ---------------

  </em>TWaffenVerhalten02 = <strong>class</strong>(TObject)
  <strong>private
    </strong>name: <strong>string</strong>;
  <strong>public
    constructor </strong>create(iName:<strong>string</strong>);
    <strong>procedure </strong>VerwendeWaffe; <strong>virtual</strong>;
  <strong>end</strong>;

  TAxtVerhalten02 = <strong>class</strong>(TWaffenVerhalten02)
    <strong>procedure </strong>VerwendeWaffe; <strong>override</strong>;
  <strong>end</strong>;

  TMesserVerhalten02 = <strong>class</strong>(TWaffenVerhalten02)
    <strong>procedure </strong>VerwendeWaffe; <strong>override</strong>;
  <strong>end</strong>;

<em>// ---------------
// Figuren
// ---------------

  </em>TFigur02 = <strong>class</strong>(TObject)
  <strong>private
    </strong>FWaffenVerhalten02: TWaffenVerhalten02;
    Name: <strong>string</strong>;
  <strong>public
    constructor </strong>Create(iName: <strong>string</strong>; iActWaffenVerhalten02: TWaffenVerhalten02);
    <strong>destructor </strong>Destroy; <strong>override</strong>;
    <strong>procedure </strong>Kaempfen; <strong>virtual</strong>;
    <strong>procedure </strong>SetWaffe(iActWaffenVerhalten02: TWaffenVerhalten02);
  <strong>end</strong>;

  TRitter02 = <strong>class</strong>(TFigur02)
    <strong>procedure </strong>Kaempfen; <strong>override</strong>;
  <strong>end</strong>;

  TBauer02 = <strong>class</strong>(TFigur02)
  <strong>public
    procedure </strong>Kaempfen; <strong>override</strong>;
  <strong>end</strong>;

  TTroll02 = <strong>class</strong>(TFigur02)
    <strong>procedure </strong>Kaempfen; <strong>override</strong>;
  <strong>end</strong>;

<strong>implementation

</strong><em>// ---------------
// Waffenverhalten
// ---------------

</em><strong>constructor </strong>TWaffenVerhalten02.create(iName:<strong>string</strong>);
<strong>begin
  </strong>Name := iName;
<strong>end</strong>;

<strong>procedure </strong>TWaffenVerhalten02.VerwendeWaffe;
<strong>begin
  </strong>ShowMessage('Weglaufen');
<strong>end</strong>;

<strong>procedure </strong>TAxtVerhalten02.VerwendeWaffe;
<strong>begin
  </strong>ShowMessage('Axt wird geschwungen');
<strong>end</strong>;

<strong>procedure </strong>TMesserVerhalten02.VerwendeWaffe;
<strong>begin
  </strong>ShowMessage('Mit Messer wird gestochen');
<strong>end</strong>;

<em>// ---------------
// Basisklasse Figur
// ---------------

</em><strong>constructor </strong>TFigur02.Create(iName: <strong>string</strong>; iActWaffenVerhalten02:
    TWaffenVerhalten02);
<strong>begin
  inherited </strong>create;
  Name := iName;
  FWaffenVerhalten02 := iActWaffenVerhalten02;
<strong>end</strong>;

<strong>destructor </strong>TFigur02.Destroy;
<strong>begin
  </strong><em>// Das Verhalten darf nicht freigegeben werden, da es ja
  // von außen "reingereicht" worden ist.
  </em><strong>inherited</strong>;
<strong>end</strong>;

<strong>procedure </strong>TFigur02.Kaempfen;
<strong>begin
  if </strong>FWaffenVerhalten02 &lt;&gt; <strong>nil then
    </strong>FWaffenVerhalten02.VerwendeWaffe;
<strong>end</strong>;

<strong>procedure </strong>TFigur02.SetWaffe(iActWaffenVerhalten02: TWaffenVerhalten02);
<strong>begin
  </strong>FWaffenVerhalten02 := iActWaffenVerhalten02;
<strong>end</strong>;

<em>// ---------------
// Figuren
// ---------------

</em><strong>procedure </strong>TRitter02.Kaempfen;
<strong>begin
  inherited</strong>;
  <em>// weitere Aktionen
</em><strong>end</strong>;

<strong>procedure </strong>TTroll02.Kaempfen;
<strong>begin
  inherited</strong>;
  <em>// weitere Aktionen
</em><strong>end</strong>;

<strong>procedure </strong>TBauer02.Kaempfen;
<strong>begin
  inherited</strong>;
  <em>// weitere Aktionen
</em><strong>end</strong>;

<strong>end</strong>.
</span></span>
</code></pre>
<p>Und auch hier etwas zum Testen.</p>
<pre><code><span style="font-size: x-small; font-family: Courier New;"><span style="color: #000000;"><strong>procedure </strong>TForm1.Button2Click(Sender: TObject);
<strong>var
  </strong>Messer : TWaffenVerhalten02;
  Axt : TWaffenVerhalten02;
  BasisWaffe : TWaffenVerhalten02;
  Ritter1 : TFigur02;
  Ritter2 : TFigur02;
  Bauer : TFigur02;
  Troll : TFigur02;
<strong>begin
  </strong><em>// -----------
  // Nur hier, beim Erzeugen der konkreten Objekte, wird der tatsächliche
  // Typ (TMesser, TAxt, TRitter u.s.w. genannt.
  // -----------
  // Verhalten
  </em>Messer := TMesserVerhalten02.Create('Messer');
  Axt := TAxtVerhalten02.Create('Axt');
  BasisWaffe := TWaffenVerhalten02.create('Standardwaffe');
  <em>// Der Client
  </em>Ritter1 := TRitter02.Create('Gerhard, der Stolze',Messer);
  Ritter2 := TRitter02.Create('Otto, der Dumme',BasisWaffe);
  Bauer := TBauer02.Create('Josef',BasisWaffe);
  Troll := TTroll02.Create('Rumpel<span id="google-navclient-highlight" style="color: white; background-color: #50ccc5;">stiel</span>zchen',Axt);

  Troll.Kaempfen;
  Ritter1.Kaempfen;
  Ritter2.Kaempfen;
  Bauer.Kaempfen;
  Troll.Kaempfen;

  <em>// Ritter2 bekommt Messer
  </em>Ritter2.SetWaffe(Messer);
  Ritter2.Kaempfen;

  Troll.Free;
  Bauer.Free;
  Ritter2.Free;
  Ritter1.Free;
  BasisWaffe.Free;
  Axt.Free;
  Messer.Free;
<strong>end</strong>;
</span>
</span>
</code></pre>
<p><span style="font-size: small;"><strong>Links zum Thema:</strong> </span><br />
<span style="font-size: x-small;"><br />
<a href="http://de.wikipedia.org/wiki/Strategie_(Entwurfsmuster)">Wikipedia</a><br />
</span></p>
]]></content:encoded>
			<wfw:commentRss>http://delphi400.neusath.de/das-strategy-muster.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Der Iterator</title>
		<link>http://delphi400.neusath.de/der-iterator.html</link>
		<comments>http://delphi400.neusath.de/der-iterator.html#comments</comments>
		<pubDate>Sat, 16 Aug 2008 15:59:51 +0000</pubDate>
		<dc:creator>Delphi400</dc:creator>
				<category><![CDATA[Entwurfsmuster]]></category>

		<guid isPermaLink="false">http://delphi400.neusath.de/?p=99</guid>
		<description><![CDATA[Das Iterator-Muster ermöglicht dem Client über eine Datenstruktur zu gehen (zu iterieren) ohne dass der Klient wissen muss wie sich diese Datenstruktur aufbaut. Das bedeutet ich habe eine Schnittstelle über die ich auf die Daten zugreife und dem Client kann es egal sein, ob die Daten in einem Array, einer List oder wie auch immer [...]]]></description>
			<content:encoded><![CDATA[<p>Das Iterator-Muster  ermöglicht dem Client über eine Datenstruktur zu gehen (zu iterieren) ohne dass  der Klient wissen muss wie sich diese Datenstruktur aufbaut. Das bedeutet ich habe eine Schnittstelle über die ich auf die Daten zugreife und dem Client kann es egal sein, ob die Daten in einem Array, einer List oder  wie auch immer vorliegen.<br />
Meistens habe ich es mit Objekten zu tun, welche ich in einer TList verwalte. Zum Beispiel innerhalb eines Kompositums. Wenn nun mein Client damit was machen will (z. B. alle Artikel einer Rezeptur im Formular auflisten)  erstellt das Kompositum einen Iteratur mit dessen Hilfe das Formular dann die Artikel  auflisten kann.</p>
<p><span id="more-99"></span></p>
<p>Hier erst mall der Quellcode für den Iterator:</p>
<pre>
<code><font  size=2 face="Courier New"><font color="#000000"><i>{ *********************************************************************** }
{                                                                         }
{ Delphi Entwursmustersammlung  -- Iterator                               }
{                                                                         }
{ Autor: Thomas Gr&ouml;schke                                                  }
{ Erstellt: 12.08.2008                                                    }
{                                                                         }
{ *********************************************************************** }
</i><b>unit </b>Iteratoren;

<b>interface

uses </b>Classes, Dialogs, sysutils;

<b>type

  </b>IIterator = <b>interface</b>(IInterface)
    <b>procedure </b>AddObj(iObj:TObject);
    <b>function </b>Count: Integer;
    <b>function </b>CurrentItem: TObject;
    <b>function </b>First: TObject;
    <b>function </b>HasNext: Boolean;
    <b>function </b>Next: TObject;
    <b>function </b>Prev: TObject;
  <b>end</b>;

  TListIterator = <b>class</b>(TInterfacedObject, IIterator)
  strict <b>private
    </b>FAggregate: TList;
    Index: Integer;
  <b>public
    constructor </b>Create(iValues:TList);
    <b>destructor </b>Destroy; <b>override</b>;
    <b>procedure </b>AddObj(iObj:TObject);
    <b>function </b>Count: Integer;
    <b>function </b>CurrentItem: TObject;
    <b>function </b>First: TObject;
    <b>function </b>HasNext: Boolean;
    <b>function </b>Next: TObject;
    <b>function </b>Prev: TObject;
  <b>end</b>;

<b>implementation

</b><i>{
******************************** TListIterator *********************************
}

</i><b>constructor </b>TListIterator.Create(iValues:TList);
<b>var
  </b>i : integer;
<b>begin
  inherited </b>Create;
  FAggregate := TList.Create;
  <b>if </b>iValues &lt;&gt; <b>nil then
    for </b>i := 0 <b>to </b>iValues.Count - 1 <b>do
      </b>AddObj(iValues[i]);
  Index := -1;
<b>end</b>;

<b>destructor </b>TListIterator.Destroy;
<b>begin
  </b>FAggregate.Free;
  <b>Inherited</b>;
<b>end</b>;

<b>procedure </b>TListIterator.AddObj(iObj:TObject);
<b>begin
  </b>FAggregate.Add(iObj);
<b>end</b>;

<b>function </b>TListIterator.Count: Integer;
<b>begin
  </b>result := TList(FAggregate).Count;
<b>end</b>;

<b>function </b>TListIterator.CurrentItem: TObject;
<b>begin
  if </b>TList(FAggregate).Count &lt;&gt; 0 <b>then
    </b>Result := TList(FAggregate).Items[Index]
  <b>else
    </b>result := <b>nil</b>;
<b>end</b>;

<b>function </b>TListIterator.First: TObject;
<b>begin
  if </b>TList(FAggregate).Count &lt;&gt; 0 <b>then
  begin
    </b>Result := TList(FAggregate).Items[0];
    Index := 0;
  <b>end
  else
  begin
    </b>result := <b>nil</b>;
    Index := -1;
  <b>end</b>;
<b>end</b>;

<b>function </b>TListIterator.HasNext: Boolean;
<b>begin
  if </b>TList(FAggregate).Count &gt; Index + 1 <b>then
    </b>Result := true
  <b>else
    </b>result := false;
<b>end</b>;

<b>function </b>TListIterator.Next: TObject;
<b>begin
  if </b>HasNext <b>then
  begin
    </b>Inc(Index);
    Result := TList(FAggregate).Items[Index];
  <b>end
  else
    </b>result := <b>nil</b>;
<b>end</b>;

<b>function </b>TListIterator.Prev: TObject;
<b>begin
  if </b>Index - 1 &gt; 0 <b>then
  begin
    </b>dec(Index);
    Result := TList(FAggregate).Items[Index];
  <b>end
  else
    </b>result := <b>nil</b>;
<b>end</b>;

<b>end</b>.
</font>
</font>
</code></pre>
<p>Quergecheckt (Links zum Thema):<br />
   <a href="http://forum.delphi-treff.de/showthread.php?t=14581 ">Wie werde ich ein Interface wieder los?</a><br />
   <a href="http://de.wikibooks.org/wiki/Muster:_Iterator ">Wikibooks: Muster Iterator</a></p>
]]></content:encoded>
			<wfw:commentRss>http://delphi400.neusath.de/der-iterator.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Das Kompositum</title>
		<link>http://delphi400.neusath.de/das-kompositum.html</link>
		<comments>http://delphi400.neusath.de/das-kompositum.html#comments</comments>
		<pubDate>Sat, 09 Aug 2008 14:33:36 +0000</pubDate>
		<dc:creator>Delphi400</dc:creator>
				<category><![CDATA[Entwurfsmuster]]></category>

		<guid isPermaLink="false">http://delphi400.neusath.de/?p=8</guid>
		<description><![CDATA[Immer wenn sich etwas in einer Baumstruktur darstellen lässt, wird es Zeit über das Kompositum-Muster nachzudenken. Wenn ich mir zum Beispiel eine Rezeptur anschaue, so besteht die aus Baugruppen (Gewürz, Soße, Panade). Diese Baugruppen bestehen aus Artikeln (Salz, Wasser, Mehl) und/oder weiteren Baugruppen (Curry, Pfeffermischung). Nun soll es möglich sein Operationen auf Teile dieser Rezeptur [...]]]></description>
			<content:encoded><![CDATA[<p>Immer wenn sich etwas in einer Baumstruktur darstellen lässt, wird es Zeit über das Kompositum-Muster nachzudenken.</p>
<p>Wenn ich mir zum Beispiel eine Rezeptur anschaue, so besteht die aus Baugruppen (Gewürz, Soße, Panade). Diese Baugruppen bestehen aus Artikeln (Salz, Wasser, Mehl) und/oder weiteren Baugruppen (Curry, Pfeffermischung). <strong>Nun soll es möglich sein Operationen auf Teile dieser Rezeptur oder auf das Ganze anzuwenden</strong> (Gib mir dein Gewicht, Gib mir deinen Wareneinsatz).</p>
<p><span id="more-8"></span></p>
<p><a href="http://delphi400.neusath.de/wp-content/uploads/2008/08/composite-klassendiagramm.jpg"><img class="alignnone size-medium wp-image-10" title="composite-klassendiagramm" src="http://delphi400.neusath.de/wp-content/uploads/2008/08/composite-klassendiagramm-300x154.jpg" alt="" width="300" height="154" /><br />
</a></p>
<pre><code><span style="font-family: Courier New; font-size: x-small;"><span style="color: #000000;"><em>{ *********************************************************************** }
{                                                                         }
{ Delphi Entwursmustersammlung  -- Composite                              }
{                                                                         }
{ Autor: Thomas Gröschke                                                  }
{ Erstellt: 09.08.2008                                                    }
{                                                                         }
{ *********************************************************************** }
</em><strong>unit </strong>Composite;

<strong>interface

uses
  </strong>Messages, Classes, Dialogs, Contnrs;

<strong>type

  </strong>TComponent = <strong>class abstract</strong>(TObject)
  <strong>private
    </strong>Key  : <strong>string</strong>;
    Name : <strong>string</strong>;
  <strong>public
    function </strong>GetName: <strong>string</strong>; <strong>virtual</strong>;

    <strong>procedure </strong>Add(AComponent :TComponent);<strong>virtual</strong>;
    <strong>procedure </strong>Remove(AComponent :TComponent);<strong>virtual</strong>;
    <strong>function </strong>GetChild(i:integer) : TComponent; <strong>virtual</strong>;
    <strong>function </strong>GetCount : integer; <strong>virtual</strong>;
  <strong>end</strong>;

  TComposite = <strong>class</strong>(TComponent)
  <strong>private
    </strong>FComponent: TObjectList;
  <strong>public
    constructor </strong>Create(iKey, iName : <strong>string</strong>);
    <strong>function </strong>GetName: <strong>string</strong>; <strong>override</strong>;

    <strong>procedure </strong>Add(AComponent :TComponent); <strong>override</strong>;
    <strong>procedure </strong>Remove(AComponent :TComponent); <strong>override</strong>;
    <strong>function </strong>GetChild(i:integer) : TComponent ; <strong>override</strong>;
    <strong>function </strong>GetCount : integer; <strong>override</strong>;
  <strong>end</strong>;

  TLeaf = <strong>class</strong>(TComponent)
  <strong>public
    constructor </strong>Create(iKey, iName : <strong>string</strong>);
    <strong>function </strong>GetName: <strong>string</strong>; <strong>override</strong>;
    <strong>function </strong>GetCount : integer; <strong>override</strong>;
  <strong>end</strong>;

<strong>implementation

</strong><em>{
********************************* TComponent **********************************
}

</em><strong>procedure </strong>TComponent.Remove(AComponent: TComponent);
<strong>begin
  </strong>ShowMessage('Error');
<strong>end</strong>;

<strong>function </strong>TComponent.GetCount: integer;
<strong>begin
  </strong>result := 0;
<strong>end</strong>;

<strong>function </strong>TComponent.GetChild(i: integer): TComponent;
<strong>begin
  </strong>ShowMessage('Error');
  result := <strong>nil</strong>;
<strong>end</strong>;

<strong>function </strong>TComponent.GetName: <strong>string</strong>;
<strong>begin
  </strong>result := Key + ', ' + Name;
<strong>end</strong>;

<strong>procedure </strong>TComponent.Add(AComponent: TComponent);
<strong>begin
  </strong>ShowMessage('Error');
<strong>end</strong>;

<em>{
********************************* TComposite **********************************
}

</em><strong>constructor </strong>TComposite.Create(iKey, iName: <strong>string</strong>);
<strong>begin
  inherited </strong>create;
  Key := iKey;
  Name := iName;
  FComponent := TObjectList.Create;
<strong>end</strong>;

<strong>procedure </strong>TComposite.Remove(AComponent: TComponent);
<strong>begin
  </strong>FComponent.Remove(AComponent);
<strong>end</strong>;

<strong>function </strong>TComposite.GetCount: integer;
<strong>begin
  </strong>result := FComponent.Count;
<strong>end</strong>;

<strong>function </strong>TComposite.GetChild(i: integer): TComponent;
<strong>begin
  </strong>result := TComponent(FComponent.Items[i]);
<strong>end</strong>;

<strong>function </strong>TComposite.GetName: <strong>string</strong>;
<strong>begin
  </strong>result := 'Kompositum: ' + Key + ', ' + Name;
<strong>end</strong>;

<strong>procedure </strong>TComposite.Add(AComponent: TComponent);
<strong>begin
  </strong>FComponent.Add(AComponent);
<strong>end</strong>;

<em>{
*********************************** TLeaf ************************************
}

</em><strong>constructor </strong>TLeaf.Create(iKey, iName: <strong>string</strong>);
<strong>begin
  inherited </strong>create;
  Key := iKey;
  Name := iName;
<strong>end</strong>;

<strong>function </strong>TLeaf.GetCount: integer;
<strong>begin
  </strong>result := 0;
<strong>end</strong>;

<strong>function </strong>TLeaf.GetName: <strong>string</strong>;
<strong>begin
  </strong>result := 'Blatt: ' + Key + ', ' + Name;
<strong>end</strong>;

<strong>end</strong>.
</span>
</span></code></pre>
<ul> <strong>Und hier der Quellcode zum Testen:</strong></ul>
<pre><code><span style="font-family: Courier New; font-size: x-small;"><span style="color: #000000;"><strong>unit </strong>Main;

<strong>interface

uses
  </strong>Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls,
  Composite, Composite2, Iteratoren;

<strong>type
  </strong>TForm1 = <strong>class</strong>(TForm)
    TreeView1: TTreeView;
    Button1: TButton;
    TreeView2: TTreeView;
    <strong>procedure </strong>Button1Click(Sender: TObject);
    <strong>procedure </strong>FormCreate(Sender: TObject);
  <strong>private
    </strong>Wurzel : TComponent;
    <strong>procedure </strong>CreateWurzel;
    <strong>procedure </strong>FillTree;
  <strong>public
    </strong><em>{ Public-Deklarationen }
  </em><strong>end</strong>;

<strong>var
  </strong>Form1: TForm1;

<strong>implementation

</strong><em>{$R *.dfm}

</em><strong>procedure </strong>TForm1.Button1Click(Sender: TObject);
<strong>begin
  </strong>FillTree;
<strong>end</strong>;

<strong>procedure </strong>TForm1.CreateWurzel;
<strong>var
  </strong>E1_Komponente : TComponent;
  E2_Komponente : TComponent;
  E3_Komponente : TComponent;
  E4_Komponente : TComponent;
<strong>begin
  </strong>Wurzel := TComposite.Create('Wurzel', 'Die Wurzel');
  E1_Komponente := TComposite.Create('E1', '#1 von Ebene 1');
  E2_Komponente := TComposite.Create('E2', '#1 von Ebene 2');
  E3_Komponente := TComposite.Create('E3', '#1 von Ebene 3');
  Wurzel.Add(E1_Komponente);
  E1_Komponente.Add(E2_Komponente);
  E2_Komponente.Add(E3_Komponente);

  E2_Komponente.Add(TLeaf.Create('B1','Blatt1 von E2'));
  E2_Komponente.Add(TLeaf.Create('B2','Blatt2 von E2'));
  E2_Komponente.Add(TLeaf.Create('B3','Blatt3 von E2'));

  E3_Komponente.Add(TLeaf.Create('B1','Blatt1 von E3'));

  E4_Komponente := TComposite.Create('E4', 'E4: Noch jemand da');
  Wurzel.Add(E4_Komponente);
  E4_Komponente.Add(TLeaf.Create('B1','Blatt1 von E4'));
<strong>end</strong>;

<strong>procedure </strong>TForm1.FillTree;

  <strong>procedure </strong>Recur(iActNode: TTreeNode; iKomponente:TComponent);
  <strong>var
    </strong>ActNode: TTreeNode;
    i : integer;
  <strong>begin
    if </strong>iKomponente &lt;&gt; <strong>nil then
      for </strong>i := 0 <strong>to </strong>iKomponente.GetCount - 1 <strong>do
      begin
        </strong>ActNode := TreeView1.Items.AddChildObject(iActNode, iKomponente.GetChild(i).GetName, iKomponente.GetChild(i));
        <strong>if </strong>iKomponente.GetChild(i).GetCount &lt;&gt; 0 <strong>then
           </strong>Recur(ActNode,iKomponente.GetChild(i));
      <strong>end</strong>;
  <strong>end</strong>;

<strong>begin
  </strong>TreeView1.Items.Clear;
  Recur(<strong>nil</strong>, Wurzel);
<strong>end</strong>;

<strong>procedure </strong>TForm1.FormCreate(Sender: TObject);
<strong>begin
  </strong>CreateWurzel;
<strong>end</strong>;

<strong>end</strong>.
</span>
</span>
</code></pre>
<p>Ich werde später noch mal auf das Muster zurück kommen und es mit mehr Funktionalität und einem Iterator versehen.</p>
<p>Weiterführende Links:</p>
<p><a title="Nestet Sets" href="http://www.klempert.de/nested_sets/" target="_blank">http://www.klempert.de/nested_sets/</a></p>
<p><a title="Nestet Sets (2)" href="http://www.bluegate.at/tutorials-faqs/design-patterns/nested-sets-verstehen-und-anwenden/" target="_blank">http://www.bluegate.at/tutorials-faqs/design-patterns/nested-sets-verstehen-und-anwenden/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://delphi400.neusath.de/das-kompositum.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
