4 Stimmen

PHP: Wie kann man Code wiederverwenden (oop)?

Ich habe in php oop studiert und mich mit dem Konzept des wiederverwendbaren Codes auseinandergesetzt.

Ich habe ein Beispiel gesehen wie

interface iTemplate
{
    public function setVariable($name, $var);
    public function getHtml($template);
}
And implement it:

// Implement the interface
class Template implements iTemplate
{
    private $vars = array();

    public function setVariable($name, $var)
    {
        $this->vars[$name] = $var;
    }

    public function getHtml($template)
    {
        foreach($this->vars as $name => $value) {
            $template = str_replace('{' . $name . '}', $value, $template);
        }

        return $template;
    }
} 

Ich kann den Code verstehen, bin mir aber nicht sicher, warum er wiederverwendbar ist. Jedes Mal, wenn ich eine neue Funktion in der iTemplate-Schnittstelle hinzufügen möchte, muss auch meine Template-Klasse geändert werden. Ich verstehe das Konzept der "Wiederverwendung" nicht. Ich bin für jede Hilfe dankbar. Danke!

8voto

ircmaxell Punkte 159431

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...

0voto

Alex Pliutau Punkte 20530

Die Schnittstelle wird zu Beginn der Entwicklung nur 1 Mal geschrieben. Und erst danach schreiben andere Klassen, die diese Schnittstelle implementieren. Interface - ist ein Fundament. Hinweis: Die Methode setVariable ist nicht erforderlich. Es gibt gute magische Methoden in PHP wie __get() y __set() .

0voto

halfdan Punkte 32370

Schnittstellen sind in der Regel dann nützlich, wenn etwas austauschbar sein soll. Stellen Sie sich vor, Sie würden eine Plugin-Anwendung entwickeln. Sie haben dann die Schnittstelle iPlugin:

interface iPlugin {
   public function init();
   /* .. */
}

und alle Plugins würden diese Schnittstelle implementieren. Ein Plugin-Manager könnte dann einfach überprüfen, ob ein Plugin die Schnittstelle implementiert und die init()-Methode dafür aufrufen.

0voto

podperson Punkte 2186

Code muss nicht OO sein, um wiederverwendbar zu sein, obwohl dies in vielen Fällen hilfreich ist.

Der Code muss nicht unbedingt Schnittstellen verwenden, um wiederverwendbar zu sein, auch wenn dies in einigen Fällen hilfreich ist.

Der Schlüssel zum Schreiben von wiederverwendbarem Code liegt darin, Code zu schreiben, der klar geschrieben und gut kommentiert ist, konsistente Benennungs- und Aufrufkonventionen verwendet und allgemeiner ist, als es für das jeweilige Problem unbedingt erforderlich ist.

Eine der einfachsten und mächtigsten Techniken zum Schreiben von wiederverwendbarem Code in PHP ist das Schreiben von Methoden, die entweder eine variable Anzahl von Argumenten oder ein assoziatives Array von Parametern akzeptieren.

Oft stellt sich heraus, dass Code, der ursprünglich nicht wiederverwendbar sein sollte, doch wiederverwendet werden soll. Typischerweise beginnt der Code "inline" und dann stellt man fest, dass man genau oder fast genau das Gleiche an mehreren Stellen tun muss. Wenn Sie sich dabei ertappen, dass Sie Code kopieren und einfügen, ist es an der Zeit, ihn als Funktion zu refaktorisieren.

Ähnlich verhält es sich, wenn Sie sich wünschen, dass eine Funktion, die Sie in Datei X definiert haben, in Datei Y wirklich hilfreich wäre, dann ist es an der Zeit, sie in ein Modul zu verschieben.

All dies lernt man am besten durch Erfahrung. Einige Leute werden Ihnen raten, diese Dinge von Anfang an zu planen, und das ist sicherlich eine gute Idee, wenn Sie den Einblick und die Erfahrung haben, dies zu tun, aber es ist genauso gültig, dies von Grund auf zu tun, und es ist wahrscheinlich der beste Weg zu lernen.

0voto

Boss Ruhul Punkte 1

Wiederverwendbarkeit der objektorientierten Programmierung ist der Gebrauch der vorhergehenden Kategorie oder der Funktion oder der Methode in der anwesenden Kategorie aber kein Problem der vorhergehenden Kategorie.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X