Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何使继承成为可选的_Php_Oop_Inheritance - Fatal编程技术网

Php 如何使继承成为可选的

Php 如何使继承成为可选的,php,oop,inheritance,Php,Oop,Inheritance,我目前正在帮助构建一个希望第三方开发者使用的API。此API与云中的服务挂钩。这项服务不断变化,目前不是很可靠。因此,我想在我的SDK中提供真实的客户端和假的客户端。每当服务关闭时,开发人员就可以简单地使用假客户端而不是真客户端继续编码 我研究了各种设计模式,其中一些很好地解决了我的问题。不过,这里有个陷阱。。我想让代码尽可能简单:所以让我们假设我的服务叫做Experia。我希望人们能够这样做: class Experia extends Exp ... $ex = new Experia(

我目前正在帮助构建一个希望第三方开发者使用的API。此API与云中的服务挂钩。这项服务不断变化,目前不是很可靠。因此,我想在我的SDK中提供真实的客户端和假的客户端。每当服务关闭时,开发人员就可以简单地使用假客户端而不是真客户端继续编码

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

class Experia extends Exp

...

$ex = new Experia(/*initialization parameters*/);  //init prameters like user name, password etc
$ex->story()->create($storyArgs);
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的类,该类包含这些资源及其可用文件的列表。。它还扩展了一个名为Client的泛型类,该类定义了基本的get()和post()方法等,并基本上设置了客户端远程url等(它围绕

Exp是这样的:

class Experia extends Exp

...

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

}
我想创建另一个包含我所有伪资源的类。。大概是这样的:

class Experia extends Exp

...

$ex = new Experia(/*initialization parameters*/);  //init prameters like user name, password etc
$ex->story()->create($storyArgs);
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
时,需要注入此适配器类,如果需要,它是可以模拟的部分

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;
    }

}
除了扩展
抽象类
之外,还可以使用
接口
规范

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

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

$exp->foo();

取决于您的php版本,但在这种情况下,我会使用traits

trait Exp {

}
trait ExpFake {

}    
class Experia {
    use Exp;
}

驱动程序的替代方案也可以,例如定义接口和单独的驱动程序或实现(与db一样,当您有不同的驱动程序类,例如mysql、psql等)

您可能应该让
ExpFake
扩展
Exp
,而不是
客户端
,并覆盖所有需要实际服务的内容。@lanzz仍然没有回答我的问题。。在这种情况下,Experia将扩展什么?Exp是假的还是Exp?这是同样的问题不幸的是,PHP5.4不到1%。。对于所有sortsa开发人员都将使用的API来说,这不是一个理想的解决方案。当然,这取决于您的客户群。驱动程序解决方案是另一种选择。