# Checkstyle - Design for Extension



## NTB (30. Mai 2007)

Hiho,

ich habe mir das Checkstyle Plugin für Eclipse installiert. Checkstyle prüft den Code auf Konventionen und Coding Standards. Alleine schon, um mich daran zu erinnern, meinen eigenen Kram immer schön brav Du dokumentieren, ist das Plugin fein (aber auch anstrengend - wer dokumentiert schon jede Variable *g*).

Es sei folgender Code gegeben:


```
public class Foo {

    public String getHelloWorld() {
        return "Hello World";
    }
}
```

bei der Methode moniert Checkstyle folgendes:


```
Design For Extension: Die Methode 'getHelloWorld' ist nicht für Vererbung entworfen - 
	 muss abstract, final oder leer sein.
```

Mir ist nicht so ganz klar, warum sie so nicht für Vererbung geeignet ist.
Im Fall von Final kann sie von einem erbenden eben nicht überschrieben werden.
Im Fall von abstract wäre die Methode halt nicht ausformuliert. Wobei dann doch die gesamte Klasse abstract sein müsste, oder nicht? 
Warum ist aber die Methode besser für Vererbung geeignet, wenn sie leer ist?

Wenn ich z.B. einen BusinessController habe, dann würde ich die Methode "final" deklarieren. Geht von Euch tatsächlich jemand so vor, dass er solche Methoden alle als final deklariert?


----------



## Ullenboom (31. Mai 2007)

Hallo!

Bei Checkstyle habe ich mich auch schon zweimal an den Autor gewandt, weil ich einmal die Beschreibung unpräzise fand und zum anderen die Prüfung nicht vollständig war. Ich rätsele da auch immer und bei einer Meldung wie "Design For Extension" würde ich mir auch was Besseres wünschen. Der Grund aber, warum Checkstyle bei deinem Beispiel viel lieber


```
public class Foo {
    public final String getHelloWorld() {
        return "Hello World";
    }
}
```

sehen möchte ist der, dass man nicht-finale Methoden "aus versehen" überschreiben kann und somit unabsichtlich das Template-Pattern implementiert. Etwa bei folgendem Beispiel:


```
class A
{
  A() { a(); }
  void a() { System.out.println("A");}
}

class B extends A
{
  B() { a(); }
  void a() { System.out.println("B");}
  public static void main( String[] args ) { new B(); }
}
```

Hier wird bei new B(); zweimal a() aus B aufgerufen, was sicherlich nicht beabsichtigt war, da man denkt, das der Konstruktor A() auch "sein" a() aus A aufruft. Daher wird man a() aus A üblicherweise auch privat machen.

Daher kann man die Meldung auch so verstehen: "Design For Extension: Die Methode 'getHelloWorld' ist aktuell für Vererbung entworfen, wird aber nicht so verwendet. Mache die Methode abstract oder final oder leer, damit nicht aus Versehen eine Unterklasse Verhalten überschreibt."

Grüße

 Christian


----------



## NTB (31. Mai 2007)

Ok, also soll das verhindern, dass beim vererben (un)erwartetes (nicht) passiert 

So hatte ich das auch angenommen.

Jetzt bleibt mir aber immer noch eine Frage offen:
Wird das wirklich so in der Praxis umgesetzt? Ich habe jetzt noch nicht explizit drauf geachtet, aber ich glaube, ich würde darüber stolpern, wenn ich Code lesen würde, bei dem mehrere Methoden als "final" deklariert sind.


----------



## Ullenboom (31. Mai 2007)

Ich finde das mit dem final (genauso wie bei lokalen Variablen) zwar sehr verbose, doch mache ich es nur für meinen internen kleinen Quicky-Programme, die keiner sieht, nicht.

Grundsätzlich finde ich das eine gute Idee, weil ich denke, dass alles im Quellcode stehen muss und so ein Modifizierer auch etwas anders als eine Compiler-Bedeutung haben muss. (Da halte ich mich an den Ausspruch "everything is in the code".) Wenn eine Methode *nicht final* ist, *wird* sie überschrieben. Wenn eine Variable *nicht final* ist, *wird* sie später überschrieben. Lässt man's weg, kann's ja beides sein.

Grüße

 Christian


----------



## NTB (31. Mai 2007)

Danke für die Gedanken (währenddessen habe ich mir das in Deinem Blog gepostete PDF zu Ebays Architektur reingezogen *g*).

Vielleicht kann ich mich ja daran gewöhnen, in solchen Fällen tatsächlich die Methoden mit final zu deklarieren.


----------

