我想使用php实现策略设计模式:
interface dummy_function {
public function render();
}
class a implements dummy_function {
public function render() {
echo "class a\n";
// I want to acess x_main::dummy like: echo parent::dummy
}
}
class b implements dummy_function {
public function render() {
echo "class b\n";
// I want to acess x_main::dummy like: echo parent::dummy
}
}
class x_main {
public $dummy = "hello world";
public function setX_Function( dummy_function $funcname ) {
$this->x_function = $funcname;
}
public function render() {
$this->x_function->render();
}
}
$test = new x_main();
$test->setX_Function( new a() );
$test->render();
在我的类中,我想访问主类中定义的一些方法和变量。不幸的是,父母"无法访问类中的内容" x_main"在实现类中。
我找到的方法是将$ this作为参数提供给方法"渲染",如:
class x_main {
[...]
public function render() {
$this->x_function->render( $this );
}
}
class a implements dummy_function {
public function render( $mainclass ) {
echo "class a\n";
echo $mainclass->dummy;
}
}
我测试的下一个方法是将变量从类main直接设置为已实现的函数,如:
class x_main {
[ ... ]
public function setX_Function( dummy_function $funcname ) {
$this->x_function = $funcname;
$this->x_function->dummy = $dummy;
}
}
class a implements dummy_function {
public function render() {
echo "class a\n";
echo $this->dummy;
}
}
这两种解决方案都有效,但如果这是实现我想要的想法的最佳方式,我会感到有些困惑。它看起来非常像一种解决方法,但不像真正的面向对象编程。
我期待你的想法。
答案 0 :(得分:2)
重申上述评论:
这两个类没有任何关联,他们肯定没有 父母关系。一个对象持有另一个对象的实例 并不意味着这两个对象与之有任何关系 另一个。您只需要将数据明确传递到您的 dummy_function实例;例如:
public function render(array $data).
响应:
在我的第一个解决方案中,我把整个mainclass作为参数 渲染功能。所以这是一个无论如何都可以使用的解决方案。但 如果这两个对象之间肯定没有关系我 通过直接设置参数来选择我的第二个解决方案
$this->x_function->dummy = $dummy;
很抱歉告诉你,那里你错了。在对象上隐式设置属性绝不是定义的接口。而且我没有在PHP的interface
关键字的意义上使用这个词,我的意思是广义上的指定两段代码如何交互和合作。
您已经为interface
函数指定和使用render()
做得很好,这极大地减少了代码耦合并提高了灵活性和可测试性。现在你通过使用未定义和脆弱的属性赋值再次破坏它。
您需要将传递到接口规范的render
方面部分。例如:
interface dummy_function {
public function render(array $data);
}
或者:
interface dummy_function {
public function setData(array $data);
public function render();
}
或更好:
interface DummyData {
/**
* @return string
*/
public function getDummyData();
}
interface DummyRenderer {
public function render(DummyData $data);
}
有了这个,你就是:
string
)render()
可以访问此类数据的位置(它将收到一个DummyData
方法的getDummyData()
对象您无需猜测涉及哪些属性名称或传递的对象具有什么结构。