我在一个项目中,我有一个扩展ADODB_base类的数据库类 - 我的目标是用一个特殊的数据库包装器层类替换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([...]);
}
//[...]
}
我的目标是找到最佳做法,告诉do_something()
属于Postgres
,而query()
属于ADODB_base
,而不更改所有代码使用Postgres
类。
甚至可以识别属性......
答案 0 :(得分:10)
以下是一些方法,其中没有一个我觉得最佳实践名称会很舒服:
class A
{
public function fn() {}
}
class B extends A
{
public function foo() {}
}
Reflection API几乎可以识别您课程的各个方面。但是,由于提供此信息所需的大量分析过程,这会对性能产生影响。更快的替代方案是类/对象功能。但是,可能收集的信息比Reflection提供的信息更加有限。
$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
如果这是针对某种类型的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
);
}
}
请注意,所有魔术方法都会对您的应用程序产生严重的性能影响,并且您希望对解决方案进行基准测试,以确定它是否可以在您的设置中容忍。
有关其他想法,请查看其他Structural Design Patterns