Можно ли избежать дублирования кода в перехватчике __call() в данном частном случае (код внутри)? Прошу помощи у профи! Взялся за освоение ООП на PHP, сам придумываю себе примеры, поэтому, возможно, в коде присутствуют глупости. Есть объект класса Computer, внутри которого инициализируются еще два объекта - объект класса Hardware (содержащий информацию о "железе") и Software (соответственно, о софте). В этих двух классах есть метод getPrice(), получающий цену. Запрос цены "железа" и "софта" происходит так:print $computer->software->getPrice(); print $computer->hardware->getPrice(); Проблема: в "перехватчике" __call() класса Computer мне приходится проверять, есть ли у объекта software метод getPrice(), и есть ли у software метод getPrice(). Код почти идетничен (дублируется), за исключением названия объектов:// перехватчик function _call( $methodname, $args ) { // Вот здесь следует два практически одинаковых if-блока, // каждый из которых делает одно и то же - // проверяет наличие вызванного метода // // Вопрос: можно ли тут избежать дублирования? Если да, то как?
if ( method_exists( $this->hardware, $methodname ) ) { return $this->hardware->$methodname( $this ); } if ( method_exists( $this->software, $methodname ) ) { return $this->software->$methodname( $this ); } } Мне кажется, тут можно и нужно этого дублирования избежать, но как, пока не понимаю.Вот код полностью:hardware = new Hardware(); $this->software = new Software(); } // перехватчик function _call( $methodname, $args ) { // Вот здесь следует два практически одинаковых if-блока, // каждый из которых делает одно и то же - // проверяет наличие вызванного метода // // Вопрос: можно ли тут избежать дублирования? Если да, то как?
if ( method_exists( $this->hardware, $methodname ) ) { return $this->hardware->$methodname( $this ); } if ( method_exists( $this->software, $methodname ) ) { return $this->software->$methodname( $this ); } } } abstract class ComputerInfo { /* * * Выносим свойства и методы, общие для всех блоков информаци * о компьютере, в этот абстрактный класс * */ protected $price; function getPrice() { return $this->price; }
} class Hardware extends ComputerInfo { /* * * Блок информации об аппаратном обеспечении * */ function __construct() { $this->price=40000; } } class Software extends ComputerInfo { /* * * Блок информации о программном обеспечении * */ function __construct() { $this->price=15000; } } $computer = new Computer; print $computer->software->getPrice(); print "\r\n "; print $computer->hardware->getPrice(); ?>
Просьба пнуть в правильном направлении :) Заранее спасибо!
Да, дублирование кода в перехватчике __call() можно избежать. Вместо того, чтобы проверять каждый раз отдельно наличие вызываемого метода в hardware и software, можно использовать переменную, которая будет указывать на соответствующий объект (hardware или software), и затем вызывать метод на этом объекте.
Вот как это можно сделать:
function __call($methodname, $args) { $objects = [$this->hardware, $this->software]; foreach($objects as $object) { if (method_exists($object, $methodname)) { return $object->$methodname($this); } } }
Таким образом, мы перебираем массив объектов $objects, в который записаны объекты hardware и software. Если вызываемый метод есть у одного из объектов, мы вызываем его на этом объекте.
Теперь при вызове методов через объект $computer, он будет проверять наличие метода у объектов hardware и software без дублирования кода.
Надеюсь, это поможет вам избежать дублирования кода в вашем примере. Если у вас есть еще вопросы, не стесняйтесь задавать!
Да, дублирование кода в перехватчике __call() можно избежать. Вместо того, чтобы проверять каждый раз отдельно наличие вызываемого метода в hardware и software, можно использовать переменную, которая будет указывать на соответствующий объект (hardware или software), и затем вызывать метод на этом объекте.
Вот как это можно сделать:
function __call($methodname, $args) {$objects = [$this->hardware, $this->software];
foreach($objects as $object) {
if (method_exists($object, $methodname)) {
return $object->$methodname($this);
}
}
}
Таким образом, мы перебираем массив объектов $objects, в который записаны объекты hardware и software. Если вызываемый метод есть у одного из объектов, мы вызываем его на этом объекте.
Теперь при вызове методов через объект $computer, он будет проверять наличие метода у объектов hardware и software без дублирования кода.
Надеюсь, это поможет вам избежать дублирования кода в вашем примере. Если у вас есть еще вопросы, не стесняйтесь задавать!