关于适配器模式和继承 (PHP) 的混淆



我对适配器模式有些困惑,想知道它是否是我想要完成的正确工具。

基本上,我正在尝试让另一个开发人员编写的类符合我编写的接口,同时保留该类中的其他方法。

所以我为容器对象编写了以下接口:

interface MyContainerInterface
{
    public function has($key);
    public function get($key);
    public function add($key, $value);
    public function remove($key);
}

我还编写了一个实现该接口的适配器:

class OtherContainerAdapter implements MyContainerInterface
{
    protected $container;
    public function __construct(ContainerInteface $container) {
        $this->container = $container;
    }
    public function has($key) {
        $this->container->isRegistered($key);
    }
    ...
 }

我在我的课堂上使用它,如下所示:

class MyClass implements ArrayAccess
{
    protected $container;
    public function __construct(MyContainerInterface $container) {
        $this->setContainer($container);
    }
    public function offsetExists($key) {
        $this->container->has($key);
    }
    ...
}

然后我的应用程序使用该类,如下所示:

$myClass = new MyClass(new OtherContainerAdapter(new OtherContainer));

遇到的问题是,为了使用适配器中的方法,我必须编写以下内容:

$myClass->getContainer()->getContainer()->has('some_key');

理想情况下,它只是:

$myClass->getContainer()->has('some_key');
$myClass->getContainer()

应该返回一个MyContainerInterface实例,并且具有has()函数。它不应该有getContainer()函数。

我认为您不需要适配器模式。 在我看来,您正在寻求多态解决方案,这可以通过简单地使用抽象类来完成。 无需适配器。

界面

interface MyContainerInterface
{
    public function has($key);
    public function get($key);
    public function add($key, $value);
    public function remove($key);
}

然后是抽象基类:

class MyContainerBaseClass implements MyContainerInterface, ArrayAccess
{
    public function offsetExists($key) {
        $this->has($key);
    }
    ...
 }

然后,来自其他开发人员的子类:

class ClassByOtherDeveloper extends MyContainerBaseClass 
{
    public function has($key) {
        $this->isRegistered($key);
    }    
    //you also need to implement get(), add(), and remove() since they are still abstract.
    ...
}

您可以在应用程序中使用它,如下所示:

$object = new ClassByOtherDeveloper();
$x = $object->has('some_key');

我假设isRegistered方法存在于其他开发人员的实现中。

要使其真正多态,您不会对类名进行硬编码,但会使用可能来自配置文件、数据库或工厂的变量。

例如:

$className = "ClassByOtherDeveloper"; //this could be read from a database or some other dynamic source
$object = new $className();
$x = $object->has('some_key');

最新更新