Как я могу избежать отражений при использовании полиморфизма в PHP - PullRequest
0 голосов
/ 23 января 2019

У меня есть ситуация, когда у меня есть класс «Задача», который может «прогрессировать»

Однако у каждой Задачи есть разные обязательные параметры, чтобы знать, как развиваться, и поэтому «прогресс» должен получать разные параметры.

Что я делал, так это проверял, чтобы в каждой «Задаче» был реализован интерфейс «ITask», который заставляет внедрять метод «прогресса».Параметром для метода «prgoress» является интерфейс «ITaskProgress», который позволяет мне правильно определять ход выполнения задачи для каждой задачи.

Проблема заключается в том, что при использовании я должен отражать taskProgress внутри задачи.прогрессировать, знать, какие члены / метод существуют внутри «taskProgress», чтобы я мог использовать его для прогресса.

Я не чувствую, что это правильный путь, как бы вы соединили части правильно??

Предположим, что, поскольку задание и ход выполнения задания должны сохраняться в разных местах, они не могут жить в одном классе.

interface ITaskProgress {};
interface ITask
{
    function progress(ITaskProgress $taskProgress);
}
class DoThisTaskPrgoress implements ITaskProgress
{
    public $needThisToProgress;
}

class DoThatTaskProgress implements ITaskProgress
{
    public $needThatToProgress;
    public $alsoNeeded;
}

class DoThisTask implements ITask
{

    function progress(ITaskProgress $taskProgress)
    {
        if ($taskProgress instanceof DoThisTaskPrgoress)
        {
            $taskProgress->needThisToProgress++;
        }
    }
}

class DoThatTask implements ITask
{
    function progress(ITaskProgress $taskProgress)
    {
        if ($taskProgress instanceof DoThatTaskProgress)
        {
            if ($taskProgress->needThatToProgress > $taskProgress->alsoNeeded)
            {
                $taskProgress->needThatToProgress = 0;
            }

        }
    }
}

1 Ответ

0 голосов
/ 23 января 2019

Я знаю, что это немного самоуверенный ответ, но, насколько вам интересно мое мнение, я думаю, что вы можете доверять своим чувствам и должны опираться на них сильнее:

Я не чувствую, что это правильный путь, как бы вы соединили части правильно?

Также заголовок вопроса проясняет, что вам не нравится использовать отражения. Так что избавление от отражений - это, вероятно, хороший способ исправить ситуацию.

Так что сейчас вам нужно проанализировать объект, чтобы вы могли его использовать. Обычно это довольно громоздко для объектов, ваш случай - просто еще один пример этого.

Но почему это так громоздко? Ну, чтобы приносить пользу объектам, они должны быть более абстрактными. Однако здесь, в вашем случае (пожалуйста, не рассматривайте это как оскорбление, просто как еще один пример), вам нужно написать очень специализированный код только для использования объекта ( Tell Don't Ask ).

Это как если бы оно вывернулось наизнанку. Вместо того, чтобы выполнение задачи являлось деталью реализации, сама задача должна иметь дело с различными видами прогресса.

Так как решить это? Прежде всего, не делайте то, что вы не хотите делать (и делайте только то, что вы должны делать, в соответствии с вашим вопросом, то есть, если я правильно вас поняла, чтобы справиться с препятствием полиморфизма ) " [как вы его называете]), поэтому удалите if s:

class DoThisTask implements ITask
{

    function progress(DoThisTaskPrgoress $taskProgress)
    {
        $taskProgress->needThisToProgress++;
    }
}

class DoThatTask implements ITask
{
    function progress(DoThatTaskProgress $taskProgress)
    {
        if ($taskProgress->needThatToProgress > $taskProgress->alsoNeeded)
        {
            $taskProgress->needThatToProgress = 0;
        }
    }
}

Так что теперь это стало лучше, поскольку отражение (проверка типов) вышло из реализации выполнения.

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

Поскольку в PHP нет понятия «друзья» в видимости, намекание на тип более специфического типа хода выполнения задачи (по сравнению с интерфейсом хода выполнения задачи) имеет решающее значение, так как становится ясно, над каким конкретным типом прогресс ожидает работать. ( Вещи не ищите ).

И это приближает нас к инверсии управления , с которой мы часто сталкиваемся в объектно-ориентированном программировании. Теперь ясно, что для задания задачи требуется выполнение определенной задачи - объект, представляющий состояние, введенный в качестве параметра метода.

Если это основной дизайн, который вы выбираете для решения общей проблемы, он также должен помочь вам найти шаблон родительского контроля для вашего объектно-ориентированного дизайна. Например. Похоже, вам нужна (по крайней мере, очень маленькая) абстрактная фабрика, поэтому все, что происходит, происходит из семейства классов (задача progress и ), чтобы центральная фабрика могла предоставить это семейство. И фабрика может быть введена (инверсия управления), так что это семейство классов может быть «единым» в вашем общем приложении.

Какая задача затем нуждается в том, какой прогресс затем может быть решен на заводе, а остальная часть вашего кода должна просто работать (тм).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...