我有一个旧代码需要恢复生命,它使用大约10-15个布尔人在整个班级中跳舞,如下:
if (condition)
{
bool1 = true
}
if (condition)
{
bool2 = true
}
...
然后
if (bool1 == true && bool2 == true && bool3 == false)
{
do something
}
else if (bool1 == true && bool2 == false && bool3 == false)
{
do something
}
...
可以避免以这种方式编码吗?有没有更好的方法来实现这一点?也许利用地图?
我希望提高可读性和整体性能,因为这段代码长达1,000多行。
反馈后添加更具体的例子:
boolean bool1 = false, bool2 = false, bool3 = false, bool4 = false, bool5 = false,
bool6 = false, bool7 = false, bool8 = false, bool9 = false, bool10 = false;
if (string_object.startsWith("Pattern1"))
{
bool1 = true
}
if (string_object.startsWith("Pattern2")
{
bool2 = true
}
if (string_object.startsWith("Pattern3")
{
bool3 = true
}
if (string_object.startsWith("Pattern4")
{
bool4 = true
}
if (string_object.startsWith("Pattern5")
{
bool5 = true
}
// and so on...
if (system_type.equals("type1"))
{
if (bool1 == true && bool2 == true && bool3 == false)
{
system_value.set("value1")
}
else if (bool1 == true && bool2 == false && bool3 == false)
{
system_value.set("value2")
}
else if (bool1 == true && bool3 == false && bool4 == true)
{
system_value.set("value3")
}
}
else if (system_type.equals("type2"))
{
if (bool1 == true && bool2 == true && bool4 == true)
{
system_value.set("value1")
}
else if (bool1 == true && bool3 == false && bool5 == true)
{
system_value.set("value4")
}
else if (bool1 == true && bool3 == false && bool4 == true)
{
system_value.set("value5")
}
}
// and so on...
答案 0 :(得分:4)
你可以做一些事情。
正如其他人所提到的,代码如下:
if(condition) { bool1 = true; }
可以压缩为:
bool1 = (condition);
这方面的一个例子就是改变这个:
if (bool1 == true && bool2 == true && bool3 == false)
{
do something
}
else if (bool1 == true && bool2 == false && bool3 == false)
{
do something
}
对于这样的事情:
if (firstCondition())
{
do something
}
else if (secondCondition())
{
do something
}
private boolean firstCondition() {
return (bool1 && bool2 && !bool3 );
}
private boolean secondCondition() {
return (bool1 && !bool2 && !bool3);
}
分解这样的复杂条件使您的代码更易于阅读和维护。
答案 1 :(得分:1)
您可以从布尔值构造位图,并将所需组合编码为整数。
以下是一个例子:让我们说你需要三个布尔值,flag0
,flag1
和flag2
,你需要检查五种不同的旗帜组合:
flag2 flag1 flag0 Action
----- ----- ----- ----------
true false false ActionOne
true true false ActionTwo
true false true ActionThree
false false true ActionFour
false true true ActionFive
然后你可以按如下方式构建标志:
int flags = 0;
if (condition0) flags |= (1 << 0);
if (condition1) flags |= (1 << 1);
if (condition2) flags |= (1 << 2);
现在,每个条件组合都被编码为0到7之间的唯一数字,包括0和7,因此可以使用switch
语句进行检查:
switch(flags) {
case 4: actionOne(); break; // 1 0 0
case 6: actionTwo(); break; // 1 1 0
case 5: actionThree(); break; // 1 0 1
case 1: actionFour(); break; // 0 0 1
case 3: actionFive(); break; // 0 1 1
}
答案 2 :(得分:1)
大多数情况下,这种反模式是由于开发人员不希望仅为一个新行为创建子类。如果是这种情况,多态可能有所帮助。
假设您有以下课程:
public class Animal {
private final boolean isCat;
private final boolean isReptile;
private final boolean isDog;
private Animal(final boolean isCat, final boolean isReptile, final boolean isDog) {
this.isCat = isCat;
this.isReptile = isReptile;
this.isDog = isDog;
}
public static Animal getLizard() {
return new Animal(false, true, true);
}
public static Animal getDog() {
return new Animal(false, false, false);
}
public String seeStranger() {
final StringBuilder result = new StringBuilder(this.toString());
if (isDog) {
result.append(" barks and");
} else if (isCat) {
result.append(" meows and");
}
if (isReptile) {
result.append(" crawls away.");
} else {
result.append(" walks forward.");
}
return result.toString();
}
}
您真正想要的是具有不同行为的多个类:
public abstract class Animal {
public static Animal getLizard() {
return new Lizard();
}
public static Animal getDog() {
return new Dog();
}
public abstract String seeStranger();
private static class Lizard extends Animal {
@Override
public String seeStranger() {
return this.toString() + " crawls away.";
}
}
private static class Dog extends Animal {
@Override
public String seeStranger() {
return this.toString() + " barks and walks forward.";
}
}
}
答案 3 :(得分:1)
根据您的使用情况,您可能会发现更容易完全省略布尔变量,只是将条件内联在控制流语句中。例如,您可以更改此内容:
if (condition1)
{
bool1 = true
}
else if (condition2)
{
bool2 = true
}
...
if (bool1 == true && bool2 == true && bool3 == false)
{
do something
}
else if (bool1 == true && bool2 == false && bool3 == false)
{
do something
}
...
更像是这样:
if (condition1 && condition2 && condition3)
{
do something
}
else if (condition1 && (not condition2) && codition3)
{
do something
}
...
您也可以简化您的条件。例如,可能有一个condition4
等效于condition1 && condition2
但不使用&&
。考虑condition1 := x <= 100
和condition2 := x >= 100
。 condition1 && condition2
完全等同于x == 100
,我肯定会建议更改
...
bool1 = (x >= 100);
...
bool2 = (x <= 100);
...
if (bool1 == true && bool2 == true) { ... }
...
改为:
...
if (x == 100) { ... }
...
我毫不犹豫地将布尔变量明确地用作反模式,但我倾向于尽可能将布尔值保持为R值。
答案 4 :(得分:0)
在这种情况下,我建议单独使用布尔值,如果它们标记良好
但如果它们密切相关(即方向,N / S / E / W),可以做一个巧妙的事情,称为bitmasks 相关的Stack Overflow帖子:what is a bitmask and a mask
如果你有一个街道网格,它们对方向有用,每个街道交叉路口可以有N / S / E / W道路,可以定义为4位数字
让我们定义一些常量
N=1 (0001)
S=2 (0010)
E=4 (0100)
W=8 (1000)
N和E的道路交叉点为N | E
N|E=1|4=5 (0101)
满+交叉(NSEW)将是N | S | E | W
N|S|E|W=1|2|4|8=15 (1111)
如果你要添加一个位掩码,newMask = oldMask | direction
我们将S添加到我们的NE掩码
int newMask = oldMask | S
oldMask为0101,S为0010,newMask为0111
它还有一种简单的方法来检查方向是否存在
如果我们想检查oldMask是否包含N
boolean N? = (oldMask & N) != 0
oldMask&amp; N将隔离N位,使返回值为N或0