Kolumne: Quality Time

Von den Verantwortlichkeiten: Das Single Responsibilty Principle
Kommentare

Wer sich bei Designentscheidungen einige Prinzipien verinnerlicht, kann beim Aufbau von Klassen, Modulen und Komponenten wart-, erweiter- und anpassbare Software erzeugen. Den Anfang macht das Single Responsibilty Principle.

PHP Magazin

Die Kolumne „Von den Verantwortlichkeiten“ von Tobias Schlitt ist erstmalig erschienen im PHP Magazin 4.2012.

Gutes, objektorientiertes Softwaredesign führt zu wartbarer, erweiterbarer und anpassbarer Software. Doch wer beim Thema Softwaredesign sofort bei hinlänglich bekannten Patterns hängt, hat zu kurz gedacht: Den meisten anständigen Designentscheidungen liegen viel subtilere Prinzipien zu Grunde, die sich, einmal verinnerlicht, intuitiv beim Aufbau von Klassen, Modulen und Komponenten anwenden lassen. In diese Kategorie fallen insbesondere die SOLID-Prinzipien, die von Robert C. Martin [1], alias Uncle Bob, bekannt gemacht wurden. Grund genug für uns, in den nächsten Ausgaben jeweils eines der Prinzipien unter die Lupe zu nehmen, beginnend bei S, wie Single Responsibility Principle.

Das folgende Beispiel zeigt eine einfache Klasse, die in einem Projekt dafür verwendet wird, Wetterdaten für einen bestimmten Ort von einem Web Service abzurufen. Hierzu stellt sie die Methode getWeatherForLocation() bereit (Listing 1).

Listing 1
class WeatherLoader 
{ 
    public function getWeatherForLocation( Location $location ) 
    { 
        $xml = $this->fetchData( $location->city ); 
        return $this->parseData( $xml ); 
    } 
    protected function fetchData( $city ) 
    { 
        $url = sprintf( 'http://...?city=%s', $city ); 
        return $this->fetchFromUrl( $url ); 
    } 
    /* ... */ 
} 

Wie leicht zu erkennen ist, verrichtet diese Methode indirekt einiges an Arbeit: Zunächst werden Wetterdaten mittels eines HTTP-Requests geholt. Im Anschluss werden sie geparst und in ein Datenobjekt gekapselt. Die Details dieser Prozesse wurden hier aus Platzgründen ausgelassen. Und damit zeigt sich auch schon das Problem: Die Klasse verrichtet zu viel Arbeit.

Das Single Responsibility Principle

Das Single Responsibility Principle, also das Prinzip der einzelnen Verantwortlichkeit, widmet sich genau diesem Problem: Jede Klasse sollte genau eine einzelne Verantwortlichkeit haben. Oder, wie in der Formulierung des Prinzips selbst ausgedrückt: Für jede Klasse sollte es nur einen Grund geben, sie zu ändern. Im gezeigten Beispiel fallen einem aber umgehend mehrere Gründe ein, warum hier Code angepasst werden müsste, von der Behebung von Bugs einmal abgesehen: Der angefragte Provider ändert seine URL-Struktur, seine Datenstruktur oder gar seine Lizenzbedingungen, sodass in Zukunft ein ganz anderer Anbieter verwendet werden muss. Es gilt also, die verschiedenen Verantwortlichkeiten zu trennen, was in Listing 2 durchgeführt wurde.

Listing 2
class WeatherLoader 
{ 
    public function __construct( WeatherService $service, WeatherParser $parser ) 
    { 
        // ... 
    } 
    public function getWeatherForLocation( Location $location ) 
    { 
        $data = $this->service->getWeather( $location ); 
        return $this->parser->parseData( $data ); 
    } 
} 

Der WeatherLoader hat nun zwei Abhängigkeiten: Ein Objekt vom Typ WeatherService, das rohe Wetterdaten beschafft, und eines vom Type WeatherParser, das diese Daten verarbeitet. Damit hat die betrachtete Klasse selbst nur noch eine einzelne Verantwortlichkeit: Diese beiden Prozesse zu verknüpfen.

Es ist leicht erkennbar, dass durch das Refactoring die oben genannten Änderungsmotivationen verschwinden. Die Anpassungen können allesamt durch neue Implementierungen eines oder beider abhängiger Typen realisiert werden.

Sozusagen als „zusätzliches Goodie“ wird auch das automatisierte Testen der Klasse wesentlich erleichtert: Die abzudeckende Menge an Code ist nun überschaubar und es bestehen keine harten Abhängigkeiten mehr, wie beispielsweise vorher auf eine Internetverbindung um eine echte Anfrage an den Datenprovider zu stellen. Diese Wechselwirkung tritt hier nicht nur zufällig auf, sondern ist gang und gäbe bei der Anwendung der SOLID-Prinzipien.

Natürlich ist das Erkennen von Verantwortlichkeiten, insbesondere am Anfang, nicht ganz einfach. Hier helfen vor allem praktische Übung, Coaching und die offene Diskussion mit Kollegen.

Tobias Schlitt ist Diplominformatiker (Uni) und arbeitet seit 1999 in professionellen Webprojekten auf Basis von PHP. Als Open-Source-Enthusiast beteiligt er sich an verschiedenen Communityprojekten. Tobias ist Mitgründer der Qafoo GmbH (http://qafoo.com), die Entwicklungsteams dabei unterstützt, hochqualitative Websoftware zu entwickeln. Dazu zählen unter anderem Consulting und Training zu Qualitätssicherungsprozessen und professionellem Software-Engineering.
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -