# Frage zu Programmierstil



## Guest (18. Aug 2008)

Hallo zusammen,
ich habe eine kleine Frage zum Thema Programmierstil. 
Bislang habe ich in einer Methode alle Objekte / Datentypen deklariert und ggfs initialisiert. Dies "sollte" guter Programmierstil sein. 
Jetzt habe ich aber öfters Objekte, die ich nur innerhalb einer while-schleife benötige. Diese hatte ich bislang auch immer am Anfang der Methode angelegt. 
Jedoch denke ich mittlerweile, dass es besser ist, die Deklarationen so "lokal" wie möglich zu halten.


Was haltet ihr davon bzw. wie setzt ihr das um?


Vorher:


```
private void methodX(){
    int tempInt;
    String tempString;

    //...
    while() {
    // hier werden die temp.... genutzt
    }
    //...
}
```


Nachher:


```
private void methodX(){
    //...
    while() {
    int tempInt;
    String tempString;

    // hier werden die temp.... genutzt 
    }
    //...
}
```


----------



## maki (18. Aug 2008)

Lass das temp weg und nutze eine for Schleife, schon viel besser.


----------



## byte (18. Aug 2008)

Variablen immer erst in dem Scope deklarieren, wo sie auch benutzt werden. Das hilft (i) dem GC und (ii) beim Verständnis des Codes.


----------



## Leroy42 (18. Aug 2008)

Anonymous hat gesagt.:
			
		

> Jedoch denke ich mittlerweile, dass es besser ist, die Deklarationen so "lokal" wie möglich zu halten.




Das sehe ich genauso!


----------



## schalentier (18. Aug 2008)

byto hat gesagt.:
			
		

> Variablen immer erst in dem Scope deklarieren, wo sie auch benutzt werden. Das hilft (i) dem GC und (ii) beim Verständnis des Codes.



Beiden Punkten wuerde ich widersprechen:

Dem GC is das ziemlich egal (Details hier).

Ueber die Lesbarkeit kann man streiten, ich persoenlich bevorzuge die Deklaration der Variablen am Anfang der Methode. So kann ich mit dem ersten Blick erkennen:
i) Wie heisst die Methode und was liefert sie zurueck
ii) Welche Parameter bekommt die Methode
iii) Welche (lokalen) Variablen existieren in der Methode

Weiterhin kann man so die Variablen gleich noch vernuenftig initialiseren und ein "//"-Kommentar dahinter machen, um den Sinn der Variable zu erklaeren.

Obendrein bekomm ich direktes Feedback vom Quellcode: Wenn ich feststellen muss, dass in meiner Methode sehr viele Variablen deklariert werden, kann ich davon ausgehen, dass die Methode zu viel macht und 2 Methoden die bessere Wahl waeren. 

Demnach: 

```
private void methodX() {

    int    tempInt    = 0;
    String tempString = null;

    //...
    while() {
       // hier werden die temp.... genutzt
    }
}
```


----------



## maki (18. Aug 2008)

Schalentier,

Kommentare sind ein ziemlich eindeutiges Zeichen für schlechten Code und wenn man die Variablen dort deklariert wo man sie braucht, sieht man gleich wozu sie gehören


----------



## Leroy42 (18. Aug 2008)

schalentier hat gesagt.:
			
		

> ich persoenlich bevorzuge die Deklaration der Variablen am Anfang der Methode.



In C war das damals notwendig, in Java jedoch finde ich das eher als schlechten Stil.


----------



## tfa (18. Aug 2008)

schalentier hat gesagt.:
			
		

> Dem GC is das ziemlich egal (Details hier).


Je kürzer die Lebenszeit eines Objekts, desto leichter hat es der GC (u.U. ist ein GC-Lauf gar nicht nötig, um kurzlebige Objekte abzuräumen). Und das erreicht man durch möglichst lokalen Scope.
Der Artikel sagt übrigens nicht viel über GC aus. Ich hoffe, du hast dir auch die Kommentare durchgelesen.


----------



## byte (18. Aug 2008)

schalentier hat gesagt.:
			
		

> iii) Welche (lokalen) Variablen existieren in der Methode


Diese Information ist mir ziemlich egal. Wenn ich Quellcode lese, dann möchte ich (so abstrakt wie möglich), wissen was sie macht. Das kann ich am besten, wenn die Variable dort zum ersten Mal auftaucht, wo sie auch benutzt wird. Alles andere sind unnötige Informationen. Wenn eine Variable erst in einer Schleife benutzt und deklariert wird, dann weiss ich genau, dass ich diese Variable ausserhalb des Scopes wieder vergessen kann. Werden alle Variablen hingegen am Anfang deklariert, dann kann ich überhaupt keine Aussage darüber treffen, wann sie benutzt werden.



> Obendrein bekomm ich direktes Feedback vom Quellcode: Wenn ich feststellen muss, dass in meiner Methode sehr viele Variablen deklariert werden, kann ich davon ausgehen, dass die Methode zu viel macht und 2 Methoden die bessere Wahl waeren.


Das Feedback hast Du direkt, wenn Du Dir die LOCs der Methode anguckst. Wozu bitte noch alle Variablen auf einem Haufen sehen?


----------



## Saxony (18. Aug 2008)

Hiho,

die Deklaration an der Stelle wo die Variable auch gebraucht wird, halte ich auch für am besten. Solche Var Cluster zu Beginn einer Methode waren mir persönlich schon immer ein Graus.

Ich erinnere nur an Zeiten wie:


```
procedure Proc();
var
   i: Integer;
   j: Integer;
   k: Integer;
   c: char;
   s: string;
   T: TMyOwn;
   D: TSomeOtherType;
   ...
begin
   {something usefull}
end;
```



bye Saxony


----------



## GambaJo (18. Aug 2008)

Einerseits finde ich das persönlich auch nicht so übersichtlich, wenn man mittendrin Variablen deklariert, andererseits hat es mich bei sehr langen Funktionen schon immer gestört für eine neue Variable an den Anfang springen zu müssen, um sie zu deklarieren (nicht in Java). Da kommt man so leicht raus aus dem Programmierfluss.


----------



## maki (18. Aug 2008)

GambaJo hat gesagt.:
			
		

> Einerseits finde ich das persönlich auch nicht so übersichtlich, wenn man mittendrin Variablen deklariert, andererseits hat es mich bei sehr langen Funktionen schon immer gestört für eine neue Variable an den Anfang springen zu müssen, um sie zu deklarieren (nicht in Java). Da kommt man so leicht raus aus dem Programmierfluss.


Sehr lange Methoden sind schlecht und so gar nicht OO, sollten aufgeteilt werden 
Davon abgesehen ist "mittendrin" unglöücklich ausgedrückt, ersetze es durch "dort wo sie gebraucht werden" und es sollte klar sein was gemeint ist und auch warum.


----------



## schalentier (18. Aug 2008)

maki hat gesagt.:
			
		

> Kommentare sind ein ziemlich eindeutiges Zeichen für schlechten Code


Ja richtig, aber sie sind nicht immer zu vermeiden.

@tfa: Auch richtig, aber Deklarationen am Anfang einer Methode widersprechen dem nicht. Die Methoden muessen nur kurz genug sein ;-)



			
				byto hat gesagt.:
			
		

> Diese Information ist mir ziemlich egal. Wenn ich Quellcode lese, dann möchte ich (so abstrakt wie möglich), wissen was sie macht. Das kann ich am besten, wenn die Variable dort zum ersten Mal auftaucht, wo sie auch benutzt wird. Alles andere sind unnötige Informationen. Wenn eine Variable erst in einer Schleife benutzt und deklariert wird, dann weiss ich genau, dass ich diese Variable ausserhalb des Scopes wieder vergessen kann. Werden alle Variablen hingegen am Anfang deklariert, dann kann ich überhaupt keine Aussage darüber treffen, wann sie benutzt werden.



Nochmal: Am Anfang deklariere ich die verwendeten, lokalen Variablen. Dann kommen Sicherheitschecks, dann der Kern der Methode, dann der Schluss. Will ich wissen, was die Methode macht, konzentriert man sich intuitiv auf den Kern und dort ist dann eben weniger Code, da keine Deklarationen mehr vorhanden sind. Am besten mach ich mal ein Beispiel:


```
public int fooBar( int count ) {
  KomplizierterAlgorithmusFactory factory = KomplizierterAlgorithmusFactory.getFactory();
  KomplizierterAlgorithmus algorithmus = factory.create();
  int result = 0;
  for( int i=0; i<count; i++ ) {
    AlgorithmusResult algorithmusOutput = algorithmus.solve( i );
    result += algorithmusOutput.toIntValue();
  }
  return result;
}
```


```
public int fooBar( int count ) {
  int                             result             = 0;
  KomplizierterAlgorithmusFactory factory;
  KomplizierterAlgorithmus        algorithmus;
  AlgorithmusResult               algorithmusOutput;

  factory     = KomplizierterAlgorithmusFactory.getFactory();
  algorithmus = factory.create();

  for( int i=0; i<count; i++ ) {
    algorithmusOutput = algorithmus.solve( i );
    result           += algorithmusOutput.toIntValue();
  }

  return result;
}
```

So, was davon besser lesbar ist muss jeder selbst entscheiden.


----------



## SlaterB (18. Aug 2008)

unabhängig von der Frage ist das Zweite übrigens nicht Formatter-konform und damit nicht zu gebrauchen, 
es sei denn man drückt nie Strg-F und formatiert jedes Leerzeichen alleine..

noch besser wäre natürlich ein eigener Formatter, der das so hinbekommt


----------



## schalentier (18. Aug 2008)

1. Ist selbstformatierter Quellcode immer besser als Strg+F
2. Fuer die faulen gibts Formatter, die das koennen (JIndent)


----------



## byte (18. Aug 2008)

schalentier hat gesagt.:
			
		

> Deklarationen am Anfang einer Methode widersprechen dem nicht. Die Methoden muessen nur kurz genug sein ;-)


Wenn die Methode eh hinter dem eigentlichen Scope der Variable endet, dann ist es egal. Trotzdem war Dein Widerspruch oben etwas sinnbefreit.  



			
				schalentier hat gesagt.:
			
		

> Nochmal: Am Anfang deklariere ich die verwendeten, lokalen Variablen. Dann kommen Sicherheitschecks, dann der Kern der Methode, dann der Schluss. Will ich wissen, was die Methode macht, konzentriert man sich intuitiv auf den Kern und dort ist dann eben weniger Code, da keine Deklarationen mehr vorhanden sind.


Die Problematik ist nicht sonderlich kompliziert, ich habe Dich schon verstanden. Du stehst mit Deiner Meinung zu diesem Thema aber wohl ziemlich alleine da, und zwar nicht nur hier im Forum.


----------



## Saxony (19. Aug 2008)

Hiho,

@schalentier

Wie verhält es sich dann bei dir mit solchen methoden:


```
private String getFunctionCode(String aCode, int aPos) {

	run = false;		
	String erg = aCode.substring(aPos);
	String name = erg.substring(0, erg.indexOf('('));
	
	if(functions.containsKey(name)) {
	
		run = true;			
		return name;
	}
		
	String code = getInlineCode(erg.substring(name.length()), '(', ')');
				
	functions.put(name, code);

	return name;
}
```

Sollte ich da code auch schon zu Beginn deklarieren, auch wenn es unnötig ist, da ja vorher schon das return kommen könnte.

Es gibt ja zwei Möglichkeiten:


```
String code = "";
// oder 
String code = getInlineCode(erg.substring(name.length()), '(', ')');
```

Beides ist aber unnütz, da ich im Falle von if(functions.containsKey(name)) einmal eine überflüssige String Variable habe, welche ich nie brauche und im zweiten Fall habe ich sogar noch eine andere Methode angeschubst um gleich einen Wert für code zu berechnen, welchen ich auch nicht immer brauche. Wieso also nicht dort deklarieren/berechnen wo ich das dann auch sicher brauche?

bye Saxony


----------



## schalentier (19. Aug 2008)

Kurze Antwort: Ja.

Lange Antwort:


```
private String getFunctionCode(String aCode, int aPos) {

    String functionName = null;
    String function;
    String functionCode;
    String functionBody;
    int    leftParenthesis;

    run = false;

    if ( (aCode != null) && (aPos >= 0) && (aPos < aCode.length()) ) {

        function        = aCode.substring(aPos);
        leftParenthesis = function.indexOf('('); // FIXME: '(' not found
        functionName    = function.substring(0, leftParenthesis);

        if ( functions.containsKey(functionName) ) {

            run = true;
        } else {

            functionBody = function.substring(functionName.length());
            functionCode = getInlineCode(functionBody, '(', ')');
            functions.put(functionName, functionCode);
        }
    } else {
        handleIllegalArguments("aCode", aCode, "aPos", aPos);
    }

    return functionName;
}
```

Weiterhin denkbar waere, die Zeilen 15/16 und 23/24 in eigne Methoden auszulagern.

Ich wollt hier nur dem TO (und alle Interessierten) einen alternativen Weg zeigen, fuer einen entscheiden muss jeder selbst.


----------



## ARadauer (19. Aug 2008)

schalentier hat gesagt.:
			
		

> 1. Ist selbstformatierter Quellcode immer besser als Strg+F


sorry versteh ich nicht, bei mir sieht mein selbstformatierter code, genauso aus wie nach strg+f. Sollte das nicht so sein, würd ich mal meinen Formater anpassen.


----------



## tfa (19. Aug 2008)

Hier hat schalentier recht. Ich kenn auch keinen zufriedenstellenden automatischen Formatierer.


----------



## byte (19. Aug 2008)

Den Großteil deckt der Eclipse Formatter aber schon ab imo.


----------



## tfa (19. Aug 2008)

Das ist richtig, ich verwende den auch. Aber manchmal muss man schon von Hand nachformatieren, wenn man es vernünftig haben will.


----------



## schalentier (19. Aug 2008)

Der Eclipse-Formatter kann den Quellcode nicht ausrichten, wie in meinen Beispielen zu sehen. Und da ich mich nicht irgendwelchen Tools unterordnen moechte (sondern sich die Tools gefaelligst mir unterzuordnen haben), hab ich nur 2 Alternativen: 
i) Selbstformatieren (bzw. gleich richtig schreiben ;-)) 
ii) einen flexibleren Formatter nehmen (z.B. eben JIndent, mit dem hab ich die Codebeispiele formatiert - kann aber gut sein, dass es noch bessere gibt, hab da nicht lange gesucht)


----------



## Yzebär (19. Aug 2008)

@schalentier

Variablen am Anfang zu definieren ist in modernen Sprachen kein guter Stil. Früher mußte das so gemacht werden, weil der Compiler die Variablennamen sonst nicht auflösen konnte (Unterteilung in Deklarationsblock und Ausführungsblock), d.h. es war keine bewußte Entscheidung dafür, sondern eine Zweckmäßigkeit. Wozu man diesen Stil aufrecht erhalten soll, ist mir auch nach deinen Beispielen mehr als rätselhaft. Der Code ist schlechter lesbar (zB bei komplexeren Algorithmen mit vielen Variablen) und du kannst nach diesem Stil fast nie "final" für Variablen verwenden.


----------



## schalentier (19. Aug 2008)

Final verwende ich fast nie und wenn der Code schlecht lesbar wird, weil am Anfang ein riesiger Block Deklarationen steht, ist die Methode (wie bereits gesagt) zu lang und sollte in mehrere kleinere aufgeteilt werden (zumal ich die Logik nicht verstehe, wieso durch das "Auslagern" der Deklaration an den Anfang, der Code schlechter lesbar sein soll - erst Recht bei komplexen Algorithmen.. da wo es interessant ist, steht mit meiner Version deutlich weniger Quellcode -> einfacher). 
Und das es "frueher" Pflicht war (Turbo Pascal, C) und heute nicht mehr, ist kein Argument. Nicht alles von heute ist besser als frueher ;-)


----------



## byte (19. Aug 2008)

schalentier hat gesagt.:
			
		

> Der Eclipse-Formatter kann den Quellcode nicht ausrichten, wie in meinen Beispielen zu sehen. Und da ich mich nicht irgendwelchen Tools unterordnen moechte (sondern sich die Tools gefaelligst mir unterzuordnen haben), hab ich nur 2 Alternativen:
> i) Selbstformatieren (bzw. gleich richtig schreiben ;-))
> ii) einen flexibleren Formatter nehmen (z.B. eben JIndent, mit dem hab ich die Codebeispiele formatiert - kann aber gut sein, dass es noch bessere gibt, hab da nicht lange gesucht)


Der Eclipse Formatter beherrscht diese Einrückung, allerdings nicht für lokale Variablen in Methoden, sondern für die Felder einer Klasse. Du bist aber auch der erste, den ich kennenlerne, der auf diese Weise seine lokalen Variablen deklariert.

In größeren Teams ist es übrigens sehr ärgerlich, wenn jeder Entwickler nach unterschiedlichen Richtlinien formatiert. Da sollte man sich tunlichst auf einen Standard einigen.


----------



## SlaterB (19. Aug 2008)

ein schalentier würde sich aber nie unterordnen..


----------



## maki (19. Aug 2008)

Code manuell formatieren?

Klar, wenn es keine echten Vorgaben für das Projekt gibt und jeder Entwickler macht was er will..

Ansonsten müssen immer die gleichen Konventionen befolgt werden, lässt sich eben nur mit automatischem Formatieren sicherstellen, zahlt sich vor allem in mittleren bis größeren Teams aus.

Abgesehen davon habe ich einrückungen wie oben das letzte mal in Turbo Pascal gesehen und selbst gemacht


----------



## schalentier (19. Aug 2008)

SlaterB hat gesagt.:
			
		

> ein schalentier würde sich aber nie unterordnen..


--zensiert--

Wir haben uns auf einen Standard geeinigt. ;-) Sieht so aus wie in den Beispielen oben.


----------



## Yzebär (19. Aug 2008)

schalentier hat gesagt.:
			
		

> Final verwende ich fast nie



Aber du weißt, daß die Verwendung von final den Code lesbarer (man weiß daß die Variable nur einmal beschrieben werden kann) und sicherer macht (unabsichtliches beschreiben wird vom Compiler verhindert)?



> und wenn der Code schlecht lesbar wird, weil am Anfang ein riesiger Block Deklarationen steht
> , ist die Methode (wie bereits gesagt) zu lang und sollte in mehrere kleinere aufgeteilt werden



Viel Spaß beim debuggen, testen und erstellen von Sequenzdiagrammen... eine Methode, die man mit einem Blick (inkl Deklarationsblock) erfassen kann, wird sicher keine 10 Zeilen umfassen...



> (zumal ich die Logik nicht verstehe, wieso durch das "Auslagern" der Deklaration an den Anfang, der Code schlechter lesbar sein soll - erst Recht bei komplexen Algorithmen..



Man kann zB sofort sehen, daß in welchem Scope die Variable gültig ist (macht sich sehr gut, wenn mal ohne IDE oder Editor mit Syntax Highlighting auskommen muß) und von welchem Typ die Variable ist.



> da wo es interessant ist, steht mit meiner Version deutlich weniger Quellcode -> einfacher).



Nicht nur weniger Code, sondern auch weniger Informationen.



> Und das es "frueher" Pflicht war (Turbo Pascal, C) und heute nicht mehr, ist kein Argument. Nicht alles von heute ist besser als frueher



Es ging mir darum aufzuzeigen, daß es früher nicht anders ging und man sich nicht freiwillig dafür entschieden hat. Auch wenn es in deinen Augen kein Argument gegen deine Version ist, so ist es zumindest auch kein Argument für deine Version.


----------



## schalentier (19. Aug 2008)

Herrje. Da hab ich mir ja was eingebrockt. 

Ich haett gern ein Beispiel fuer eine final Variable, so wie du es oben beschrieben hast. Fuer nicht-aenderbare Werte nehme ich normalerweise Konstanten. 

Zum Rest:

Mein Ziel (und das meiner Firma - und sicher das von den meisten hier) ist das Erstellen von gutem Quellcode, der
i) korrekt ist
ii) sicher ist (im Sinne von Robust gegen Fehleingaben)
iii) performant ist, wo es sinnvoll erscheint 

Unser Trick ist nun, so kurze Methoden wie moeglich zu schreiben. 1 Aufgabe pro Methode. Das hat einige Auswirkungen.

Pro Methode:
- wenig Scopes
- wenig lokale Variablen
- wenig LOC 

Das wiederrum erlaubt Dinge, die mit den bekannten, laenglichen Methoden nicht so in dieser Weise machbar sind:
- Variablendeklaration an den Anfang (siehe Sun Code Conventions) --> wird dieser Deklarationsblock zu lang --> Methode zu gross, Refaktoring
- Trennung Deklaration und Zuweisung (Lesbarkeit) --> Possible Nullpointer Exceptions sind sofort sichtbar, bessere Formatierung moeglich (Alignment)
- Ein "Kern" pro Methode, sticht hervor --> Lesbarkeit 

Es entstehen kleine, kurze Methoden. Diese sind fuer sich einfacher zu testen (Unittests) und genauso debugbar wie jede andre Methode auch. 

Diese Methoden sind auch viel besser wiederverwendbar, indem man sie in der Hierarchie nach oben schiebt (je kuerzer und atomarer, desto haeufiger koennen sie an anderen Stellen benutzt werden).

Ueber ein Beispiel, wo diese Art der Entwicklung ungeeignet scheint, wuerde ich mich freuen.


----------



## byte (19. Aug 2008)

Komisch, bei mir ist

```
String foo = bar();
```
immernoch kürzer als

```
String foo;
foo = bar();
```
 :roll:


----------



## tfa (19. Aug 2008)

Ich kapier's auch nicht ;-)


----------



## Saxony (19. Aug 2008)

Hiho,

yup meine Methode von oben versteh ich, nach Schalentiers Formatierung, nun auch nicht mehr! 

bye Saxony


----------



## SlaterB (19. Aug 2008)

> Ueber ein Beispiel, wo diese Art der Entwicklung ungeeignet scheint, wuerde ich mich freuen.

siehe deinen Code vom 18. 08. 2008, 16:15,
die Methode mit der intialien Deklaration ist 50% länger,
ich würded das als 'ungeeignet' bezeichnen, darüber kann man aber aber streiten,

steht in jedem Fall in Widerspruch zu 
> - wenig LOC 
falls das Lines of Code sind
(dass Methoden auf Grund wenig Inhalts/ kleiner Aufgaben möglichst kurz sein sollen ist ein anderes Thema)

--------
mich stört, dass algorithmusOutput keine lokale Variable in der Schleife ist,
so muss man zweimal nachschauen, ob man nicht damit einen wichtigen Wert überschreibt, der vorher gesetzt wurde und hinterher weiterverwendet wird,

man könnte auch interpretieren, dass diese im glatten Widerspruch zu den Sun CodeConventions stehen:



> 6.3 Placement
> Put declarations only at the beginning of blocks. (A block is any code surrounded by curly braces "{" and "}".) Don't wait to declare variables until their first use; it can confuse the unwary programmer and hamper code portability within the scope.
> 
> void myMethod() {
> ...


wieso wird dort int2 nicht am Anfang der Methode deklariert?


wenn man dann noch zwei Schleifen hat mit zufällig zwei temp-Variablen des gleichen Typs, 
verwendet man dann zwei derartige Temp-Variablen oder nur eine doppelt?
darf man diese noch auf null prüfen?

Variablen länger als nötig zu halten kann auch gefährlich sein wegen Veraltung,
z.B. 
int size = list.length();
bzw. bei dir ja
int size =  0;
+
size = list.length();
(..)
+ später die Liste vergrößern/ verkleinern


nahezu alle diese Argumente lassen sich durch das Argument 'kurze Methoden' aus dem Weg räumen,
da kann man nix gegen sagen, 
außer natürlich, dass so ein Outsourcing in Untermethoden quasi einem Block mit eigenen lokalen Variablen entspricht,
insofern also auch nicht allzuweit davon entfernt


-----

apropos CodeConventions:



> 6.2 Initialization
> Try to initialize local variables where they're declared. The only reason not to initialize a variable where it's declared is if the initial value depends on some computation occurring first.


der letzte Satz läßt vermuten, dass damit nicht die Dummy-Initialisierung mit null gemeint ist, die ja immer geht,
sondern tatsächlich
String foo = bar();


----------



## schalentier (19. Aug 2008)

Saxony hat gesagt.:
			
		

> Hiho,
> 
> yup meine Methode von oben versteh ich, nach Schalentiers Formatierung, nun auch nicht mehr!
> 
> bye Saxony



Immerhin sind nun weniger Fehler drin. Ich lass das hier sein. Is mir echt zu doof. Sorry, wenn ich genervt haben sollte.


----------



## DLor (19. Aug 2008)

Selbst mit JAVA wird einem manchesmal vorgeschrieben, das die Variablen direkt zu Beginn einer Methode deklariert werden MÜSSEN.

Wenn man ein Programme auf BASIS von J2ME entwickelt ist dies ein Muss. Jedenfalls war es das vor 3 Jahren!


----------



## Saxony (19. Aug 2008)

Hiho,



			
				schalentier hat gesagt.:
			
		

> Immerhin sind nun weniger Fehler drin.



Um Fehlerbehandlung ging es aber nicht! Wenn ich das mal aus deinem Code rausnehme sieht es so aus:



			
				schalentier hat gesagt.:
			
		

> ```
> private String getFunctionCode(String aCode, int aPos) {
> 
> String functionName = null;
> ...



So - und ich würde meinen folgendes kann man aber wesentlich besser lesen:


```
private String getFunctionCode(String aCode, int aPos) { 

   run = false;       
   String erg = aCode.substring(aPos); 
   String name = erg.substring(0, erg.indexOf('(')); 
    
   if(functions.containsKey(name)) { 
    
      run = true;          
      return name; 
   } 
       
   String code = getInlineCode(erg.substring(name.length()), '(', ')'); 
             
   functions.put(name, code); 

   return name; 
}
```

Übrigens sind es einmal 18 und einmal 26 LOC. 

Nuja - kann ja jeder machen wie er will! 

bye Saxony


----------



## schalentier (19. Aug 2008)

SlaterB hat gesagt.:
			
		

> nahezu alle diese Argumente lassen sich durch das Argument 'kurze Methoden' aus dem Weg räumen,
> da kann man nix gegen sagen,
> außer natürlich, dass so ein Outsourcing in Untermethoden quasi einem Block mit eigenen lokalen Variablen entspricht,
> insofern also auch nicht allzuweit davon entfernt



Wenigstens einer hats begriffen.

@Saxony: Wenn du die Idee weiter fortfuehrst kommst du zu:


```
private String getFunctionCode(String aCode, int aPos) {

    String functionName;
    String functionCode;
    String function;

    run          = false;

    function     = aCode.substring(aPos);
    functionName = getFunctionName(function);

    if ( functions.containsKey(functionName) ) {

        run = true;
    } else {

        functionCode = getFunctionCode(function, functionName);
        functions.put(functionName, functionCode);
    }

    return functionName;
}
```

Wenn du jetzt die tatsaechlichen Zeilen zaehlst, in denen was passiert, ist es gleich lang. Das Splitten von Deklaration und Zuweisung hilft IMHO dem Lesenden, (possible) NPE auf den ersten Blick zu erkennen und ermoeglicht IMHO schickeres Formatieren durch Alignment. Zudem hat es mir geholfen, Methoden auszulagern, um diese an anderer Stelle wiederzuverwenden.

Aber wie du schon sagtest, jeder kann machen wie er will.


----------



## Yzebär (19. Aug 2008)

Zum Thema final, auf der Seite stehen eigentlich alle Vorteile gut zusammengefaßt

http://mindprod.com/jgloss/final.html

Zusätzliche Literaturempfehlung "Hardcore Java" von Robert Simmons, Kapitel 2 "The Final Story" (da gehts dann auch um final Collections, die ich jetzt in diesem Zusammenhang außen vor lassen möchte).

Das Argument 'kurze Methoden' zieht auch nicht immer. Da muß auch eine gewisse Verhältnismäßigkeit gegeben sein, schließlich kostet jede Methode Entwicklungszeit (Schreiben der Tests + Doku für jede Methode) und jeder Methodenaufruf kostet Performance. Von der Unübersichtlichkeit der Sequenz der Methodenaufrufe ganz zu schweigen


----------



## maki (19. Aug 2008)

```
private String getFunctionCode(String aCode, int aPos) {

    this.run = false;
    String functionName = getFunctionName(aCode.substring(aPos));

    if (functions.containsKey(functionName) ) {
        run = true;
    } else {
        functions.put(functionName, getFunctionCode(function, functionName));
    }

    return functionName;
}
```

Warum eine Methode die "getFunctionCode" eine Variable zurückgibt der "functionName" heist, erschliesst sich mir nicht.
Die Tatsache dass es in der alten Version eine Variable gibt die "functionCode" heisst führt dann zu Verwirrungen.


----------



## schalentier (19. Aug 2008)

Es ist nicht mein Quellcode, im Originalcode wars genauso. Ich hab die Variable nur umbenannt von "name" in "functionName".

Ich kann auch alles auf eine Zeile schreiben. Dann hab ich 1 LOC. Geil oder?

Oben hab ich Quark geschrieben. Es werden nicht weniger LOC, es werden (logischerweise) mehr LOC. Dafuer werden die Zeilen kuerzer, das wollte ich urspruenglich sagen. 

Und Methodenaufrufe direkt in andere Methoden zu leiten find ich auch nicht besonderns praktisch. Das verleitet sehr schnell dazu, die Methoden mehrfach aufzurufen, anstatt das Ergebnis in lokalen Variablen abzuspeichern. 

Und was ihr alle gegen Alignment habt, erschliesst sich mir auch nicht. In der Mathematik macht man das doch auch, auch wenn das nicht direkt miteinander zu vergleichen ist. Mir jedenfalls gefaellts besser.


----------



## maki (19. Aug 2008)

Dein Alignement ist imho nicht gewöhnungsbedürftig, soll heissen: würde nicht daran gewohnen können 

Aber mal im Ernst, 

wenn eine Methode getFunctionCode heisst, dann brauche ich nur eine Variable um den Wert zwischenzuspeichern, wenn dieser öfters benutzt wird, d.h. so etwas

```
functionCode = getFunctionCode(function, functionName);
        functions.put(functionName, functionCode);
```
ist imo Sinnfrei, hat keinen Mehrwert an Infos.

Wenn die Methodename mehrdeutig ist kann man dennoch einen sprechenden Variablen wählen, aber das ist ja hier gar nicht der Fall.

Da funcitonName öfter verwendet wird qualifiziert es sich schon für seine eigene Variable, trotzdem wäre functionCode der passendere Name.


----------



## SlaterB (19. Aug 2008)

@ schalentier:
CodeConventions über alles, schau dir 99% des Codes auf der Welt an,
wird sich zwar auf mehr als 99 Weisen unterscheiden, 
zumindest kann aber zu diesem Punkt hier sagen, dass es nicht in diese Welt gehört,

naja, Thema Unterordnung..


----------

