我可以写一个简单的 switch/case 语句,但是如果条件改变或添加新的馅饼,维护将并不容易,所以......
我有点卡住了,真的不知道如何封装条件和决策以减少条件之间的耦合,并允许在馅饼烹饪条件下轻松维护。
你将如何处理复杂的决策算法实现?
从 switch/case 到可维护的 OOP 的经典更改/重构是用抽象类专业化/实现替换每个条件和操作。
旧代码:
variable_t variable; // initialized elsewhere
switch(variable) {
case value1:
do_action1();
break;
case value2:
do_action2();
break;
// ...
}
新代码:
struct Actor // actor is your "abstract chef"
{
virtual ~Actor();
virtual bool matches(variable_t const v) const = 0;
virtual void do_action() = 0;
};
现在,对于每个动作和条件组合,您创建一个专业化:
struct SweedishChef: public Actor {
bool matches(variable_t const v) const override
{
return v == 1;
}
void do_action() override
{
std::cerr << "bork! bork!\n";
}
};
有了这个,客户端代码不再有任何硬编码。
客户端代码初始化:
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
代码):
// 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
}
从维护和可测试性的角度来看,这段代码更易于维护: