Лучшая практика, чтобы отличать унаследованные методы от собственного метода класса - PullRequest
2 голосов
/ 28 апреля 2011

Я в проекте, где у меня есть класс базы данных, который расширяет класс ADODB_base - Моя цель состоит в том, чтобы заменить ADODB_class классом слоя специальной оболочки базы данных .

В классе есть ~200 методов;Что может быть хорошей практикой для определения методов, которые он наследует от ADODB_class (что мне нужно воссоздать с тем же именем / аргументами в пользовательской оболочке, чтобы избежать больших головных кэшей при рефакторинге), и это собственные методы?

РЕДАКТИРОВАТЬ: пример кода:

class Postgres extends ADODB_base{
    //[...]
    // This method exist in Postgres class but not in ADODB_base,
    // let's say this is a Postgres own method.
    public function do_something()
    {
        //[...]
        // query() method belongs to ADODB_base class, so i need to create it
        // in my wrapper too, keeping the name and the args.
        $this->query([...]);
    }
    //[...]
}

Моя цель - найти лучшие практики, чтобы сказать, что do_something() принадлежит Postgres, а query() принадлежит ADODB_base, без изменений всего кода, который использует Postgres класс.

Будет приятно идентифицировать даже атрибуты ..

1 Ответ

10 голосов
/ 28 апреля 2011

Вот несколько подходов, ни один из которых я бы не назвал наилучшей практикой:

Примеры классов

class A
{
    public function fn() {}
}
class B extends A 
{
    public function foo() {}
}

Reflection API может в значительной степени идентифицировать каждый аспект ваших классов.Однако это приводит к снижению производительности из-за сложного процесса анализа, необходимого для предоставления этой информации.Несколько более быстрыми альтернативами являются функции класса / объекта.Однако информация, которую можно собрать, гораздо более ограничена, чем предоставляемая Reflection.

Использование Reflection API для получения класса, в котором был определен метод

$reflector = new ReflectionMethod('B', 'fn');
echo $reflector->getDeclaringClass()->getName(); // A
$reflector = new ReflectionMethod('B', 'foo');
echo $reflector->getDeclaringClass()->getName(); // B

Использование Функция класса / объекта для проверки наличия метода в родительском

var_dump(method_exists(get_parent_class('B'), 'fn'));  // TRUE
var_dump(method_exists(get_parent_class('B'), 'foo')); // FALSE

Использование функции класса / объекта для вывода списка всех родительских методов

print_r(get_class_methods(get_parent_class('B')));

Демонстрационная версия для всехвыше: http://codepad.org/YWrKGNzm


Использование декоратора

Если это для какого-то шаблона декоратора, вы также можете использовать магические методы __call для перехвата и делегирования любых вызововметоды, которых нет в декораторе для декорированного экземпляра, например,

class Decorator 
{    
    public function __construct($instance)
    {
        $this->decoratedInstance = $instance;
    }
    public function __call($method, $args)
    {
        return call_user_func_array(
            array($this->decoratedInstance, $method), 
            $args
        );    
    }
}

Обратите внимание, что любой магический метод может оказать серьезное влияние на производительность вашего приложения, и вы хотите сравнить решение с тестом, чтобы увидеть, допустимо ли оно в вашей установке.


Дополнительные сведения

Для дополнительных идей, посмотрите на другие Структурные шаблоны проектирования

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...