如何用OOP在php中实现策略模式?

时间:2019-06-06 11:17:22

标签: php

我的同事问我如何在类中动态实现方法。我想出的是策略模式。第一次,我制定了常规的策略模式,最后,我意识到使属性调用功能不是一个好主意。因为子类是控制器类,其方法需要直接调用。 因此,我正在尝试直接将Package的方法实现为B类。但是我在调​​用__call函数时被卡住了。该函数试图在B类中实现该功能。但是,对它进行扩展时,我保存在B类中的功能不起作用。


<?php

class A {
    public $once = 0;
}

class B extends A {

    public $methods = [];

    public function __construct()
    {
        //load package
        $package = new Package;
        //get method names
        $methods = get_class_methods($package);
        //loop to assign methods to class B instance
        foreach($methods as $method)
        {
            $this->methods[$method] = $this->setFunc($package, $method);
        }
    }
    //I made this function because [$package, $method] was regarded as
    // array instead of function when it is assigned to other variable
    private function setFunc($package, $methodName)
    {
        return function() use($package, $methodName)
        {
            return call_user_func([$package, $methodName]);
        };    
    }
}

//package class
class Package {
    public function hello_world(){
        return  "hello world";
    }
}

class C extends B{

    public function __construct()
    {
        parent::__construct();

        //assigning functions to class C
        foreach($this->methods as $key => $val)
        {
            //I did it in child class because dynamically produced properties
            // weren't recognized
            $this->$key = $val;
        }
    }

    //dynamically assigned functions to dynamic properties must be called by
    //__call function
    public function __call($name, $arguments)
    {
        //I made this condition because calling function loops infinitely.
        if($this->once >= 1)
        {
            return;
        } 
        $this->once++;

        //not working here. nothing shown
        return $this->$name();
    }
}

$c = new C;

echo $c->hello_world(); //I want to display hello world!

1 个答案:

答案 0 :(得分:0)

return $this->$name();替换为call_user_func($this->$name,[]); 或在php7中,此方法return ($this->$name)();