Tell don’t ask – Weg mit den Gettern [endlich-clean.net]

Im Zusammenhang mit dem Tell don’t ask Prinzip erläutere ich oft, dass man als Entwickler versuchen sollte, auf Getter zu verzichten. Danach schaue ich meist in ungläubige Gesichter ;-)

Heute bin ich in einem Video wieder mal darüber gestolpert (ab Minute 17:26 geht es um Mock Objekte, bei 20:02 um Smart Handlers). Ja, auch andere erzählen das. Deshalb muss es noch nicht richtig sein, aber ich halte den Ansatz nach wie vor für nützlich. Nicht im Sinne eines Dogmas wie etwa “Verwende keine Getter!”, sondern als ein nützliches Tool in meinem Werkzeugkasten.

Nehmen wir mal ein Beispiel, bei dem es auf Anhieb schwer fällt, sich die Klasse ohne Getter vorzustellen:

   1: public class Kunde

   2: {

   3:   public string Name { get; set; }

   4:   public string Vorname { get; set; }

   5:   public string Nummer { get; set; }

   6: }

Aber wie wäre es damit:

   1: public class Kunde

   2: {

   3:   private string vorname;

   4:   private string name;

   5:   private string nummer;

   6:  

   7:   public void HandleDetails(KundeHandler handler) {

   8:     handler.Name(string.Format("{0} {1}", vorname, name));

   9:     handler.Nummer(nummer);

  10:   }

  11: }

Wenn nun die Details eines solchen Kunde Objektes auf die Konsole geschrieben werden sollen, muss nur ein entsprechender Handler implementiert werden:

   1: public class ConsoleWriter : KundeHandler

   2: {

   3:   public void Name(string name) {

   4:     Console.WriteLine(name);

   5:   }

   6:  

   7:   public void Nummer(string nummer) {

   8:     Console.WriteLine(nummer);

   9:   }

  10: }

Auch andere Aufgaben sind denkbar und leicht zu realisieren, wie z.B. Konvertierung/Mapping in ein ViewModel oder Data Tranfer Object.

Vorteile

Die Klassen halten das Single Responsibility Principle ein. Denn die Klasse übernimmt auf diese Weise nicht auch noch die Aufgabe der Darstellung, sondern delegiert diese an eine Handler Klasse.

Das Information Hiding Prinzip ist eingehalten. In obigem Beispiel ist es für den Handler völlig irrelevant, wie der Kundenname intern repräsentiert wird. Ob dazu zwei Felder, wie im Beispiel, verwendet werden oder nur eines ist nach außen nicht sichtbar. Durch den Wegfall der Getter sind die Beziehungen zwischen der Kunde Klasse und anderen reduziert.

Die Klasse behält ihre Automomie. Dies ist in der Regel eine Folge des Tell don’t ask Prinzip. Wenn Objekte nur Befehle entgegen nehmen, bleibt von außen keine Möglichkeit, auf unterschiedliche Zustände des Objektes zu reagieren. Der Zustand ist schlicht nicht sichtbar. Das führt dazu, dass die Logik in der Klasse landet, zu der sie gehört.

Nicht zuletzt können die einzelnen Klassen einfacher in Isolation getestet werden. Es wird nicht mehr ein Kunde Objekt in eine andere Klasse hineingereicht, sondern lediglich die benötigten skalaren Werte (oder auch komplexe Value Objects). Die Handler Objekte fungieren als Vermittler.

Fazit

Einfach mal ausprobieren!

Kick it on dotnet-kicks.de

5 Responses to “Tell don’t ask – Weg mit den Gettern [endlich-clean.net]”

  1. Sebastian Jancke Says:

    endlich getter-los ;-)

    Ich behaupte mal noch schlimmer als ein Getter ist ein Getter der bool(ean) zurückgibt.

  2. Stefan Lieser Says:

    Jep, ungefähr so:

    if (!service.IsInitialized()) service.Initialize();

    Grrrr…. Tell don’t ask! Wäre service.Initialize() idempontent, bräuchte es keinen Getter.

  3. Gordon Breuer Says:

    Hum…

    Ich habe mir das Video ehrlich gesagt noch nicht angesehen, aber so ganz habe ich das “Problem” noch nicht verstanden. Könnte auch daran liegen, dass ich die “Lösung” noch nicht 100% nachvollziehen kann, aber vermutlich ist das Thema zu umfangreich und komplex um es mal eben zwischen “Tür und Angel” zu erfassen.

    Hast du vielleicht Link-Tipps dazu, dann schaue ichs mir doch noch mal etwas genauer an. ;-)

    Gruß, Gordon

  4. Stefan Lieser Says:

    @Gordon
    Links zu Tell don’t aks:
    http://www.pragprog.com/articles/tell-dont-ask
    http://c2.com/cgi/wiki?TellDontAsk
    http://www.javangelist.de/space/Tell,+don‘t+ask

    Grüße
    Stefan

  5. Bernd Hengelein Says:

    Folgender Post nimmt sich auch dem Thema an:
    http://jamesladdcode.com/?p=12
    Der Autor nennt sein Vorgehen “East Bound”. Auch sehr interesant.

    Bernd