关于适配器模式和继承的困惑(PHP)
Confusion about adapter pattern and inheritance (PHP)
我对适配器模式有些困惑,想知道它是否是我想要完成的目标的正确工具。
基本上,我试图让另一个开发人员编写的 class 符合我编写的接口,同时还保留了 class 的其他方法。
所以我为容器对象编写了以下接口:
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 中使用它,如下所示:
class MyClass implements \ArrayAccess
{
protected $container;
public function __construct(MyContainerInterface $container) {
$this->setContainer($container);
}
public function offsetExists($key) {
$this->container->has($key);
}
...
}
然后我的应用程序就这样使用 class:
$myClass = new MyClass(new OtherContainerAdapter(new OtherContainer));
我遇到的问题是,为了使用适配器中的方法,我必须编写以下内容:
$myClass->getContainer()->getContainer()->has('some_key');
理想情况下应该是:
$myClass->getContainer()->has('some_key');
$myClass->getContainer()
应该 return 一个 MyContainerInterface
的实例,并且具有 has()
函数。它不应该有 getContainer()
函数。
我认为您不需要为此使用适配器模式。在我看来,您似乎在寻求多态解决方案,只需使用抽象 class 即可实现。无需适配器。
界面
interface MyContainerInterface
{
public function has($key);
public function get($key);
public function add($key, $value);
public function remove($key);
}
然后抽象基class:
class MyContainerBaseClass implements MyContainerInterface, \ArrayAccess
{
public function offsetExists($key) {
$this->has($key);
}
...
}
然后,来自其他开发者的子class:
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
方法存在于其他开发人员的实现中。
要使其真正具有多态性,您不会硬编码 class 名称,但您会使用可能来自配置文件、数据库或工厂的变量。
例如:
$className = "ClassByOtherDeveloper"; //this could be read from a database or some other dynamic source
$object = new $className();
$x = $object->has('some_key');
我对适配器模式有些困惑,想知道它是否是我想要完成的目标的正确工具。
基本上,我试图让另一个开发人员编写的 class 符合我编写的接口,同时还保留了 class 的其他方法。
所以我为容器对象编写了以下接口:
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 中使用它,如下所示:
class MyClass implements \ArrayAccess
{
protected $container;
public function __construct(MyContainerInterface $container) {
$this->setContainer($container);
}
public function offsetExists($key) {
$this->container->has($key);
}
...
}
然后我的应用程序就这样使用 class:
$myClass = new MyClass(new OtherContainerAdapter(new OtherContainer));
我遇到的问题是,为了使用适配器中的方法,我必须编写以下内容:
$myClass->getContainer()->getContainer()->has('some_key');
理想情况下应该是:
$myClass->getContainer()->has('some_key');
$myClass->getContainer()
应该 return 一个 MyContainerInterface
的实例,并且具有 has()
函数。它不应该有 getContainer()
函数。
我认为您不需要为此使用适配器模式。在我看来,您似乎在寻求多态解决方案,只需使用抽象 class 即可实现。无需适配器。
界面
interface MyContainerInterface
{
public function has($key);
public function get($key);
public function add($key, $value);
public function remove($key);
}
然后抽象基class:
class MyContainerBaseClass implements MyContainerInterface, \ArrayAccess
{
public function offsetExists($key) {
$this->has($key);
}
...
}
然后,来自其他开发者的子class:
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
方法存在于其他开发人员的实现中。
要使其真正具有多态性,您不会硬编码 class 名称,但您会使用可能来自配置文件、数据库或工厂的变量。
例如:
$className = "ClassByOtherDeveloper"; //this could be read from a database or some other dynamic source
$object = new $className();
$x = $object->has('some_key');