设计模式策略,可以访问父类

时间:2015-01-09 08:48:01

标签: php oop interface strategy-pattern implements

我想使用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;
    }
}

这两种解决方案都有效,但如果这是实现我想要的想法的最佳方式,我会感到有些困惑。它看起来非常像一种解决方法,但不像真正的面向对象编程。

我期待你的想法。

1 个答案:

答案 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()对象

您无需猜测涉及哪些属性名称或传递的对象具有什么结构。