实现此行为的最佳模式是什么?
我有很多方法,比如method_1 .. method_N,可以通过一个参数进行参数化,比如$ k。我想把它们作为静态方法放在一个类中,所以当然我可以像这样编写我的ComputationClass:
class Computation {
static function method1( $k, $otherParams ) { ... }
static function method2( $k, $otherParams ) { ... }
static function method3( $k, $otherParams ) { ... }
}
现在,由于$ k属于特定范围的值,比如{'dog','cat','mouse'},我想创建许多Computation的子类,每个可能的值都有一个。
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()。 / p>
嗯..希望足够清楚......你会如何设计这种行为? PS:我真的需要它们作为静态方法
由于
答案 0 :(得分:1)
我根本不会设计这种行为。如果你需要调用parent :: Method1('dog'),这意味着parant显然知道计算狗。您的Calculating_Dog类只是一个包含shorthands的愚蠢类。
是的,如果你向基类添加一个方法,你必须将它添加到所有其他类。
如果你有实例而不是静态类,你可以在包含计算类型的类中添加一个属性。然后,您将不需要长函数。您可以将简写函数添加到基类,并使用属性而不是参数。 您可以为此类提供受保护的构造函数,并将其传递给正确的类型。
然后,您可以创建具有不带参数的构造函数的后代,该参数将所需类型作为参数调用其父级构造函数。 然后,对这些后代进行单例引用。
这将是一种接近你想要的方式。但我需要看到或听到您实际想要达到的目标,以确定这是否是最佳解决方案。
[编辑]
您可以使用__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');
答案 1 :(得分:0)
我不确定我是否完全理解代码,但我认为您的问题的解决方案是使用Late Static Bindings。
但是,如果您可以更准确地了解这些方法的具体用途,我们可能会为您提供更好的整体解决方案。
答案 2 :(得分:0)
从php5.3开始,您可以使用Late Static Bindings.Use static::getK()
而不是self::getK()
。
Late Static Bindings