Refactoring: Eine Methode mit einem Methodenobjekt ersetzen

Howto Refactoring: Eine Methoden mit mehreren Methodenvariablen in kleinere Einheiten zerlegen.

Heute möchte ich meine neue Artikelserie einläuten: Refactoring. Dabei werde ich in unregelmäßigen Abständen Tipps und Tricks dazu veröffentlichen. Der erste geht im speziellen an meinen Freund Eggi, der viel mit von Kollegen geerbten Legacy Code zu kämpfen hat:

Wer kennt sie nicht, viel zu lange Methoden. Mit Variablen die am anfang deklariert, in der Mitte 5x verändert und am Ende zurückgegeben werden sollen. Und dann auch noch 2 oder mehr von den Dingern!

Ok es müssen nicht 5 davon sein, und die Methode noch nichtmal lange. Ein schnelles, bewusst sehr simples Beispiel: Einfach mal versuchen die beiden Zuweisungen mittels Eclipse -> Extract Method als neue private Method rausziehen.

package test;

public class ToMuchVarMethod {
	
	public void shortExample(){
		
		int i = 1;
		int j = 1;
		
		i = 2;
	    j = 2;
	    
	    System.out.println(i +" "+ j);
	}

}

Die neue Methode wird einem mit der Meldung „Ambiguous return value: Selected block modifies more than one local variable used in subsequent code.“ versagt.

Was also tun? Nun es mag in dem hier gewählten Beispiel nicht besonders schlau wirken, aber eine saubere Lösung wäre es, die Methode in ein eigenes Objekt umzuwandeln. Man muss dazu den Scope der lokalen Methodenvariablen ändern und sie zu Instanzvariablen dieses Objektes werden lassen. Als nächsten Schritt gilt es, die lange Methode in einzelne Methoden innerhalb des neuen Objekts aufzusplitten. Die neue Klasse bietet dann eine Startmethode an wie z.B. compute() oder run() und bildet darin durch die einzelnen Methodenaufrufe die alte Methode nach.

So entsehen gut testbare Units und klare logische Abgrenzungen was in den einzelnen Methoden passiert.

Auch wenn es in dem hier angeführten Beispiel zu mehr Zeilen Code führt und somit etwas aufgebläht wirkt, bedient man dabei doch folgende zwei Prinzipien, die zu einem besser lesbaren, verständlicheren und damit besser wartbaren Code führen:

Hier noch das Beispiel von oben aufgesplittet in

das Aufrufende Objekt:

package test;

public class ToMuchVarMethod {
	
	public void shortExample(){
		
		ShortExample e = new ShortExample(1, 1);
		e.compute();
	}

}

und Methodenobjekt:

package test;

public class ShortExample {
	
	private int i;
	private int j;
	
	ShortExample(int i, int j){
		this.i = i;
		this.j = j;
	}
	
	private void setToTwo(){
		this.i = 2;
		this.j = 2;
	}
	
	private void print(){
		System.out.println(this.i + " "+ this.j);
	}
	
	public void compute(){
		setToTwo();
		print();
	}

}

Ähnliche Artikel: