08/2008 - KaffeeKlatsch
08/2008 - KaffeeKlatsch
08/2008 - KaffeeKlatsch
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
Abgeschottet<br />
deren, denen er das Objekt (großmütig) zur Verfügung<br />
stellt, dieses auf keinen Fall ändern sollen. Vertrauen ist<br />
gut, aber kein Schreibzugriff ist besser.<br />
Die besten Voraussetzungen so etwas zu schaffen, hat<br />
man mit Schnittstellen. Mit einer Schnittstelle hat man<br />
ganz präzise Möglichkeiten, den Zugriff auf das Objekt<br />
zu Beschreiben.<br />
public interface ReadableValue {<br />
public String getValue();<br />
}<br />
Ein solches Interface verrät nichts über die Implementierung<br />
und bietet dabei alles, was der Anwender<br />
wünscht.<br />
public static void doIt(ReadableValue rv) {<br />
… rv.getValue() …<br />
}<br />
Die Vorteile, die Interfaces generell mit sich bringen,<br />
bleiben dabei natürlich erhalten: Lose Kopplung von<br />
Klassen, Paketen oder Systemen; einfache Testbarkeit<br />
mit Hilfe geeigneter Mock-Klassen; 3 und viele, viele<br />
mehr.<br />
Eine Implementierung muss nun nur diesem Interface<br />
genügen, ansonsten gibt es keine Anforderungen an<br />
die implementierende Klasse.<br />
public class Value implements ReadableValue {<br />
String value;<br />
public Value(String value) {<br />
this.value = value;<br />
}<br />
public void setValue(String value) {<br />
this.value = value;<br />
}<br />
public String getValue() {<br />
return value;<br />
}<br />
…<br />
}<br />
Die Unverbesserlichen – die „das geht schon in Ordnung,<br />
ich weiß doch was ich tue“-Entwickler – könnten nun<br />
einfach auf die Idee kommen aus dem ReadableValue<br />
durch Casting ein Value machen. Das lässt sich aber<br />
verhindern, indem man die Value-Klasse nur innerhalb<br />
ihres Paketes bekannt macht.<br />
3<br />
Eine Mock-Klasse täuscht ein echte Klasse vor. Für das anwendende Programm<br />
ist kein Unterschied bemerkbar, da doch nur die Schnittstelle verwendet wird.<br />
Damit ist es relativ leicht, nutzende Programme zu testen, insbesondere kann<br />
man dann auch mit Daten testen, die im realen Anwendungsfällen eigentlich<br />
nicht auftreten können – es aber dann doch immer wieder tun.<br />
Geregelte Verhältnisse<br />
Will man nun eine Klasse doch für den Schreibzugriff<br />
öffnen, so muss man sich überlegen, ob ein Schreibzugriff<br />
einen Lesezugriff impliziert. Das ist zwar oft der Fall,<br />
aber durchaus nicht immer sinnvoll.<br />
public class Value implements Read, Write {<br />
…<br />
}<br />
Eine Trennung von Read und Write ist deswegen sinnvoll,<br />
weil nur so die beiden Schnittstellen unabhängig<br />
voneinander entwickelt werden können.<br />
interface ExtendedRead extends Read {<br />
…<br />
}<br />
interface ExtendedWrite extends Write {<br />
…<br />
}<br />
class ExtendedValue<br />
extends Value<br />
implements ExtendedRead<br />
{<br />
…<br />
}<br />
Letzteres hat dann leider nicht ganz so funktioniert wie<br />
gewünscht, weil sich die Write-Schnittstelle doch über<br />
die Value-Klasse eingeschlichen hat. Die einzige Lösung<br />
des Problems ist – wenn es vorher nicht absehbar<br />
ist, wie die Vererbung aussehen wird –, die Implementierungen<br />
ebenfalls losgelöst von den Schnittstellen zu<br />
halten.<br />
class ValueAdapter {<br />
…<br />
}<br />
class ExtendedValueAdapter extends ValueAdapter {<br />
…<br />
}<br />
class Value<br />
extends ValueAdapter<br />
implements Read, Write<br />
{<br />
// nur Konstruktoren, wenn überhaupt<br />
}<br />
class ExtendedValue<br />
extends ExtendedValueAdapter<br />
implements ExtendedRead<br />
{<br />
// nur Konstruktoren, wenn überhaupt<br />
}<br />
Seite 12 <strong>KaffeeKlatsch</strong> Jahrgang 1 / Nr. 8 / August 20<strong>08</strong>