我有以下代码:
if (book.type == A) do_something();
else if (book.type == B) do_something_else();
....
else do so_some_default_thing.
只要有新书类型,就需要修改此代码 或删除书籍类型时。我知道我可以使用枚举并使用开关 声明。是否有一种设计模式可以删除if-then-else?
这种模式比使用switch语句有什么好处?
答案 0 :(得分:6)
您可以为每种类型的书制作不同的课程。每个类都可以实现相同的接口,并重载一个方法来执行必要的特定于类的逻辑。
我不是说这一定更好,但它是一种选择。
答案 1 :(得分:6)
正如其他人所指出的,虚拟功能应该是您的首选。
如果由于某种原因,这对你的设计没有意义/效果,另一种可能性是使用book {type}作为键和指向函数的指针(或者functor,std::map
作为相关的值,所以你只需要查找特定类型的动作(这几乎是有多少OO语言在引擎盖下实现它们的等效虚函数)。
答案 2 :(得分:2)
每种不同类型的书都是父类的不同子类,每个类实现一个具有相同接口的方法do_some_action()
。您希望执行操作时调用该方法。
答案 3 :(得分:1)
是的,它被称为循环:
struct BookType {
char type;
void *do();
};
BookType[] types = {{A, do_something}, {B, do_something_else}, ...};
for (int i = 0; i < types_length; i++) {
if (book.type == types[i].type) types[i].do(book);
}
为了更好的方法,如果do_something,do_something_else等是Book的方法,那就更加优先了,所以:
struct Book {
virtual void do() = 0;
};
struct A {
void do() {
// ... do_something
}
};
struct B {
void do() {
// ... do_something_else
}
};
所以你只需要这样做:
book.do();
答案 4 :(得分:1)
那些if-then-else-if
构造是我最敏感的宠物之一。我发现很难想象一个不那么富有想象力的设计选择。但足够了。关于它可以做些什么。
我已经使用了几种设计方法,具体取决于要采取的行动的确切性质。
如果可能性很小且未来扩展不太可能,我可能只使用switch语句。但我相信你并没有一直到SOF听到一些无聊的东西。
如果操作是赋值,那么表驱动方法允许未来增长而不实际进行代码更改。只需添加和删除表条目即可。
如果操作涉及复杂的方法调用,那么我倾向于使用Chain of Responsibility设计模式。我将构建一个对象列表,每个对象都知道如何处理特定案例的操作。
您将要处理的项目交给第一个处理程序对象。如果它知道如何处理该项目,则执行该操作。如果没有,则将项目传递给列表中的下一个处理程序。这将一直持续到项目被处理或它落入清理或打印错误或其他任何内容的默认处理程序。维护很简单 - 您可以在列表中添加或删除处理程序对象。
答案 5 :(得分:0)
您可以为每种书籍类型定义子类,并定义虚拟函数do_something
。每个子类A
,B
等都会调用自己的do_something
版本,然后do_some_default_thing
成为基础中的do_something
方法类。
无论如何,只是一种可能的方法。你必须评估它是否真的让你更容易......
答案 6 :(得分:0)
Strategy Design Pattern是我认为你需要的。
答案 7 :(得分:0)
作为为每本书设置不同课程的替代方法,请考虑从书籍类型中选择map
作为指针。然后你的代码看起来像这样(抱歉伪代码,这几天C ++不是我的指尖):
if book.type in booktypemap:
booktypemap[book.type]();
else
defaultfunc();