具有匿名功能关闭的策略模式

时间:2018-08-07 20:32:04

标签: php functional-programming closures anonymous-function strategy-pattern

我想在PHP中使用闭包实现Stategy模式。使用闭包的主要优点是通过创建其他类来减少所需的样板代码和代码。通常,模式如下所示:

interface StateDiscountCalculatorInterface
{
    public function calculateDiscount($amount);
}


class NewYorkStateStrategy implement StateDiscountCalculatorInterface
{
    public function calculateDiscount($amount)
    {
        // .... about 20 lines of code
    }
}

class CaliforniaStateStrategy implement StateTaxCalculatorInterface
{
    public function calculateDiscount($amount)
    {
       // .... about 20 lines of code that's different from New York State Strategy
    }
}

class stateTaxContext
{
    private $stategy;

    public function setStrategy(StateDiscountCalculatorInterface $strategy)
    {
        $this->strategy = $strategy;
    }

    public function getDiscount(array $amount)
    {
        return $this->strategy->calculateDiscount($amount);
    }

}

以下版本带有一个实现php功能接口的闭包。这是正确的方法吗?

interface StateDiscountCalculatorInterface
{
    public function calculateDiscount($amount);
}


class stateTaxContext
{
    private $newYorkStateStrategy;
    private $californiaStateStrategy;
    private $state;

    public function __construct()
    {
        $this->newYorkStateStrategy = function () implements StateDiscountCalculatorInterface {
            ...NewYorkStateStrategy class is replaced with code here
        };

        $this->californiaStateStrategy = function () implements StateDiscountCalculatorInterface {
            ...CaliforniaStateStrategy class is replaced with code here
        };
    }

    public function getDiscount(array $amount)
    {
        if($this->state==='california')
        {
            $this->californiaStateStrategy->calculateDiscount($amount);
        }
    }

}

1 个答案:

答案 0 :(得分:0)

我不是设计模式专家,但是在我看来,实现策略模式的最佳方法之一是以下几种-您可以按原样保留接口和策略类,但是实现如下上下文:

class StateTaxContext
{
    private $state;

    public function setState(StateDiscountCalculatorInterface $state)
    {
        $this->state = $state;
    }

    public function getDiscount(array $amount)
    {
        return $this->state->->calculateDiscount($amount);
    }
}

然后您可以在代码中的任何地方使用这种模式,如下所示:

$context = new StateTaxContext();

// Calculate NY discount?
$context->setState(new NewYorkStateStrategy());
$data = $context->getDiscount($amount);

// Calculate California discount?
$context->setState(new CaliforniaStateStrategy());
$data = $context->getDiscount($amount);