从类自己的方法告诉继承方法的最佳实践

Str*_*rae 2 php oop inheritance refactoring

我在一个项目中,我有一个扩展ADODB_base类的数据库类 - 我的目标是用ad-hoc数据库包装器层类替换ADODB_class.

该班有约200种方法; 确定从ADODB_class继承的方法(我必须在自定义包装器中使用相同的名称/ args重新创建以避免重构中的大头条)以及它自己的方法,这可能是一个很好的做法?

编辑:示例代码:

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([...]);
    }
    //[...]
}
Run Code Online (Sandbox Code Playgroud)

我的目标是找到最好的做法,告诉它do_something()属于Postgres,而query()属于ADODB_base,而不改变所有使用Postgres类的代码.

即使属性也会很可爱.

Gor*_*don 10

这里有一些方法,没有一个我觉得最佳实践的名字很舒服:

示例类

class A
{
    public function fn() {}
}
class B extends A 
{
    public function foo() {}
}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

使用类/对象函数检查父方法中是否存在方法

var_dump(method_exists(get_parent_class('B'), 'fn'));  // TRUE
var_dump(method_exists(get_parent_class('B'), 'foo')); // FALSE
Run Code Online (Sandbox Code Playgroud)

使用类/对象功能列出所有父方法

print_r(get_class_methods(get_parent_class('B')));
Run Code Online (Sandbox Code Playgroud)

以上所有的现场演示:http://codepad.org/YWrKGNzm


使用装饰器

如果这是针对某种类型的Decorator模式,您还可以使用魔术__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
        );    
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,所有魔术方法都会对您的应用程序产生严重的性能影响,并且您希望对解决方案进行基准测试,以确定它是否可以在您的设置中容忍.


进一步阅读

有关其他想法,请查看其他结构设计模式