Php 如果适配器类需要类型提示怎么办?(菲律宾)
这是一个基本的、有效的例子:Php 如果适配器类需要类型提示怎么办?(菲律宾),php,adapter,Php,Adapter,这是一个基本的、有效的例子: class Test { public function test() { return 'a'; } } /** * @mixin Adapter */ class TestAdapter { /** * @var Test */ private $test; public function __construct(Test $test) { $th
class Test
{
public function test()
{
return 'a';
}
}
/**
* @mixin Adapter
*/
class TestAdapter
{
/**
* @var Test
*/
private $test;
public function __construct(Test $test)
{
$this->test = $test;
}
public function __call($method, $args)
{
switch($method)
{
case 'test' :
return 'decorated: '.$this->test();
default :
throw new \Exception('Unhandled method call: '.$method);
}
}
}
$test = new Test();
$testAdapter = new TestAdapter($test);
$testAdapter->test();
到目前为止还不错。但是如果某人需要这个测试怎么办?如果抽象出现了呢
abstract class TestAbstract
{
public abstract function t();
}
class Test extends TestAbstract
{
public function t()
{
return 't';
}
public function test()
{
return 'test';
}
}
class WannaTest
{
public function __construct(Test $test)
{
}
}
这样:
$test = new Test();
$testAdapter = new TestAdapter($test);
$wannaTest = new WannaTest($testAdapter); // would throw fatal!
这不起作用,因为WannaTest
需要Test
。
当然,我可以扩展TestAdapter
:
class TestAdapter extends Test
{
public function t()
{
// now I cant mock it!
}
}
但在这种情况下,如果我有10个抽象方法,我就必须实现它们,即使其中一个只被使用。这样我就不能用\u call
作为代理。所以有点臭。如何解决这个问题?删除typehint不是一个选项…您可以创建一个内联类,该类扩展Test
,并根据需要装饰该方法。这里有一个例子
class TestDecorator //decorator sounds more appropriate
{
public static function decorate(Test $test) {
return new class($test) extends Test {
private $test;
public function __construct(Test $test) {
$this->test = $test;
}
public function test() {
return 'decorated: '.$this->test->test();
}
};
}
}
$test = new Test();
$decorated = TestDecorator::decorate($test);
echo $decorated->test();
类型提示Test
现在应该可以工作了,因为修饰类实际上扩展了Test
这基本上是我的第二个建议,作为匿名类:)