可选模式?

时间:2013-09-12 18:39:33

标签: php design-patterns

我正试图找到一种方法,使任何(或至少一组)班级都能够有选择。

这是我想要的通用界面

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,在这种情况下我可以使用特征)。

2 个答案:

答案 0 :(得分:2)

首先,你必须小心in order not to violate the Single-Responsibility Principle。做一些事情并考虑到选项的对象应该将这些选项作为参数。

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
}

核心要点:

  • Cookie应完全不知道默认选项。它只做一件事 - Cookie CRUD操作

  • CookieOptionsInterface应完全不知道Cookie课程。它只做一件事 - 它抽象选项访问

  • 它不破坏封装

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

  • 遵守单一责任原则

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

答案 1 :(得分: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);