重构 if 语句以使用适当的模式
我有一个包含一些状态的枚举:
enum State
{
A,
B,
C,
D
}
以及一个具有相应状态的对象:
class MyObject
{
State state;
}
我需要编写一个算法,该算法采用两个 MyObject 实例并根据这些实例的特定状态执行某些操作:
void doWork(MyObject o1, MyObject o2)
{
if (o1.state == A && o2.state == A)
{
// do something
}
else if (o1.state == A && o2.state == B)
{}
// etc for all combinations...
}
显然这种方法有很多问题,我想要更改它以理想地摆脱 if/else 语句。
这样的需求有什么模式吗?
谢谢
I have an enum with some states in it:
enum State
{
A,
B,
C,
D
}
and an object that has a corresponding state:
class MyObject
{
State state;
}
I need to write an algorithm that takes two MyObject instances and does something depending on the particular states of those instances:
void doWork(MyObject o1, MyObject o2)
{
if (o1.state == A && o2.state == A)
{
// do something
}
else if (o1.state == A && o2.state == B)
{}
// etc for all combinations...
}
Obviously this approach has many problems and I would like to change it to ideally get rid of the if/else statement.
Is there any pattern for such a requirement?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
尽管我不确定它会好得多,但您可以做的是两个状态值的所有可能组合的某种矩阵;然后,您可以使用 o1.state 和 o2.state 作为该矩阵的索引。
您可以在该矩阵中存储不同的内容:
switch
块的区分值,该块将替换您的if .. else if .. else
块——实际上并没有太大的改进。或者你的矩阵可以包含...
如果你真的想摆脱
if
语句,第二个选项可能是更好的一个;但请注意,您的代码将不再像if
/switch
块那样紧密地集中在一个位置,而是分布在多个不同的位置命令对象/类。What you could do, although I'm not sure it would be that much better, is some kind of matrix of all possible combinations of two
state
values; you could then useo1.state
ando2.state
as indexes into that matrix.You could store different things in that matrix:
switch
block which would replace yourif .. else if .. else
blocks -- not much of an improvement, really.Or your matrix could contain...
If you really want to get rid of the
if
statements, that second option might be the better one; do take note, however, that your code will then no longer be close together in one location, as would be the case withif
/switch
blocks, but spread over several different command objects/classes.构建此结构的一种方法是,您可以在枚举中拥有一个抽象方法,每个元素都将实现该方法:
然后您的方法可以如下所示
One way you can structure this, is you can have an abstract method in your enum which each element would implement:
Then your method can look like
是的,它被称为...状态模式。重要的是只有一个状态可以定义行为,即您可能需要将 object1.state 和 object2.state 组合成元状态。使用 statecontext 注册此元状态,以便当 Myobject.state 更改时更新元状态。
然后,您需要在状态上下文中保存一个 MyObjectStates 对象,并在 MyObject.state 更改时更新它。您甚至可以完全删除状态枚举。如果您对这种方法感兴趣,请给我留言,如果您愿意,我会详细说明。
状态模式的优点是您不需要保存和读回枚举并相应地选择不同的代码路径,而是为您想要以不同方式处理的每个状态提供单独的代码。
Yes, it is called the... state pattern. The important thing is to only have one state for which to define behavior, i.e. you may need to combine your object1.state and object2.state into a meta-state. Register this meta-state with a statecontext so that when Myobject.state changes the meta-state is updated.
You then need to hold one MyObjectStates object in a statecontext and update it when a MyObject.state is changed. You may even be able to remove the state enum alltogether. If this approach sounds interesting to you give me a note and I elaborate if you like.
The state pattern has the advantage that you don't need to save and read back an enum and chose a different codepath accordingly, but instead you provide separate code with every state you want to handle differently.
我可能已经这样做了,它至少更具可读性
I 'd done this probably , its at least more readable
仅使用两种状态组合,嵌套开关可能是最快实现和理解的:
如果案例顺序与某些组合无关,您可以交换
o1
和o2
在这些情况下,然后将它们放入switch
(并避免重复的代码)。此外,对于具有相同行为的所有案例组合,您可以利用失败行为。最后,以这种方式实现它可能会使这些组合的实际情况变得更加明显,这样您就可以实现更智能的方法。
using only two state combinations, a nested switch is probably the quickest to implement and comprehend:
If the case order is irrelevant for certain combinations, you may be able to swap
o1
ando2
in those cases, then drop them into theswitch
(and avoid duplicate code). Also, for all the cases combinations that have the same behavior, you can take advantage of the fall through behavior.Finally, implementing it this way may make what's actually going on with those combinations a little more obvious, such that you might be able to implement a much smarter approach.
面向对象的问题解决方案是状态模式。它涉及用状态对象封装状态交替条件。您可以在此处和此处。顺便说一句,如果您还没有这本书,我强烈建议您购买它。
干杯!
The OO solution to your problem is the state pattern. It involves encapsulating state-alternating conditionals with a state object. You may find more information about the pattern here and here. By the way, i would STRONGLY suggest buying this book if you don't already own it.
Cheers!