Schnittstellen sind nicht direkt für die Wiederverwendung von Code gedacht. Sie dienen der Abstraktion. Sie ermöglichen es Klassen, die die Vorlage verwenden, nach der Schnittstelle zu suchen, anstatt nach der Basisklasse der Vorlage. Auf diese Weise wird die Implementierung von der Schnittstellendeklaration getrennt.
Wenn Ihre Methode also etwas mit einer template
Klasse, Überprüfung auf ein Objekt der Instanz template
würde eine Abhängigkeit von dieser Klasse fest codieren. Aber in Wirklichkeit ist es egal, welche Klasse man bekommt, es ist nur wichtig, dass sie sich an die iTemplate
Schnittstelle (da dies ohnehin alles ist, was Sie aufrufen).
public function foo(Template $template) {
vs:
public function foo(iTemplate $template) {
Was nun die Wiederverwendung von Code angeht, so sind Schnittstellen nicht wirklich dafür ausgelegt. Vererbung ist das normalerweise. Grundsätzlich kann man sich Vererbung als Erweiterung einer Abstraktion vorstellen. Lassen Sie mich Ihnen ein Beispiel geben:
Wenn Sie eine Reihe von Klassen für Vögel erstellen möchten, können Sie dies mit oder ohne Vererbung tun. Schauen wir uns an, wie wir es ohne machen könnten:
interface iBird {
public function fly();
public function speak();
public function swim();
public function walk();
}
class Duck implements iBird {
public function fly() {
//Fly here
}
public function speak() {
// Quack here
}
public function swim() {
//Swim here
}
public function walk() {
//Walk here
}
}
class Turkey implements iBird {
public function fly() {
//Fly here, but limited
}
public function speak() {
//Make turkey sound here
}
public function swim() {
throw new Exception('Turkeys can not swim!');
}
public function walk() {
//Walk here
}
}
Dies ist ein einfaches Beispiel, aber Sie können sehen, dass bei diesen beiden Vögeln die walk()
Funktionen werden wahrscheinlich identisch sein (und damit gegen DRY verstoßen)...
Schauen wir uns an, wie das bei einer einstufigen Vererbung aussehen könnte:
abstract class Bird implements iBird {
public function fly() {
//Fly here
}
abstract public function speak();
public function swim() {
//Swim here
}
public function walk() {
//Walk here
}
}
class Duck extends Bird {
public function speak() {
//Quack here
}
}
class Turkey extends Bird {
public function speak() {
//Make turkey sound here
}
public function swim() {
throw new Exception('Turkeys can not swim!');
}
}
Wie Sie sehen, haben wir gerade 3 der Methoden wiederverwendet! Wir haben nicht deklariert speak()
Da keine zwei Vögel gleich klingen, wird er immer übersteuert werden.
Klingt gut, oder? Nun, je nach unseren Bedürfnissen möchten wir vielleicht andere abstrakte Typen hinzufügen. Nehmen wir also an, wir würden viele verschiedene Arten von Vögeln erstellen... Wir würden einige haben, die nicht schwimmen können, also könnten wir eine abstrakte Klasse erstellen NonSwimmingBird
die die Bird
, sondern löst die Ausnahme für uns aus. Oder eine NonFlyingBird
oder eine ShortRangeBird
...
Was die Wiederverwendung von Code angeht, sind wir auf einem guten Weg, aber in einem anderen Bereich stoßen wir auf eine Mauer. Nehmen wir an, wir haben einen Vogel, der weder fliegen noch schwimmen kann. Von welcher Klasse erben wir dann? So oder so, wir duplizieren Code. Wir müssen also einen anderen Ausweg finden. Nun, wie machen wir das? Durch Entwurfsmuster ... Anstelle der direkten Vererbung könnten wir ein Dekorator-Muster verwenden, um diese Eigenschaften im laufenden Betrieb hinzuzufügen. (Es gibt andere Muster, die hier verwendet werden können, der Punkt ist zu zeigen, dass Vererbung allein nicht alle Bedürfnisse erfüllt. Und Patterns allein auch nicht. Sie brauchen eine gute Architektur, die beide Welten nutzt, je nachdem, was Ihre genauen Bedürfnisse sind)...
Es kommt also ganz auf Ihre Bedürfnisse an. Wenn Sie nur 2 "Klassen" von Objekten haben, werden Sie etwas viel einfacheres architektieren, als wenn Sie planen, Tausende zu haben. Mit dem, was ich hier geschrieben habe, möchte ich demonstrieren, wie man durch direkte Vererbung einige DRY-Prinzipien durchsetzen kann (aber auch, wie direkte Vererbung zu Code-Duplizierung führen kann). Das Wichtigste ist, dass Sie nicht versuchen, sich an DRY zu halten, nur weil Sie sich nicht wiederholen wollen. Halten Sie sich an DRY, aber stellen Sie sicher, dass Sie kombinieren und erweitern, wo es sinnvoll ist, sonst schaffen Sie sich selbst ein Problem mit der Wartung. Halten Sie sich an die Einzige Verantwortung Prinzip und es sollte Ihnen gut gehen...