G
G
Grigory2017-02-16 16:48:00
PHP
Grigory, 2017-02-16 16:48:00

Is it possible to avoid code duplication in the __call() interceptor in this particular case (code inside)?

Ask the pros for help!
I took up the development of OOP in PHP, I come up with examples for myself, so perhaps there are stupid things in the code.
There is an object of the Computer class , within which two more objects are initialized - an object of the Hardware class (containing information about the hardware) and Software (respectively, about the software). These two classes have a getPrice() method that gets the price.
The request for the price of "hardware" and "software" goes like this:

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

Problem: In the __call() hook of the Computer class , I have to check if the software object has a getPrice() method, and if the software object has a getPrice() method. The code is almost identical (duplicated), except for the names of the objects:
// перехватчик

    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 );

        }


    }

It seems to me that here it is possible and necessary to avoid this duplication, but I still don’t understand how.
Here is the code in full:
<?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();


?>

Please kick in the right direction :)
Thanks in advance!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
F
Fuze, 2017-02-16
@gpetrov

It makes no sense to check for existence, because getPrice method is declared in computerInfo.
I would rewrite this synthetic example something like this:

<?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();

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question