Helpers - компьютеры, интернет, программирование

PHP - смешивание объектов Injection и наследования

Это дополнительный вопрос к следующему ответу: Родительский объект в php

class A {
    protected function doSomeStuff(){
       echo 'a method that all children will need to call';
    }
}

class B {
    protected $_parent;
    public function __construct($parent) {
       $this->_parent = $parent;
    }
    public function doSomeLocalStuff() {
       $this->_parent->doSomeStuff(); // Fatal Error
    }
}

$a = new A(); // will be used for other children as well.
$b = new B($a);
$b->doSomeLocalStuff();

В приведенном выше коде использовалась инъекция родительского объекта, позволяющая инициализировать класс B с использованием определенного экземпляра класса A, но класс B не будет иметь доступ к защищенным свойствам или методам класса A (например, doSomeStuff()).

Но, смешивая вышеописанное с наследованием, мы получаем лучшее из обоих миров :)

class B extends A {
    protected $_parent;
    public function __construct($parent) {
       $this->_parent = $parent;
    }
    public function doSomeLocalStuff() {
       $this->_parent->doSomeStuff(); // Works :)
    }
}

Итак, допустимо ли это? .. есть недостатки?

P.S. Я пытаюсь реализовать нестатический фабричный шаблон.

Пояснение

Учтите, я пытаюсь создать класс, который будет использоваться для вызова внешнего API. У нас более 400 различных звонков, разделенных на 10 категорий (выставление счетов, клиенты, продукты...).

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

Итак, вместо того, чтобы помещать метод 400 в один большой класс, я решил разделить их на 10 классов с родительским классом, обрабатывающим общие функции (например, аутентификацию, создание URL-адресов, веб-вызов...), а затем создал фабричный шаблон, где я могу загружать только необходимые классы/категории во время выполнения.

Что-то типа :

$apiCall = new parentPlusFactory(); 
          //contains common methods and a mechanism to load sub-classes
$apiCall->setAPIuserName("user");
$apiCall->setAPIpassword("pass");
$apiCall->useClass('customers')->doSomeCustomerStuff();
$apiCall->useClass('products')->doSomeProductStuff();

Вот почему мне нужно использовать один и тот же экземпляр родительского класса.


  • Я не понимаю, почему вы хотите передать родителя конструктору, если вы можете просто создать новый B, являющийся A. Если вы не перезаписываете методы A в B, вы можете просто продолжать их использовать, и если вам нужно добавить некоторые вещи вы все еще можете получить к ним доступ с помощью родительского ключевого слова. 02.10.2011
  • Что ж, мне нужно использовать один и тот же экземпляр класса A для дочерних классов. 02.10.2011

Ответы:


1

В общем, вы должны предпочитать композицию наследованию. Для меня ваш вариант использования звучит так, как будто B вообще не должен расширять A, но вместо этого у вас должно быть два отдельных класса.

Теперь PHP 5.4 будет иметь «горизонтальное повторное использование», также известное как «черты», где можно будет «включить» черту в ваш класс.

trait A
{
    public function doSomeStuff()
    {
        echo 'doing some stuff';
    }
}

class B
{
    use A;

    public function doSomeLocalStuff()
    {
        $this->doSomeStuff();
    }
}

class C
{
    use A;

    public function doSomeLocalStuff()
    {
        echo 'Doing something completely different here';
    }
}

См. также Руководство по PHP: признаки и Выпущена первая бета-версия PHP 5.4.

02.10.2011
  • Единственная причина для расширения A — использование его защищенных методов. Доступ к методу, обрабатывающему веб-вызовы API в A, должен осуществляться только одним из этих конкретных подклассов API. 02.10.2011
  • Если подумать... Я попытаюсь перепроектировать класс, используя только композицию, так как это кажется логичным. 02.10.2011

  • 2

    В PHP нет ключевого слова friend, как в C++. Вы можете проверить это обсуждение, чтобы узнать, как реализовать friend классов.

    Но вам действительно нужно, чтобы эта функция была объявлена ​​protected?

    01.10.2011
  • Как вы упомянули, в PHP нет ни дружественных классов, ни надежной работы. И этот родительский метод должен быть защищен, поскольку он должен вызываться дочерним элементом. 02.10.2011
  • И это действительно не могло быть публичным? 02.10.2011
  • Да, так как родительский класс содержит основную логику, которая не имеет смысла при вызове вне контекста/дочерних классов. 02.10.2011
  • Методы класса A представляют собой конструктор для API, где они содержат основную логику (подключение, имя пользователя/пароль и т. д.), а другие дочерние классы содержат фактические методы API. Я постараюсь уточнить это больше в теле вопроса. 02.10.2011
  • Новые материалы

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

    Использование машинного обучения для диагностики болезни Альцгеймера, часть 4
    Маркеры семантической согласованности для ранней диагностики болезни Альцгеймера (arXiv) Автор: Давиде Колла , Маттео Дельсанто , Марко Агосто , Бенедетто Витиелло , Даниэле Паоло Радичони..

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

    Анимированный математический анализ
    Использование Manim для создания математических анимированных визуализаций Визуализация данных помогает понять скрытые закономерности в данных, которые невозможно визуализировать..

    Создание простого слайдера изображений с помощью JavaScript
    Узнайте, как создать базовый слайдер изображений с помощью HTML, CSS и JavaScript. Введение В этом уроке мы создадим удобный слайдер изображений, используя JavaScript, HTML и CSS. Ползунок..

    Создание базы данных с помощью супергероя «Python»
    В этом посте мы узнаем, как создать «базу данных SQLite с помощью модуля python sqlite3, создав простую функцию входа и регистрации. Готовы ли вы к этому путешествию? Если да , давайте приступим..

    ИИ для чайников: руководство для начинающих по пониманию будущего технологий
    Вы чувствуете, что остались позади в мире ИИ? Не волнуйтесь, вы не одиноки! Со всей этой шумихой вокруг искусственного интеллекта может быть трудно понять, с чего начать. Но не позволяйте сленгу..