наследование — добавление абстрактного подкласса в PHP без изменения всех наследующих дочерних классов.

У меня похожая иерархия классов

interface ISomething
{
public function foo();
...
}

abstract class TopAbstract implements ISomething
{
...
}

abstract class HighAbstract extends TopAbstract
{
public function foo()
{
...
}
}

and 46(!) classes that inherit from HighAbstract

class One extends HighAbstract
{
}

...

class FortySix extends HighAbstract
{
}

Теперь я должен добавить функциональность, и для этого необходимо иметь альтернативный HighAbstract :: foo () (среди прочего).
Каков наилучший способ достичь этого?

  • Я мог бы просто изменить HighAbstract, но я хотел бы отделить эту новую функциональность (разделение задач)

  • Я мог бы добавить подкласс в HighAbstract, но тогда мне пришлось бы отредактировать 46 подклассов, чтобы изменить их родителя.

  • Я мог бы добавить признак в HighAbstract, но это все еще подразумевает изменение его (HighAbstract) с помощью ветвления и использование признака в HighAbstract :: foo ()

  • Есть другие идеи?

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

Как вы думаете?

Спасибо

0

Решение

Ваша проблема точно отражает ловушку Наследования, которая является наиболее сильной связью. Вы видите, когда ваши 46 подклассов наследуют HighAbstract класс, они будут использовать фиксированный а также бетон реализация foo метод реализован в HighAbstract учебный класс. Невозможно изменить это во время выполнения, и единственный вариант — изменить исходный код: либо измените 46 подклассов, чтобы унаследовать другого родителя, либо измените исходный код текущего родителя.

Что касается решений, я предлагаю два возможных:

1) Если вы используете хорошую IDE, вы можете использовать функцию рефакторинга, чтобы вам не нужно было вручную менять родителя для 46 подклассов.

2) Если вы ожидаете, что такого рода изменения, скорее всего, произойдут в будущем, то вы должны принять модифицирующий исходный код ваших 46 подклассов, но только один раз, предпочитая Aggregation, а не Inheritance, например:

class FlexibleAbstract extends TopAbstract {

private $origin;

public function __construct($origin) {
$this->origin = $origin;
}

public function foo() {
$this->origin->foo();
}

}

class One extends FlexibleAbstract {
...
}

function somewhere() {
$oneA = new One(new HighAbstract());
$oneB = new One(new AlternativeHighAbstract());
$oneC = new One(new AnotherAlternativeHighAbstract());
}

Конечно, это решение немного раздражает: каждый раз, когда вы создаете One объект, который вы должны создать TopAbstract возражать также Если вы ненавидите это, вам, возможно, придется рассмотреть шаблон Factory.

0

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

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

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector