13.07.2010
16:46

Refactoring Snippets

Sebastian Petzelberger Senior Consultant bei aformatik

 

von Sebastian Petzelberger 

 

Ein Refactoring Snippet zeigt ein kleines Problem auf und gibt eine kleine Lösung dazu an. Die Problemstellungen kommen aus der Projektarbeit. Die Snippets sollen kleine Hilfen sein. Außerdem sollen sie generell zum Refactoring anregen, aber auch zu einer Diskussion darüber einladen.

 

 


Refactoring Snippet: Überflüssige Hierarchie

Vorstellung

In einem Projekt waren über einem Dutzend Klassen wie die folgenden zwei aufgebaut:

public class UpButton extends JButton
{
  public UpButton()
  {
    this.setBorderPainted(false);
    this.setMaximumSize(new java.awt.Dimension(20, 20));
    this.setMinimumSize(new java.awt.Dimension(20, 20));
    this.setPreferredSize(new java.awt.Dimension(20, 20));
    this.setIcon(new javax.swing.ImageIcon(getClass().
getResource("/xxx/xxx/images/Up16.gif")));
  }
}

public class TopButton extends JButton
{
  public TopButton()
  {
    this.setBorderPainted(false);
    this.setMaximumSize(new java.awt.Dimension(20, 20));
    this.setMinimumSize(new java.awt.Dimension(20, 20));
    this.setPreferredSize(new java.awt.Dimension(20, 20));
    this.setIcon(new javax.swing.ImageIcon(getClass().
getResource("/xxx/xxx/images/Top16.gif")));
 }
}

 

kleine Probleme

Auffällig ist:

  • Viele neue Klassen
  • Redundanz

Eine Unterklasse stellt neue Funktionalität bereit, die in neuen Methoden umgesetzt werden. Hier haben die Unterklassen keine neue Funktionalität.

Es kommt auch vor, dass vorhandene Funktionalität allgemein ausgeprägt in der Unterklasse speziell umgesetzt wird. Das wäre ein Überschreiben von vorhandenen Methoden der Oberklasse. Das hätte hier Anwendung finden können. Es wäre konsequent gewesen, die Methoden getMaximumSize, getPreferredSize und getIcon zu überschreiben. Der Code hätte so die Notwendigkeit von eigenen Klassen eher wieder gespiegelt, doch neue Funktionalität hätte trotzdem gefehlt. Gut, dass dies nicht so umgesetzt wurde, denn jetzt ist es leichter zu einer einfacheren Lösung zu kommen.  

kleine Lösung

Die oben angeführten zwei Beispiele verwenden jeweils eine Methode zum Konstruieren. Wieso nicht stattdessen eine Methode zum Erzeugen verwenden? Mein Vorschlag, eine Dienstmethode:

public static JButton createIconButton(String resource)
{
JButton iconButton = new JButton();
iconButton.setBorderPainted(false);
iconButton.setMaximumSize(new Dimension(20, 20));
iconButton.setMinimumSize(new Dimension(20, 20));
iconButton.setPreferredSize(new Dimension(20, 20));
iconButton.setIcon(new ImageIcon(getClass()
.getResource(resource)));
return iconButton;
}

Das ist nur eine erste Refactoring Maßnahme. Mein Vorschlag selbst ist natürlich noch nicht fertig. Es sind immer noch Redundanzen vorhanden, beispielsweise "new Dimension(20, 20)". Ein weiteres Refactoring ist nicht nötig, da hier nur auf überflüssige Hierarchien hingewiesen werden soll.  

Beurteilung

Wer neuartige Widgets programmiert, der benötigt (eventuell) Hierarchie. Wer aber nur zusammenbaut, der tut das besser in einer Dienst-Methode. Es ist immer die einfachere Lösung zu wählen. Eine neue Klasse ist viel mächtiger als nur eine neue Methode. Bei dem obigen Beispiel haben wir noch den Vorteil, dass der vorliegende Code nur eine Methode beinhaltet. Das Prinzip ist: Nicht vererben, sondern zusammenbauen. Es soll nicht ganz auf Hierarchien verzichtet werden, der Einsatz sollte in der Praxis nur etwas kritischer geschehen.

Es gab mal einen bekannten Swing GUI-Builder, der beliebt war aufgrund der einfachen weil visuellen Handhabung GUIs zusammenzubauen. Mein größter Kritikpunkt an diesem war, dass so viele Programmierer dann auch so entwickelt haben, wie der GUI-Builder den Swing-Code erzeugt hat. Eine noch harmlose Unsitte war, dass jede GUI-Klasse eine Unterklasse von JPanel war. Eine GUI-Klasse baut ein JPanel zusammen, ist keine neue Art von JPanel. Die riesige Methodenpalette von der Vererbungshierarchie von JPanel interessiert nur beim Zusammenbauen des JPanels, also in einer Methode. Die eigenen geschrieben Methoden der GUI-Klasse sind im Code-Assistent kaum zu finden. Das weist auch darauf hin, dass Hierarchie hier kein geeignetes Mittel ist.

In dem einen oder anderen Beispielcode von SUN sind die GUI-Klassen eine neue Art von JFrame. Eine Gui-Klasse baut ein JPanel zusammen. Dieser kann dann per Dienstmethode in einen JFrame gesetzt werden ODER in einem JDialog ODER in einem anderen JPanel Verwendung finden. Letzteres wenn nämlich eine übergeordnete GUI-Klasse diesen benutzt.

 

 kleine Probleme

  •  
  • 0 Kommentare
  •  

Mein Kommentar

Zurück