首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >战略模式的自我选择变体?

战略模式的自我选择变体?
EN

Software Engineering用户
提问于 2022-10-05 10:31:25
回答 1查看 115关注 0票数 1

我发现这个模式很有用,我正在尝试对它进行分类或命名。基本上,这是:

  1. 任务应该通过不同的策略来执行,这取决于context
  2. 每个具体的strategy实现一个公共的interface
  3. 但是..。打电话的人不会选择策略。
  4. 相反,有一个按优先级排序的可用策略列表,每个strategy都根据context选择是否将接受(并声明)该任务。

听起来像另一个命名模式吗?或者你会怎么称呼它?

例如:

代码语言:javascript
复制
interface InvoicePublisherInterface {
    function accepts($context): bool;
    function publish($context): Result;
}

/** @var array> $publisherClasses */
$publisherClasses = [
   InvoicePublisherFranceCarrefour::class,  // Company-specific publisher - eg special business logic
   InvoicePublisherFrance::class,     // Country-specific publishers
   InvoicePublisherSpain::class,      // ...
   InvoicePublisherDefault::class,    // Fallback if no others match
];

// Find which publisher to use 
function resolveInvoicePublisher(Context $context): InvoicePublisherInterface {
    foreach($publisherClasses as $publisherClass) {
        $publisher = new $publisherClass(); // (a real implementation would reuse instances)

        if ($publisher->accepts($context)) {
            return $publisher;
        }
    }
    throw new LogicException('Could not resolve publisher');
}

...

// Here is some code that publishes invoices, but doesn't need to know how its done.

$publisher = resolveInvoicePublisher($context);

$result = $publisher->publish($context);

策略的顺序很重要,因为一种策略可能会覆盖另一种策略--例如,对于特定的上下文,FranceCarrefour发布者会凌驾于法国发布者之上:

代码语言:javascript
复制
class InvoicePublisherFrance implements InvoicePublisherInterface {
    public function accepts($context): bool { 
        return $context->country === 'france';
    }
    public function publish($context): Result {
        // do some france invoice publishing...
    }   
}

class InvoicePublisherFranceCarrefour extends InvoicePublisherFrance {
    public function accepts($context): bool { 
        return $context->country === 'france' && $context->company === 'carrefour';
    }
    ...
    //override some parts of the parent to apply company-specific business logic...
}

除了基本的策略模式之外,我还发现了一些优点:

  1. 解耦-每一种策略都可以决定它所支持的上下文。
  2. 关注点的分离--业务逻辑中的每一个奇怪的部分显然都属于这个类。
  3. 多态--作为另一个子集的策略可以根据需要继承和覆盖。

还没有我遇到过的具体缺点。

EN

回答 1

Software Engineering用户

回答已采纳

发布于 2022-10-05 14:05:56

在我看来,这种模式的意图听起来就像“四人帮”定义的“责任链”(CoR)。

其意图的正式定义:

通过给多个对象处理请求的机会,避免将请求的发送方耦合到接收方。将接收对象链接起来,并沿着链传递请求,直到对象处理为止。

在这种模式中,设置了一个处理程序链,如您的$publisherClasses。每个处理程序都决定是处理对象本身,还是将其传递给decides中的下一个处理程序。该模式并不描述处理程序应该如何决定处理或传递。

在你的问题中,你提到:“战略的顺序很重要,因为一种策略可能凌驾于另一种策略之上。”在CoR中,顺序是至关重要的。并不是一种策略可能覆盖,而是接受<#>的第一个处理程序将覆盖所有其他处理程序。

查看维基百科以获得更多信息:https://en.wikipedia.org/wiki/Chain-of-responsibility_模式

注意,责任链的结构非常类似于Decorator模式(也是GoF),但是意图完全不同。

票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/441440

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档