Задать вопрос
@gpetrov
web-программист

Можно ли избежать дублирования кода в перехватчике __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 );

        }


    }


Мне кажется, тут можно и нужно этого дублирования избежать, но как, пока не понимаю.

Вот код полностью:

<?php

class Computer {


/*
* 
* Класс содержит два блока информации о компьютере -
* с описанием аппаратного и программного обеспечения.
* Каждый блок реализован в виде класса.
* 
*/


    public $hardware; // здесь хранится объект с информацией о "железе"
    public $software; // и объект с информацией о софте


    function __construct() {

        $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 <br />";

print $computer->hardware->getPrice();


?>


Просьба пнуть в правильном направлении :)
Заранее спасибо!
  • Вопрос задан
  • 161 просмотр
Подписаться 1 Оценить 3 комментария
Решения вопроса 1
InstantMedia
@InstantMedia
Проверять на существование не имеет смысла, т.к. метод getPrice объявлен в computerInfo.
Я бы переписал этот синтетический пример как то так:

<?php

class computer {

    public function __get($name) {

        if(class_exists($name)){
            $this->{$name} = new $name();
            return $this->{$name};
        }

        return null;

    }

}

abstract class computerInfo {

    protected $price;

    public function getPrice() {

        return $this->price;

    }


}

class hardware extends computerInfo {

    public function __construct() {

        $this->price=40000;

    }

}

class software extends ComputerInfo {

    public function __construct() {

        $this->price=15000;

    }

}

$computer = new computer;

print $computer->software->getPrice();

print "\r\n <br />";

print $computer->hardware->getPrice();
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы