it-swarm-eu.dev

Warum hat PHP) Schnittstellen?

Ich habe festgestellt, dass ab PHP5 Schnittstellen zur Sprache hinzugefügt wurden. Da jedoch PHP so lose eingegeben ist), scheinen die meisten Vorteile der Verwendung von Schnittstellen verloren zu gehen. Warum ist dies in der Sprache enthalten?

34
GSto

Der Hauptvorteil von Schnittstellen in PHP) besteht darin, dass Klassen mehrere Schnittstellen implementieren können. Auf diese Weise können Sie Klassen gruppieren, die einige Funktionen gemeinsam nutzen, jedoch nicht unbedingt eine übergeordnete Klasse gemeinsam nutzen. Einige Beispiele umfassen möglicherweise Caching und Ausgabe oder auf bestimmte Weise auf Eigenschaften der Klasse zugreifen.

In Ihrem Code können Sie überprüfen, ob eine Klasse eine bestimmte Schnittstelle implementiert, anstatt den Klassennamen zu überprüfen. Dann funktioniert Ihr Code weiterhin, wenn neue Klassen hinzugefügt werden.

PHP bietet einige vordefinierte Schnittstellen, die in verschiedenen Situationen nützlich sein können: http://php.net/manual/en/reserved.interfaces.php .

BEARBEITEN - Ein Beispiel hinzufügen

Wenn Sie eine Schnittstelle mit dem Namen MyInterface haben und mit mehreren Objekten verschiedener Klassen arbeiten, die möglicherweise einige Funktionen gemeinsam nutzen oder nicht, können Sie mit den Schnittstellen Folgendes tun:

// Assume $objects is an array of instances of various classes
foreach($objects as $obj) {
 if($obj instanceof MyInterface) {
     $obj->a();
     $obj->b();
     $obj->c();
   }
}
31
pjskeptic

PHP ist lose typisiert, aber es kann stark über Dinge wie Methodenparameter typisiert werden.

Betrachten Sie das folgende Beispiel:

interface Car { function go(); }

class Porsche { function go() {} }

function drive(Car $car) {}

$porsche = new Porsche();

drive($porsche);

Der obige Code würde Folgendes ausgeben:

Argument 1, das an drive () übergeben wurde, muss die Schnittstelle Car implementieren, Instanz von Porsche angegeben

23
Emanuil Rusev

Mit Schnittstellen können Sie das Open-Closed-Prinzip implementieren, eine lose gekoppelte Codebasis beibehalten und viele der besten OOP-Entwurfsmuster) implementieren.

Wenn beispielsweise eine Klasse eine andere Klasse als Argument akzeptiert:

class A {

    public function __construct(B $class_b) {
        // use class b
        $class_b->run();
    }
}

Ihre Klasse A und Klasse B haben jetzt eine enge Kopplung, und Klasse A kann keine andere Klasse außer B und ihren Unterklassen verwenden. Die Typangabe stellt sicher, dass Sie die richtige Art von Argument haben, hat aber jetzt die Beziehung zwischen A und B gefestigt.

Nehmen wir an, Sie möchten, dass Klasse A alle Arten von Klassen verwenden kann, die jedoch eine run () -Methode haben. Dies ist im Grunde (aber nicht ganz) das COMMAND-Entwurfsmuster. Zum Lösen würden Sie stattdessen einen Hinweis über eine Schnittstelle anstelle einer konkreten Klasse eingeben. B würde dann diese Schnittstelle implementieren und wird als Argument für Klasse A akzeptiert. Auf diese Weise kann Klasse A jede Klasse akzeptieren, die diese Schnittstelle als Argument für ihren Konstruktor verwendet.

Diese Art der Codierung wird in den meisten OOP Entwurfsmustern) verwendet und ermöglicht VIEL einfachere Änderungen des Codes zu einem späteren Zeitpunkt. Diese sind Teil der Grundlagen der AGILE-Programmierung.

class A {

    public function __construct(C $interface_c) {
        // use any class that implements interface C
        $interface_c->run();
    }
}

interface C {

    public function run();
}

class B implements C {

    public function run() {
        // do something
    }
}
8
dqhendricks

@pjskeptic hat eine gute Antwort und @Kamil Tomšík hat einen guten Kommentar zu dieser Antwort.

Das Tolle an dynamisch typisierten Sprachen wie PHP) ist, dass Sie versuchen können, Methoden für Objekte zu verwenden, und es wird Sie nicht anschreien, es sei denn, die Methode ist nicht vorhanden.

Das Problem mit dynamisch typisierten Sprachen wie PHP) ist, dass Sie versuchen können, Methoden für Objekte zu verwenden, und es wird Sie anschreien, wenn die Methode nicht vorhanden ist.

Schnittstellen bieten eine bequeme Möglichkeit, Methoden für ein unbekanntes Objekt aufzurufen und sicherzustellen, dass die Methoden vorhanden sind (nicht, dass sie unbedingt korrekt sind oder funktionieren). Es ist kein notwendiger Bestandteil einer Sprache, aber es macht das Codieren bequemer. Es ermöglicht stark typisierten OOP Entwicklern, stark typisierten PHP Code) zu schreiben, der dann neben lose typisiertem PHP geschriebenem Code) arbeiten kann von einem anderen PHP Entwickler.

eine Funktion wie:

foo( IBar $bar )
{
  $baz = $bar->baz();
  ...
}

ist bequemer als:

foo( $bar )
{
  if ( method_exists( $bar, 'baz' ) )
  {
    $baz = $bar->baz();
  }
  else
  {
    throw new Exception('OMGWTF NO BAZ IN BAR!');
  }
  ...
}

und meiner Meinung nach ist einfacher, lesbarer Code besserer Code.

7
zzzzBov

Sie sind völlig nutzlos, wenn Sie Ententyp sind. Wenn Sie Enten tippen, ist es ziemlich ärgerlich, mit Bibliotheken/Frameworks zu arbeiten, die Typ-Hinweise verwenden.

Dies gilt auch für alle Arten der dynamischen Metaprogrammierung (magische Methoden).

5
Kamil Tomšík

PHP ist nicht lose oder stark, sondern dynamisch typisiert .

Über Schnittstellen sollten Sie sich zunächst fragen: Was sind die meisten Vorteile von Schnittstellen?

In OOP geht es bei Schnittstellen nicht nur um Typen, sondern auch um Verhalten.

Da PHP hat auch eine Typ-Hinweis-Funktion , können Sie Schnittstellen wie in einer reinen oo-Sprache wie Java verwenden.

interface File
{
    public function getLines();
}

CSVFile implements File
{
    public function getLines()
    {}
}

XMLFile implements File 
{
    public function getLines()
    {}
}

JSONFile implements File 
{
    public function getLines()
    {}
}

class FileReader
{
    public function read(File $file)
    {
        foreach($file->getLines() as $line)
        {
            // do something
        }
    }
}

Mit PHP Interface-Implementierung können Sie auch Mocks für abstrakte Klassen mit PHPUnit erstellen - und das ist eine verdammt gute Funktion:

public function testSomething()
{
    $mock = $this->getMockForAbstractClass('File');

    $mock->expects($this->once())
         ->method('getLines')
         ->will($this->returnValue(array()));

    // do your assertions
}

Grundsätzlich können Sie also eine SOLIDE kompatible Anwendung in PHP) verwenden, indem Sie die Sprachfunktionen verwenden, von denen eine Schnittstellen sind .

3
Daniel Ribeiro

Schnittstellen sind für die Abhängigkeitsinjektion viel nützlicher als Beton. Als Barebone-Beispiel:

interface Istore { 
  public function save(); 
}

class Article_DB implements Istore 
{ 
  public function save($data) 
  {
    // do save to format needed.
  } 
}

class Article
{
   private $content;

   public function content($content)
   {
     $this->content = $content;
   }

   public function save(Istore $store)
   {
     $store->save($this->content);
   }
}

$article = new Article();
$article->content('Some content');

$store = new Article_DB();
$article->save($store);

Sagen Sie nun, ob sich Ihre Anforderungen ändern und Sie in einem PDF speichern möchten. Sie können zu diesem Zweck eine neue Klasse erstellen, anstatt die Artikelklasse zu verschmutzen.

class Article_PDF implements Istore 
{ 
  public function save($data) 
  {
    // do save to format needed.
  } 
}


$article = new Article();
$article->content('Some content');

$store = new Article_PDF();
$article->save($store);

Die Artikelklasse hat jetzt einen Vertrag, den Klassen, die sie zum Speichern verwendet, die Istore-Schnittstelle implementieren müssen. Es ist egal, wo es speichert oder wie es speichert.

0
Pete