php - 如何使继承成为可选的

标签 php oop inheritance

我目前正在帮助构建一个 API,我希望第 3 方开发人员使用该 API。该 API Hook 到云中的服务。这项服务不断变化,目前还不太可靠。因此,我想在我的 SDK 中提供真实客户端和虚假客户端。每当服务出现故障时,开发人员只需使用假客户端而不是真实客户端即可继续编码。

我研究过各种设计模式,其中一些很好地解决了我的问题。但这里有一个问题......我想让代码尽可能简单:所以假设我的服务称为 Experia。我希望人们能够做这样的事情:

class Experia extends Exp

...

$ex = new Experia(/*initialization parameters*/);  //init prameters like user name, password etc
$ex->story()->create($storyArgs);

目前,Experia 是一个扩展另一个类 Exp 的类,Exp 包含这些资源的列表以及它们在其中可用的文件..并且它还扩展了一个名为 Client 的通用类,该类定义了基本的 get() 和 post()方法等,并基本上设置客户端远程 url 等(它环绕 pest library )

所以 Exp 是这样的:

class Exp extends Client
{     
    public function story() {
         include_once('classes/User.php');
    }

    //other resource methods

}

我想创建另一个包含我所有虚假资源的类..如下所示:

class ExpFake extends Client
{     
    public function story() {
         include_once('classesFake/User.php');
    }

    //other resource methods

}

这是我面临的问题。我希望 Experia 能够根据其声明来扩展 Exp 或 ExpFake,而不会有任何丑陋。我所说的丑陋是指使用我的 API 的开发人员必须使用的任何额外代码。例如,我尝试做的一件事是将客户端与 Exp 分离,基本上就是这样做的

$ex = new Experia(/*... */);
$ex->client = new fakeClient();   //I could also do $ex-> client = new realClient();

但问题是每次我想使用调用资源时..我必须指定客户端:

$this->client->story()->create($args)

客户端部分是额外的代码,我无法包含在我的 API 中。

长话短说..什么是设计模式(或者直接的方式,如果可能的话..在php中)可以实现与选择性地从一个类或另一个类继承相同的结果

就像可以选择这样做:

类 Experia 扩展(Exp 或 ExpFake 取决于 Experia 的初始化参数)

最佳答案

适配器模式是一个好方法。您的主要客户端是 Exp 类,开发人员使用该类与您的服务进行交互。不过,此类依赖于适配器来连接到您的服务。该适配器类需要在实例化Exp时注入(inject),并且是必要时可以mock的部分。

class Exp {

    protected $adapter;

    public function __construct(ExpAdapter $adapter) {
        $this->adapter = $adapter;
    }

    public function foo() {
        return $this->adapter->doFoo();
    }

}

abstract class ExpAdapter {

    abstract public function doFoo();

}

然后您可以创建一个真正的 ExpAdapter 和一个模拟的:

class LiveExpAdapter extends ExpAdapter {

    public function doFoo() {
        // contact the actual service
    }

}

class MockExpAdapter extends ExpAdapter {

    public function doFoo() {
        return true;
    }

}

您还可以使用接口(interface)规范,而不是扩展抽象类。

对于开发人员来说,这看起来像:

$exp = new Exp(new LiveExpAdapter);
// if service is down, use instead:
// $exp = new Exp(new MockExpAdapter);

$exp->foo();

关于php - 如何使继承成为可选的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10879300/

相关文章:

php - 将对象数组展平为指定值的数组

python - 如何从 Python 中的方法访问函数

c# - 将隐含为派生程度较低的类型的对象放入派生程度较高的类型的列表中

javascript - 如何动态获取WordPress媒体库

php - 使用 PHP 为不同用户显示不同的 MySQL 字段

PHP memory_get_peak_usage 和 ini_set ('memory_limit' , '-1' )

java - 没有泛型的代码重用

c++ - 通过引用传递父对象

python - 应该如何创建一个继承自 NumPy ndarray 并具有默认值的类?

c# - C# 中泛型的接口(interface)和继承