#php #oop
#php #ооп
Вопрос:
Допустим, у меня есть класс с именем Class_Tool_RandomColor. Все, что он делает, это возвращает случайный цвет. У него есть метод с именем GetValue(), Другой называется Class_Tool_RandomLineType . Этот возвращает тип строки, как в сплошном, пунктирном и так далее .. также использует GetValue()
Теперь у меня есть много классов, которым нужен случайный цвет и случайный тип строки. Class_Square, Class_Circle, Class_Triangle и так далее…
/* First I create my Class_Tool_RandomColor on top of my php file */
$colorObj = new Class_Tool_RandomColor();
$lineObj = new Class_Tool_RandomLineType();
…
…
…
…
/* Now when I created my other classes I pass the object to them */
$squareObj = new Class_Square($colorObj,$lineObj);
... ...
$circleObj = new Class_Circle($colorObj,lineObj);
... ...
Это лучший способ? или есть другие способы?
Я думаю, я могу использовать extend?
class Class_Tool_RandomColor extends Class_Square{
Но если я использую extend, что делать, если несколько классов могут его расширить..
Комментарии:
1. Вопрос «Это лучший способ?» не является хорошим вопросом для SO, однако я бы рекомендовал для этого композицию. Ваш пример наследования не будет работать
2. лучший вариант использовать интерфейс, php не поддерживает множественное наследование, чтобы преодолеть эту проблему, вам нужно использовать интерфейс
3. Значит, передача нескольких классов родительскому классу не рекомендуется? Почему бы и нет? Я прочитаю об интерфейсе, предполагая, что смогу найти простой для понимания учебник по нему, спасибо
4. Наследование не должно изменять тип объектов — родительский — это просто более общий тип (даже абстрактный) для его дочерних элементов. Ваш подход к внедрению зависимостей — лучший выбор здесь. Интерфейс предоставит вам зависимость от абстракции (например, ваш круг не должен зависеть от случайного цвета — просто что-то, что возвращает цвет с
getValue()
помощью метода — вы бы достигли этого, введя разныеColor
/Line
классы). КромеClass
того,Tool
части имен являются избыточными — удалите их. Возможно, последнее более описательно, но я бы все равно использовал такое общее имя как часть пространства имен.5. Я читаю об интерфейсе, но не понимаю, это не работает с мозгом. По крайней мере, не так, как это применимо к моему примеру выше. Я хочу получить доступ к некоторым методам одного класса «инструмент» внутри одного из других классов (circle). Единственный способ, которым я могу это сделать, — передать $colorObj(tool) в качестве параметра классу (circle). Или путем создания нового экземпляра $colorObj внутри circleObj (чего я не хочу делать). Также я нашел этот пример https://gist.github.com/reaneyk/6604607 но я этого не понимаю. Я отлично работаю без реализации
Ответ №1:
Я думаю, что термин, который вы ищете IoC
, — это инверсия управления, но сканируйте, прежде чем идти, и начните с Dependency Injection
и Factories
, это шаблоны проектирования. Вы ступаете в гораздо более глубокую воду, так что приготовьтесь плавать.
Преимущества использования a service container
для управления классами [объектами] в вашем приложении огромны. A service container
создаст экземпляр ваших классов и внедрит зависимости объектов для вас.
Несколько быстрых результатов поиска в Google для начала:
- http://coderoncode.com/dependency-injection/design-patterns/programming/php/development/2014/01/06/dependency-injection-php.html
- http://krasimirtsonev.com/blog/article/Dependency-Injection-in-PHP-example-how-to-DI-create-your-own-dependency-injection-container
- http://www.phptherightway.com/pages/Design-Patterns.html (Только первая часть, называемая Фабриками, относится к этому вопросу.
- https://github.com/domnikl/DesignPatternsPHP/tree/master/Creational (Примеры кода шаблона проектирования php для создания)
Некоторые библиотеки:
- Pimple — очень простой DI-контейнер. http://pimple.sensiolabs.org /
- http://php-di.org/
Большинство новых фреймворков php включают в себя какой-то сервисный уровень, реализующий материал, который вы прочитали выше.
Ответ №2:
Если вы расширяете класс, это означает, что он будет загружаться одновременно с созданием экземпляра производного класса и использованием памяти. Вы можете использовать extends
, когда вам нужен родительский класс, в основном во всех методах производного класса. Но создание экземпляра внутри метода класса полезно, когда вам нужен минимальный вызов из другого класса. Итак, это зависит от того, насколько важен другой класс.
Комментарии:
1. также вы можете использовать getter setter для одного экземпляра любого класса и использовать его для всех методов, когда это необходимо.