Каков наилучший способ добиться такого же поведения перегрузки метода в PHP? - PullRequest
0 голосов
/ 08 марта 2020

Предположим, у меня есть два класса с именами User и Product. Оба они должны быть сохранены в базе данных.

Третий класс, называемый PersistencyHandler, обрабатывает все взаимодействия с базой данных (чтобы подчиняться как принципу единой ответственности, так и инверсии зависимости). Вот как выглядит этот класс:

<?php
/**
 * Class PersistencyHandler
 * Handles database using PDO API
 */
class PersistencyHandler{

    /**
     * PDO connection used to save objects into.
     * @var $conn PDO
     */
    private $conn;

    /**
     * PDODatabaseSaver constructor.
     * @param $conn PDO
     */
    public function __construct($conn){
        $this->pdo = $conn;
    }

    /**
     * Saves the given object in the database
     * @param $object mixed
     */
    public function save($object){

        // as PHP does not support classic method overloading for different
        // types of objects, this is the cleanest solution I've been able to find.
        // And it's still pretty dirty...

        if($object instanceof Product) {
            $this->saveProduct($object);
        } else if($object instanceof User) {
            $this->saveUser($object);
        } else {
            throw new UnsupportedOperationException("Cannot save object, unsupported type."); // custom class
        }
    }


    private function saveProduct(Product $object){
        // save Product into database
    }

    private function saveUser(User $object){
        // save User into database
    }

}
?>

Я пришел из Java опыта и уверен, что использование instanceof - это очень плохая практика (по крайней мере, в Java). Например, в Java я использовал для решения подобных проблем перегруженные методы.

Я проверил php. net и другие веб-сайты (включая этот), но Я не нашел хорошего ответа на свой вопрос:

Каков лучший способ добиться того же поведения вышеуказанного кода правильным способом?

Уведомление что у меня есть единственный метод с единственным аргументом и вызываемый метод определяется типом аргумента.

1 Ответ

1 голос
/ 08 марта 2020

Решение состоит в том, чтобы использовать динамический вызов c (аналогично отражению в Java):

public function save($object)
{
    $mtd = 'save'.get_class($object);
    if(method_exists($this, $mtd))
        call_user_func(array($this, $mtd), $object);
    else
        throw new UnsupportedOperationException("Cannot save object, unsupported type.");
}

Примечание: если вы используете пространства имен, вам нужно будет адаптировать код (get_class ( ) возвращает полное имя).

...