首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >决策,复杂的条件和规划,易于维护

决策,复杂的条件和规划,易于维护
EN

Stack Overflow用户
提问于 2014-09-29 17:28:45
回答 2查看 219关注 0票数 4

我正在尝试找到一种优雅的方法来实现决策算法,使其易于维护,因为决策的条件可能会经常变化。

我将尝试在这里举一个更具体的例子:

假设我正试图在一家餐厅的厨房里管理一个厨师团队。

每个厨师都会做3种馅饼:苹果派、南瓜派和覆盆子派,还有2种披萨:芝士披萨和培根披萨。他们都知道怎么做饭。

现在,我想向这些主管下达命令,告诉他们客户会得到什么。

这些条件包括:

头儿一次只能做一个派。例如,如果我命令一个厨师做一个苹果派,我不能命令他做一个覆盆子派或南瓜派,除非苹果派已经做好了,或者我发送了一个取消苹果派的请求。

我可以让一个厨师一次做5个披萨,因为它是为不同的客户准备的。

我想创建一个算法,返回我被允许发送给特定厨师的订单集,关于他已经在做的东西。

我和c++一起工作。我可以写一个简单的switch/case语句,但是如果条件改变或者添加了新的pie,那么维护起来就不容易了,所以...

我有点卡住了,真的看不出我可以如何封装条件和决策,以减少耦合的条件,并允许容易维护的条件,馅饼烹饪。

您将如何处理复杂决策算法实现?

EN

回答 2

Stack Overflow用户

发布于 2014-09-29 17:46:57

我可以写一个简单的switch/case语句,但是如果条件改变或者添加了新的pie,那么维护起来就不容易了,所以...

我有点卡住了,真的看不出我可以如何封装条件和决策,以减少耦合的条件,并允许容易维护的条件,馅饼烹饪。

您将如何处理复杂决策算法实现?

从switch/case到可维护的OOP的经典更改/重构是将每个条件和操作替换为抽象类专门化/实现。

旧代码:

代码语言:javascript
复制
variable_t variable; // initialized elsewhere
switch(variable) {
case value1:
    do_action1();
    break;
case value2:
    do_action2();
    break;
// ...
}

新代码:

代码语言:javascript
复制
struct Actor // actor is your "abstract chef"
{
    virtual ~Actor();
    virtual bool matches(variable_t const v) const = 0;
    virtual void do_action() = 0;
};

现在,对于每个操作和条件组合,创建一个专门化:

代码语言:javascript
复制
struct SweedishChef: public Actor {
    bool matches(variable_t const v) const override
    {
         return v == 1;
    }

    void do_action() override
    {
         std::cerr << "bork! bork!\n";
    }
};

这样,客户端代码就不再有任何硬编码。

客户端代码初始化:

代码语言:javascript
复制
std::vector<std::unique_ptr<Actor>> actors;
actors.emplace_back( new SweedishChef{} };
// adding a new type of chef simply means adding _one_ line of
// code here, for the new type

决策代码(替换旧的switch代码):

代码语言:javascript
复制
// using std::find, begin, end
variable_t variable; // initialized elsewhere
const auto chef = find(begin(actors), end(actors),
    [&v](const std::unique_ptr<Actor>& a) { return a->matches(v); });

if(chef != end(actors))
    chef->do_action();
else
{
    // here goes whatever was in the default part of the switch code
}

从维护和可测试性的角度来看,这段代码的可维护性要好得多:

添加新的chef时,客户端代码的

  • 更改最少

  • 厨师和命令之间的交互已经在接口

后面形式化(和冻结)

  • 每个条件/操作都可以(也应该)单独测试

  • 可以单独测试调度机制(并使用模拟的注入执行器,用于命中各种情况)。

  • 可以单独测试初始化机制
票数 4
EN

Stack Overflow用户

发布于 2014-09-29 18:12:23

不是的。这对于编码来说太多了。只需计算符号即可。这种类型的编码不能保证为"new SweedishChef{}“清除内存释放。并且客户端大小在变量声明中变得更长。

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

https://stackoverflow.com/questions/26096632

复制
相关文章

相似问题

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