Artikelformat

Interfaces – eine (kurze) Einführung

Nachdem ich wieder fit bin, gibt es nun einen kurzen Artikel zum Thema Interfaces. Dieser wird sicher nicht alle Aspekte betrachten und es wird ganz tolle Möglichkeiten geben, die ich nicht beschreibe, aber ihr sollt ein Lebenszeichen von mir bekommen.

Interfaces gibt es in PHP seit Version 5. Diese „Dinger“ sind vielen Programmierern etwas suspekt. Schließlich wird nicht darin programmiert und dennoch haben sie einen Nutzen. Zuerst gibt es aber wie sooft ein kleines Beispiel, das zeigt wie so ein Interface überhaupt aussieht.

1
2
3
4
5
6
<?php
 
interface NeedsUser {
     public function setUser(User $user);
}
?>

Dieses Interface kann man nun eine Klasse implementieren. Das heißt man gibt der Klasse per implements in der Klassensignatur an, dass dieses Interface beachtet werden soll. Dann muss in der Klasse selbst noch die Funktion setUser implementiert werden. Diese muss natürlich die gleiche Methodensignatur haben. Nun haben wir eine Klasse, von der wir wissen, dass dieser ein Benutzer übergeben werden kann. Das ist nur bedingt spannend, aber jetzt kann man damit relativ sauber arbeiten. Wichtig ist noch der Punkt, dass eine Klasse auch gernen mehrere Interfaces implementieren kann und Interfaces können auch voneinander abgeleitet werden.

Wir haben nun eine Klasse, bspw eine Factory o.ä., die einem Objekt über eine Methode ein User zuweist, dann würde man das zum Beispiel so machen:

1
2
3
4
5
6
 ...
private function putUserTo($object) {
     if (method_exists($object,"setUser")) {
            $object->setUser($this->dummy_user);
     }
...

Das ist soweit okay, aber mit unserem Interface kann man das hübscher lösen. Wir nutzen jetzt das Type Hinting. Damit kann man sicherstellen, dass ein Object, das man einer Methode übergibt vom richtigen Typ ist bzw. das richtige Interface implementiert. Das heißt, wenn putUserTo aufgerufen werden kann mit einem Objekt, dann muss dieses Objekt auf jeden Fall die Methode setUser implementieren und schon passt alles. Ansonsten fliegt eine Exception, die ich an einer bestimmten Stelle im Code abfangen muss.

1
2
3
4
5
...
private function putUserTo(NeedsUser $object) {
     $object->setUser($this->dummy_user);
}
...

Angenommen ich habe jetzt keine Lust mich um Eception Handling zu kümmern, dann gibt es noch eine Alternative, die man an dieser Stelle nutzen kann:

1
2
3
4
5
6
7
...
private function putUserTo($object) {
     if ($object instanceof NeedsUser) {
          $object->setUser($this->dummy_user);
     }
}
...

Wenn man 2 oder mehr Klassen hat, die eine Methode nutzen, die eigentlich gleich ist nur intern etwas anders funktioniert, so macht es Sinn diese Methode in ein Interface zu extrahieren. Früher oder später ist es sehr praktisch, wenn man auf die oben gezeigte Art und Weise eine Zusicherung über das Vorhandensein einer Methode erhält. Gelegentlich macht es auch Sinn sogenannte Marker-Interfaces zu nutzen. Dabei handelt es sich um Interfaces, die keine Methodensignatur haben. Dadurch weiß man aber trotzdem, dass eine Klasse für eine bestimmte Nutzung vorgesehen ist. Bspw. wäre IsCachable ein solcher Marker. Nun weiß jeder, der den Code liest, dass die betreffende Klasse im Cache abgelegt werden darf. Auf der anderen Seite kann der Cache (bzw dessen Klassenstruktur) überprüfen, ob die Klasse, die der Programmierer gerade versucht zu cachen, dafür überhaupt vorgesehen ist. So wandert bspw nicht aus versehen eine DB-Resource in den Cache, was zu seltsamen Effekten führen würde.

Bei der OOP sind Interfaces sehr beliebt und hier wird auch nicht gespart. Klassen die 10-15 Interfaces implementieren sind keine Seltenheit.

Wer nun direkt sein Projekt mit möglichst vielen Interfaces auszustatten will, darf gerne hier weiterlesen.

Einen kleinen Wermutstropfen gibt es dennoch. Im Zend Studio gibt es einen direkten Support für Interfaces, das bedeutet, die IDE erkennt, wenn ich eine notwendige Methode noch nicht implementiert habe. Bei Netbeans und Eclipse merke ich das erst bei der Ausführung.

4 Kommentare

  1. Interessantes Thema wenn auch, wie ich finde, etwas oberflächlich behandelt. Durch Interfaces legst du die Schnittstellen in deiner Software fest.

    Es gibt dazu einen schönen Merksatz: „Programm to an interface, not to implementation“, was so viel bedeutet, dass du dich als Entwickler nur noch darum kümmern musst, was du machen willst und dich die eigentliche Implementierung (also die konkrete Klasse) nicht mehr interessieren muss.

    Durch die Verwendung von Interfaces kann eine Klasse auch mehreren Typen einer nicht geraden Vererbung entsprechen.

    Nochwas zu deinem Code-Beispiel 2 in Zeile 3: Es gibt eine Funktion dafür Namens ‚method_exists()‘.

    Antworten
    • Ja, ich stimme dir zu, zu Interfaces kann man sehr viel mehr schreiben. „method_exists“ kannte ich nicht und wie ich eben sah, gibt es diese Funktion schon seit PHP4. Ich werde das Codebeispiel entsprechend abändern.

      Vielen Dank

Schreibe einen Kommentar

Pflichtfelder sind mit * markiert.