我在PHP中使用设计模式装饰器,我有一个结构问题。装饰模式与方法关系
这里有一个简单的例子来说明我的问题:
interface MyInterface {
function showUsers($array);
function showUser($i);
}
class MyCLass implements MyInterface {
function showUsers($array)
{
foreach($array as $toto) {
$this->showUser($toto);
}
}
function showUser($i)
{
echo $i;
}
}
class MyCLassDecorator implements MyInterface {
private $inner;
public function __construct(MyInterface $inner)
{
$this->inner = $inner;
}
function showUsers($array)
{
$this->inner->showUsers($array);
}
function showUser($i)
{
echo "User: $i";
}
}
class MyCLassDecorator2 implements MyInterface {
private $inner;
public function __construct(MyInterface $inner)
{
$this->inner = $inner;
}
function showUsers($array)
{
$this->inner->showUsers($array);
}
function showUser($i)
{
$this->inner->showUser($i);
echo " is wonderful";
}
}
$myClass = new MyCLassDecorator2(new MyCLassDecorator(new MyCLass()));
$myClass->showUsers(["Alfred", "Bob", "Claire"]);
有了这个代码,MyClassDecorator & MyClassDecorator2的方法showUser将永远不会被调用。
我该怎么办? 禁止调用同一类的另一种方法吗? (不是很方便的分割我的代码) 有没有另一种方法来做到这一点? 我应该通过方法创建一个接口吗?
感谢很多:)
编辑:
这里是我最后使用的解决方案,虽然我不是很满意的吧...
我不是在拆我的代码方法,但在接口(服务)
这就是:
interface IShowUsers {
function showUsers($array);
}
interface IShowUser {
function showUser($user);
}
class Services {
static $showUsers;
static $showUser;
}
class MyShowUsers implements IShowUsers {
function showUsers($array)
{
foreach($array as $toto) {
Services::$showUser->showUser($toto);
}
}
}
class MyShowUser implements IShowUser {
function showUser($user)
{
echo $user;
}
}
class MyShowUserDecorator implements IShowUser {
private $inner;
public function __construct(IShowUser $inner)
{
$this->inner = $inner;
}
function showUser($user)
{
echo "User: ";
$this->inner->showUser($user)
}
}
class MyShowUserDecorator2 implements IShowUser {
private $inner;
public function __construct(MyInterface $inner)
{
$this->inner = $inner;
}
function showUser($user)
{
$this->inner->showUser($user);
echo " is wonderful";
}
}
$myClass = new MyShowUserDecorator2(new MyShowUserDecorator(new MyShowUser()));
Services::$showUsers = new MyShosUsers();
Services::$showUser = new MyShowUserDecorator2(new MyShowUserDecorator(new MyShowUser()));
Services::$showUsers->showUsers(["Alfred", "Bob", "Claire"]);
如果你有一个更好的解决方案,我会很高兴地知道它:)
当然,我在这些exemples使用Decorator模式在许多项目中使用不同的方式处理这些装饰,如:
//no decorators
Services::$showUser = new MyShowUser();
//only the first
Services::$showUser = new MyShowUserDecorator(new MyShowUser());
//only the second
Services::$showUser = new MyShowUserDecorator2(new MyShowUser());
所以扩展似乎不是一个好的解决方案。
非常感谢你又给这样做的正确的方式:)
是的,在这个小例子中它将是一个很好的解决方法,但是我在symfony服务中遇到了这个问题,它具有更复杂的功能和更多的装饰封装。所以我需要保持装饰模式,以避免擦除重写。 –
您没有正确使用装饰模式,并且编辑了代码,所以我的示例现在已过时。你调用了'$ this-> inner-> showUsers($ array);'在MyCLass的一个实例上调用'showUsers',这就是为什么它没有使用MyCLassDecorator :: showUser。你必须'扩展'这个类,以便它知道重写方法,或者你需要正确使用装饰器模式。我会看看我能否拿出一个例子。 – waterloomatt
我已经编辑了我的帖子,你现在可能会更好地理解我需要的东西:) 而且我确切的说,我不知道装饰者将使用哪种顺序。 –