Шаблон декоратора с отношением метода

Я использую шаблон проектирования Decorator в 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"]);

С этим кодом методы showUser из MyClassDecorator & MyClassDecorator2 никогда не будет вызываться.

Что я могу сделать?
Запрещено ли вызывать другой метод того же класса? (Не очень удобно разбивать мой код)
Есть ли другой способ сделать это?
Должен ли я создать один интерфейс по методу?

Большое спасибо 🙂

РЕДАКТИРОВАТЬ:

Вот решение, которое я наконец-то использовал, хотя я не очень доволен им …

Я делю код не по методам, а по интерфейсам (сервисам)

Вот :

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"]);

Если у вас есть лучшее решение, я буду рад узнать это 🙂

Конечно, я использую шаблон декоратора, чтобы использовать эти декораторы по-разному во многих проектах, как в следующих примерах:

//no decorators
Services::$showUser = new MyShowUser();

//only the first
Services::$showUser = new MyShowUserDecorator(new MyShowUser());

//only the second
Services::$showUser = new MyShowUserDecorator2(new MyShowUser());

Таким образом, расширение не кажется хорошим решением.

Еще раз большое спасибо за то, что дали правильный способ сделать это 🙂

0

Решение

Мне кажется, вам нужно немного подумать об этом. Если вы можете дать четкое представление о том, чего вы пытаетесь достичь, тогда мы сможем предоставить вам более глубокое понимание. Но ответить на ваш вопрос напрямую вы можете extend класс, а затем override метод.

http://sandbox.onlinephpfunctions.com/code/61c33b0ce98631986134bf78efcd0391f9b9ab67

<?php
interface MyInterface {
function showUsers($array);
function showUser($i);
}

class MyCLass implements MyInterface {

function showUsers($array = ["Alfred", "Bob", "Claire"])
{
foreach($array as $toto) {
$this->showUser($toto);
}
}

function showUser($i)
{
echo $i;
}
}

// Extend the class in order to override the methods.
class MyCLassDecorator extends MyCLass {

// Also, try removing this method to see what it does.
function showUsers($array = [1,2,3])
{
foreach($array as $toto) {
$this->showUser($toto);
}
}

function showUser($i)
{
echo "c'est la fete chez $i";
}
}

$myClass = new MyCLassDecorator();

$myClass->showUsers();

РЕДАКТИРОВАТЬ

Не уверен, ясно ли мне, но проблема в том, что вы ожидаете наследственное поведение без использования наследование. Как MyCLass должен знать о MyCLassDecorator::showUser?

foreach($array as $toto) {
// The issue is this line. You're mixing `decorator` and `inheritance`.
// You should re-think your design. This will not work.
$this->showUser($toto);
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]