簡體   English   中英

PHP 嵌套函數 OOP

[英]PHP Nesting functions OOP

我正在使用一個庫,它具有以下過程來將許多操作附加到一個事件

$action = (new EventBuilder($target))->addOperation($Operation1)->addOperation($Operation2)->addOperation($Operation3)->compile();

我不確定如何根據我需要做的事情動態添加操作。

像這樣的東西

$action = (new EventBuilder($target));

while (some event)
{
$action = $action->addOperation($OperationX);
}

$action->compile();

我需要能夠在 while 循環中動態添加操作,並在所有操作都添加后運行它。

先感謝您

您提出的解決方案將起作用。 EventBuilder 提供了所謂的Fluent Interface ,這意味着有一些方法可以返回構建器本身的實例,允許您根據需要多次調用addOperation ,然后調用compile方法來產生結果。 但是,您可以隨意忽略addOperation的返回值,只要您有一個包含最終可以調用compile的構建器實例的變量。

和我一起散步...

// Some boilerplate classes to work with
class Target
{
    private ?string $name;
    
    public function __construct(string $name)
    {
        $this->name = $name;
    }
    
    public function getName(): string
    {
        return $this->name;
    }
}

class Operation
{
    private ?string $verb;
    
    public function __construct(string $verb)
    {
        $this->verb = $verb;
    }
    
    public function getVerb(): string
    {
        return $this->verb;
    }
}

class Action
{
    private ?Target $target;
    private array   $operations = [];
    
    public function __construct(Target $target, array $operations)
    {
        $this->target     = $target;
        $this->operations = $operations;
    }
    
    /**
     * Do the things
     * @return array
     */
    public function run(): array
    {
        $output = [];
        foreach ($this->operations as $currOperation)
        {
            $output[] =  $currOperation->getVerb() . ' the ' . $this->target->getName();
        }
        
        return $output;
    }
}

以下是您的 EventBuilder 在幕后所做的基本解釋:


class EventBuilder
{
    private ?Target $target;
    private array   $operations = [];
    
    public function __construct(Target $target)
    {
        $this->target = $target;
    }
    
    /**
     * @param Operation $operation
     * @return $this
     */
    public function addOperation(Operation $operation): EventBuilder
    {
        $this->operations[] = $operation;
        
        // Fluent interface - return a reference to the instance
        return $this;
    }
    
    public function compile(): Action
    {
        return new Action($this->target, $this->operations);
    }
}

讓我們嘗試這兩種技術並證明它們會產生相同的結果:

// Mock some operations
$myOperations = [
    new Operation('Repair'),
    new Operation('Clean'),
    new Operation('Drive')
];

// Create a target
$target = new Target('Car');

/*
 * Since the EventBuilder implements a fluent interface (returns an instance of itself from addOperation),
 * we can chain the method calls together and just put a call to compile() at the end, which will return
 * an Action instance
 */
$fluentAction = (new EventBuilder($target))
                    ->addOperation($myOperations[0])
                    ->addOperation($myOperations[1])
                    ->addOperation($myOperations[2])
                    ->compile();

// Run the action
$fluentResult = $fluentAction->run();

// Traditional approach, create an instance and call the addOperation method as needed
$builder = new EventBuilder($target);

// Pass our mocked operations
while (($currAction = array_shift($myOperations)))
{
    /*
     * We can ignore the result from addOperation here, just keep calling the method
     * on the builder variable
     */
    $builder->addOperation($currAction);
}

/*
 * After we've added all of our operations, we can call compile on the builder instance to
 * generate our Action.
 */
$traditionalAction = $builder->compile();

// Run the action
$traditionalResult = $traditionalAction->run();

// Verify that the results from both techniques are identical
assert($fluentResult == $traditionalResult, 'Results from both techniques should be identical');

// Enjoy the fruits of our labor
echo json_encode($traditionalResult, JSON_PRETTY_PRINT).PHP_EOL;

Output:

[
    "Repair the Car",
    "Clean the Car",
    "Drive the Car"
]

Rob Ruchte 感謝您的詳細解釋,我沒有包括的一件事是每個操作本身都有 ->build() 調用,我需要將其移至每個 $builder 以使其工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM