实现这种行为的最佳模式是什么?
我有很多方法,比如method_1 ..method_N,它可以用一个参数来参数化,比如$k。我想把它们作为静态方法放在类中,所以我当然可以这样写我的compuationclass:
class Computation {
static function method1( $k, $otherParams ) { ... }
static function method2( $k, $otherParams ) { ... }
static function method3( $k, $otherParams ) { ... }
}
现在,因为$k属于一个特定的值范围,比如{'dog', 'cat', 'mouse'},我想创建计算的许多子类,每个可能的值一个。
class Computation_Dog extends Computation {
static function method1( $otherParams ) { parent::method1('dog', $otherParams); }
static function method2( $otherParams ) { parent::method2('dog', $otherParams); }
static function method3( $otherParams ) { parent::method3('dog', $otherParams); }
}
class Computation_Cat extends Computation { .. }
class Computation_Mouse extends Computation { .. }
但是这很难看,让我放弃继承的优点:如果我在计算中添加一个方法会发生什么?必须编辑所有子类…然后我聪明地改成了:
abstract class Computation {
abstract static function getK();
static function method1($otherParams) { ... self::getK() .. }
static function method2($otherParams) { ... self::getK() .. }
static function method3($otherParams) { ... self::getK() .. }
}
class Computation_Dog extends Computation {
static function getK() { return 'dog'; }
}
不错的尝试,但它不起作用,因为静态方法似乎不记住继承堆栈,并且self::getK()将调用Computation::getK()而不是Computation_Dog::getK()。
好. .希望足够清楚…你会如何设计这种行为?PS:我真的需要它们作为静态方法
谢谢
我根本不会设计这种行为。如果你需要调用parent::Method1('dog'),这意味着父类显然知道计算狗。你的Calculating_Dog类只是一个包含简写的愚蠢类。
是的,如果你在基类中添加一个方法,你就必须将它添加到所有其他类中。
如果您希望使用实例而不是静态类,则可以向包含计算类型的类添加属性。这样就不需要长函数了。您可以直接将速记函数添加到基类中,并使用属性而不是参数。你可以给这个类一个受保护的构造函数,并传递给它正确的类型。
然后,您可以创建具有不带参数的构造函数的后代,它们以所需类型作为参数调用父类构造函数。然后,对这些后代进行单例引用。这是一种接近你想要的东西的方法。但我需要看到或听到你真正想要达到的目标,以确定这是否是最佳解决方案。
[编辑]你可以使用__callStatic(来自PHP 5.3)来捕获不存在的方法的静态方法调用。然后,您可以将额外的'dog'参数移到属性的开头,并调用Calculate基类。这里演示了两种方法:
/* METHOD 1 Use __callStatic and make the parent function protected
to hide them. Else __callStatic won't work. */
class Calculate1
{
protected static function Method1($type, $param)
{
echo "Retrieving call for $type with param $param.";
}
}
class Calculate_wrapper1 extends Calculate1
{
static function __callStatic($functionName, $attributes)
{
array_unshift($attributes, 'dog');
var_dump($attributes);
// using get_parent_class()
return call_user_func_array(array(get_parent_class(), $functionName), $attributes);
}
}
Calculate_wrapper1::Method1('String');
/* METHOD 2 Don't inherit the wrapper from Calculate. This way the methods of
Calculate itself can (must!) be public. */
class Calculate2
{
public static function Method1($type, $param)
{
echo "Retrieving call for $type with param $param.";
}
}
class Calculate_wrapper2
{
static function __callStatic($functionName, $attributes)
{
array_unshift($attributes, 'dog');
var_dump($attributes);
// using the fixed class name
return call_user_func_array(array('Calculate2', $functionName), $attributes);
}
}
Calculate_wrapper2::Method1('String');
我不确定我完全理解代码,但我认为您的问题的解决方案是使用晚期静态绑定。
但是,如果你能更具体地说明这些方法到底是做什么的,我们也许能给你一个更好的整体解决方案。
从php5.3开始,你可以使用延迟静态绑定。用static::getK()
代替self::getK()
。后期静态绑定