29 Aug 2010 @ 5:57 PM 

Vorwort

Nein, du wirst es nicht brauchen.

Aber du wirst es schreiben, testen, refactoren, dokumentieren und supporten.

Du wirst sehr viel Zeit dafür verwenden und veschwenden für keinen Nutzen.

Das Programm wird nicht rechtzeitig fertig und deine Erklärung ist der Fakt, dass man die Klassen wiederverwenden kann.
Quasi als Framework für das nächste  Programm.

Irgendwann kommt endlich der Tag, an dem ein neues Problem mit deinem “Framework” gelöst werden kann, nur ein paar “Anpassungen” sind notwendig.
du benutzt stolz deine Klassen und entdeckst einen Bug. Du löst den Bug,
schreibst gleich noch ein paar neue Methoden für neue Anwendungsfälle, welche dir in der Zeit eingefallen sind. Natürlich getestet und dokumentiert.
Dein Kollege bemerkt beiläufig, dass das Anpassen des Frameworks länger gedauert hat, als die Entwicklung eine Programmes, welches einfach nur das eine Problem löst.

Dein Kollege hat Recht

Viele überstrapazieren Entwickler- Credos wie:

  • Mach es wiederverwendbar!

und

  • Wiederhol dich nicht(DRY)!

und entwickeln  Code, der scheinbar alle Teilprobleme eines Problems lösen kann.
Dabei fällt einem nicht auf, dass man gerade Overengineering betreibt. Ein Anti-Pattern!

YAGNI vs Patterns

Ich möchte heute mal darüber schreiben, dass YAGNI nicht im Wiederspruch zu anderen Entwicklungs-Patterns steht,
sondern sehr gut damit vereinbar ist.

Als Beispiel soll hier das Problem eines Simplen FTP-Uploads herhalten. Da Oberprojekt sei eine
Web 2.0 Anwendung, bei der Profilbilder hochgeladen werden können.
Dazu soll das Jakarta Commons Net – Paket benutzt werden.
Dieses Problem kann man nun auf 3 Wege lösen.

Lösung 1:

Man schreibt in seinem Programm eine Methode in der Klasse, welche die Methode benötigt.

public void uploadFile(String filename){
File file = new File(filename)
FTPClient ftpClient = new FTPClient();
ftpClient.connect("hardcodededurl");
ftpClient.login("hardcodedusername", "hardcodededpw");
ftpClient.storeFile("filename", new FileInputStream(file));
ftpClient.logout();
ftpClient.disconnect();
 
}

Lösung 2:

Man schreibt eine Klasse, die per FTP Bilder hochladen kann.

Diese Klasse hat nur eine Methode und einen Konstruktor.

public class ImageFTPUploader{
    public ImageFTPUploader(String host,String user,String pw){
      // code
    }
    public  void upload(String filename){
       // code
    }
}

Lösung 3:

Man baut ein FTP-Framework mit folgendem Interface.

public interface IFTPUploader{
    public IFTPUploader(String host); // anonymer Zugang
    public IFTPUploader(String host,String user,String pw); // normaler Zugang
    public void setTransfermode(int mode); // ascii oder binary
    public File downloadFile(String remoteFile);
    public void uploadFile(String localFile);
    public String[] listDir(String remoteDir);
    public void changeDir(String remoteChangeDir);
    // ... und ne Menge mehr in Version 2 ...
}

Mach es wiederverwendbar

Schauen wir uns die 3 Lösungen an, ist klar, das Lösung 1 da ausscheidet. Die anderen beiden sind wiederverwendbar.
Allerdings stellen sich mir bei Lösung 3 die Fragen:

  • Muss ich setTransfermode immer aufrufen?
  • Was ist der Standardwert?

Ich bin gezwungen, die Doku zu lesen, weil so viele Möglichkeiten bestehen.
Mit Augenzudrücken gibt es keinen Punktabzug.

Punktestand: 0:1:1

Keep it Simple and Stupid (KISS)

Anders gesagt, schreib soviel Code wie du musst.

Hier scheidet Lösung 3 aus, weil sie viel mehr als nur das eine Problem löst.

Punktestand: 1:2:1

Don’t repeat yourself (DRY)

Dieses Pattern ist sehr eng verwandt mit “Mach es wiederverwendbar”, deswegen ist die Punkteverteilung die gleiche

Punktestand 1:3:2

Release early, Release Often(rero)

Das ist nicht nur ein Pattern für Firmen, sonder auch ein für Entwickler. Time-To-Market (TTM) ist da der entscheidende Faktor.
Code der irgendwann mal benutzt werden könnte,  aber nicht zur Problemlösung beiträgt ist unnütz. Er kostet aber viel Zeit.

Wieder scheidet Lösung 3 aus.

Punktestand 2:4:2

There’s more than one way to do it

Okay ganz anderes Problem (Phase 2 ;) ) jetzt sollen Lebensläufe im .doc,.docx oder .pdf Format hochgeladen werden auf einen anderen Server.
Das Projekt entwickelt ein anderer Programmierer als du.

Bei der Lösung 1 gibt’s das gute alte Copy+Paste. es gibt eine Methode in seinem LebenslaufConroller die sowas macht

Bei Lösung 2 gibt’s ähnliches Copy+Paste, nur heisst die neue Klasse LebenslaufFTPUploader oder DocumentUploader

Bei Lösung 3 gibt es gar 4 Möglichkeiten:

  1. Der andere Entwickler kennt dein Framework nicht und entwickelt was eigenes
  2. Der andere Entwickler kennt dein Framework, dieses liefert aber nicht die Funktionaltät und er entwickelt was eigenes
  3. Der andere Entwickler kennt dein Framework, dieses liefert aber nicht die Funktionaltät und er bittet dich, diese nachzuimplementieren
  4. Der andere Entwickler kennt dein Framework, dieses liefert die benötigte Funktionalität

Wollen wir ehrlich sein?
Möglichkeit 3 und 4 würden wir uns alle wünschen. Die anderen Möglichkeiten spiegeln die Realität dar.
Und manchmal sind wir im Urlaub oder krank. Deswegen bekommt Lösung 3 wieder keinen Punkt.

Punktestand 3:5:2

Worse is better / weniger ist mehr (wib)

Das muss man zunächst erklären:

  1. Simplicity: Das Programm/Die Klasse muss einfach benutzbar sein
  2. Correctness: alles was funktioniert, muss zu 100% funktionieren.
  3. Consistency: alles macht das, was man davon erwartet
  4. Completeness: alles ist da, um das Problem zu lösen

Eigentlich eine Sammlung der vorhergehenden Patterns.

Doch Lösung 3 passt einfach nicht dazu.

Punktestand 4:6:2

MoSCow

Kurze Erklärung

  1. Must have – Minimal Usable SubseT – Kann alles was es soll
  2. Should have – Erwartungen an die Klasse
  3. Could have – Hoffnungen an die Klasse
  4. Won’t have – Die Goodies

Okay, die gleichen Vorraussetzungen wie bei “There’s more than one way to do it”.
Hier geht es um Erwartungen  an den Code.

Lösung 1: man erwartet das es im Ausgangskontext funktioniert
Lösung 2: man erwartet das es funktioniert, Bilder über FTP hochzuladen
Lösung 3: man erwartet das es funktioniert, bei allem was man über FTP machen kann

Die Frage ist nun: erfüllt man diese Erwartungen?
Bei Lösung 1 und 2 ist es einfach, jedoch sind die Erwartungen bei Lösung 3 recht hoch.
Man erwartet, das neue Problem damit lösen zu können … und werden diese Erwartungen, von denen man beim Schreiben keinen blassen Schimmer hatte, nicht erfüllt … verdammt man diese Klassse!

Punktestand 5:7:2

Fazit

Ich könnte die Liste beliebig erweitern, doch das Ergebnis ist klar:
Code den man nicht wiederverwenden kann, ist Mist.
Coder der unter der Prämisse entsteht, alles zu können, ist Mist.

Code ist nur dann sinnvoll, wenn er seinen Zweck erfüllt und diesen Zweck zuverlässig erfüllt

Posted By: tkdmatze
Last Edit: 29 Aug 2010 @ 05:57 PM

EmailPermalinkComments (0)
Tags
Categories: MyWeb

 Last 50 Posts
 Back
Change Theme...
  • Users » 2
  • Posts/Pages » 30
  • Comments » 6
Change Theme...
  • VoidVoid « Default
  • LifeLife
  • EarthEarth
  • WindWind
  • WaterWater
  • FireFire
  • LightLight