0

我正在尝试想出一种方法,让任何(或至少一组)班级都有选择的能力。

这是我想要的通用接口

interface OptionableInterface
{
    public function getOption($key);
    public function setOption($key, $value);
    public function getOptions();
    public function setOptions($options, $merge);
    public function removeOption($key);
}

我考虑过使用上述接口实现一个具体类,然后根据需要对其进行扩展,但由于 PHP 没有多重继承,这可能是一个问题。

另一种方法是使用装饰器模式。但我不确定这是否是装饰器模式的正确用法。

有任何想法吗?我现在坚持使用 PHP 5.2(也许以后可以更改为 5.3,在这种情况下我可以使用特征)。

4

2 回答 2

2

首先,您必须小心,以免违反单一职责原则。做某事并考虑到选项的对象应该将这些选项作为参数。

interface CookieOptionsInterface
{
    public function setPath($path);
    public function getPath();
    public function setTtl();
    public function getTtl();

    //...The rest if needed 
}


class Cookie
{
    protected $cookieOptions;
    
    public function __construct(CookieOptionsInterface $cookieOptions)
    {
       $this->cookieOptions = $cookieOptions;
    }

    public function write(array $pair)
    {
        foreach ($pair as $key => $value) {
              setcookie($key, $value, $this->cookieOptions->getTtl() + time(), $this->cookieOptions->getPath());
        }
    }

    // .. The rest
}

需要注意的核心点:

  • ACookie应该完全不知道默认选项。它只做一件事——CookieCRUD操作

  • CookieOptionsInterface应该完全不知道Cookie类。它只做一件事——抽象选项访问

  • 它不会破坏封装

  • 它遵循依赖注入(因此您可以轻松地模拟$cookieOptions

  • 它遵循单一职责原则

  • 由于CookieOptionsInterface完全解耦,您可以继承自(从而减少其他选项的代码重复,例如CookieBar

于 2013-09-12T19:19:29.943 回答
1

您可以使用组合而不是继承或接口。也许是这样的:

class SomethingThatHasOptions {
  public $options;
  public function __construct () {
    $this->options = new OptionProvider ();
  }
}

class OptionProvider {
    public function getOption($key) { ... }
    public function setOption($key, $value) { ... }
    public function getOptions() { ... }
    public function setOptions($options, $merge) { ... }
    public function removeOption($key) { ... }
}

然后你可以像这样使用它:

$optionable = new SomethingThatHasOptions;
$optionable->options->setOption('foo', 42);
于 2013-09-12T18:44:05.197 回答