什么时候对象接口在PHP中有用?

时间:2011-01-18 09:52:45

标签: class language-agnostic interface

来自php.net

  

对象接口允许您创建指定哪些方法的代码   一个类必须实现,而不必定义如何处理这些方法。

为什么我需要这样做?它可能是一种“文档”吗?

当我在考虑我必须实现的类时,我确切地知道应该编写哪些方法。

在哪些情况下,连接课程是“最佳实践”?

4 个答案:

答案 0 :(得分:2)

简短回答:统一接口和多态。

更长的答案:你显然可以创建一个可以完成所有事情的类,而且你确实知道要编写什么方法。然而,使用具体类所遇到的问题是你缺乏改变的能力。假设您有一个将用户存储到MySQL数据库中的类,我们称之为UserRepository。想象一下以下代码:

<?php
class UserRepositoryMysql {
    public function save( User $user ) {
        // save the user.
    }
}

class Client {
    public function __construct( UserRepositoryMysql $repos ) {
        $this->repos = $repos;
    }

    public function save( User $user ) {
       $this->repos->save( $user );
    }
}

现在,这一切都很好,因为它实际上会起作用,并将用户保存到数据库中。但想象一下你的应用程序将成为普及者,很快,还有一个问题需要支持PostgreSQL。您将不得不编写UserRepositoryPostgresql类,并将其传递给UserRepositoryMysql而不是UserRepositoryMysql。现在,您已经在UserRepositoryMysql上打字,而且您不确定两个存储库是否使用相同的方法。另外,关于如何实现自己的存储的潜在新开发人员几乎没有文档。

当您将Client类重写为依赖于接口而不是具体类时,您可以选择“交换它们”。这就是为什么界面在正确应用时很有用的原因。

答案 1 :(得分:1)

首先,我的php对象编码远远落后于我的.net编码,但原理是相同的。在类中使用接口的优点很多。例如,您需要从搜索例程返回数据的情况。此搜索例程可能必须跨越具有完全不同数据结构的许多不同类。在“正常”编码中,这将是一场噩梦,试图嫁给各种不同的回报值。

通过实现接口,您可以为使用它们的clsses添加一个责任,以生成一组统一的数据,无论它们有多么不同。另一个例子是你从不同的'提供者'中提取数据的情况(例如xml,json,csv等)。通过在每个类类型上实现一个接口,您可以通过添加实现接口的新类来轻松扩展数据馈送,而不是混合使用switch语句来试图找出您的意图。

总之,将界面视为“必须”尊重的“契约”。显示这意味着您只需要实现细节变化就可以对该给定场景充满信心地进行编码。

希望这有帮助。

[edit] - 请参阅SO上的此示例,以获得相当简单的解释:

接口是面向对象编程中的一个概念,它支持多态性。基本上,接口就像一个契约,实现它的类同意提供某些功能,以便它们可以像使用接口的其他类一样使用

purpose of interface in classes

答案 2 :(得分:1)

我想到的第一个案例就是当你有一个使用另一个类的某些方法的类时。你不关心这个第二类如何工作,但期望它有特定的方法。

示例:

interface IB {
    public function foo();
}

class B implements IB {
    public function foo() {
        echo "foo";
    }
} 

class A {
    private $b;
    public function __construct( IB $b ) {
        $this->b = $b;
    }

    public function bar() {
        $this->b->foo();
    }
}

$a = new A( new B() );
$a->bar(); // echos foo

现在您可以轻松使用传递给A类实例的不同对象:

class C implements IB {
    public function foo() {
        echo "baz";
    }
}

$a = new A( new C() );
$a->bar(); // echos baz

请注意调用相同的bar方法。

使用继承可以获得类似的结果,但由于PHP不支持多重继承,因此接口更好 - 类可以实现多个接口。

您可以查看PHP design patterns - Strategy之一。

答案 3 :(得分:0)

假设您正在创建数据库抽象层。您提供了一个DAL对象,该对象提供与数据库和适配器类接口的通用方法,这些方法将这些方法转换为特定数据库的特定命令。这些适配器本身需要具有通用接口,因此DAL对象可以以标准化方式与它们通信。

您可以使用接口指定适配器所需的接口。当然,您可以简单地编写一些文档来指定适配器需要具有的方法,但是在代码中编写它可以使PHP为您强制实施此接口。它使PHP能够在执行一行代码之前抛出有用的错误消息。否则只能在运行时找到丢失的方法,只有当你真正尝试调用它们时,这会使调试变得更加困难并且代码更加不可靠。

相关问题