【问题标题】:Confusion about adapter pattern and inheritance (PHP)关于适配器模式和继承的困惑(PHP)
【发布时间】:2015-01-23 01:19:06
【问题描述】:

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

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

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

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');

【问题讨论】:

    标签: php inheritance design-patterns containers adapter


    【解决方案1】:
    $myClass->getContainer()
    

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

    【讨论】:

      【解决方案2】:

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

      界面

      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');
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-18
        • 2019-11-07
        • 2019-10-26
        • 2012-04-10
        • 1970-01-01
        • 1970-01-01
        • 2014-10-15
        • 1970-01-01
        相关资源
        最近更新 更多