首先,我想说我在重构方面没有太多经验,也不知道这是否是偏离主题的。
我正在使用给定代码,其中使用了许多布尔属性,由于可读性,我想避免使用它,而且我不知道如何以正确的方式处理它。
class MyClass(){
boolean a;
...
void function(){
...
a = true;
...
}
void anotherFunction(){
...
if(a == true){
//do something
} else {
//do something else
}
...
}
...
}
boolean a
用于多个function
,其中anotherFunction
正在运行与a
相关的代码。由于在anotherFunction
中使用了多个属性和局部变量,因此很难理解代码和依赖关系,而且我很难重构它。重构的努力可能非常高。
我总是试图避免使用这样的布尔值,因为在我看来这不是一个好习惯。如果我错了,请不要犹豫,纠正我。
现在我想知道我是否应该重构代码并花费精力?在这种情况下是否可以使用某种模式?
答案 0 :(得分:6)
您可以使用状态模式。根据单独的抽象State
类中的布尔变量封装状态和行为。当布尔值设置为false时,将状态更改为FalseState
(扩展State
)的实例,并委托给此FalseState
实例。当布尔值设置为true时,将状态更改为TrueState
的实例,并委托给此TrueState
实例。
例如,以下类
public class Apple {
private boolean fresh = false;
public String getColor() {
if (fresh) {
return "green";
}
else {
return "brown";
}
}
public void setFresh(boolean fresh) {
this.fresh = fresh;
}
}
可以重构为
public class Apple {
private AppleState state = new OldAppleState();
public String getColor() {
return state.getColor();
}
public void setFresh(boolean fresh) {
this.state = state.nextState(fresh);
}
private static abstract class State {
public abstract State nextState(boolean fresh);
public abstract String getColor();
}
private static class OldAppleState extends State{
public State nextState(boolean fresh) {
return fresh ? new FreshAppleState() : this;
}
public String getColor() {
return "brown";
}
}
private static class FreshAppleState extends State{
public State nextState(boolean fresh) {
return fresh ? this : new OldAppleState();
}
public String getColor() {
return "green";
}
}
}
我使用了内部类,但你当然可以使用顶级类。
答案 1 :(得分:2)
您提供的代码示例显然有些截断,但我觉得这个类的行为类似于state machine。
如果类中有许多布尔属性,并且它们都确定了该函数中方法的行为,那么很快就会出现大量可能性,并且代码变得难以理解 - 最终会得到代码像:
if (true == a && false == b){
...
}
elseif (false == a && false == b){
....
}
等等。
您可以应用的第一个重构是创建状态查找方法;这会将上面的代码转换为:
if (aNotB == getState(a, b)){
....
}
elseif (notANotB == getState(a, b)){
...
}
这使得代码变得更容易,并迫使您根据应用程序的状态进行思考,而不是单个布尔值。
如果需要,您可以转到完整的状态机 - 对于大多数编程语言,遍布整个网络的参考实现。
答案 2 :(得分:2)
如果多次使用布尔a,我更喜欢类似monad的内部类函数。
public class BoolAHandler{
public bool A = false;
public BoolAHandler IfTrue(Action act){
if(A){
act();
}
return this;
}
public BoolAHandler IfFalse(Action act){
if(!A){
act();
}
return this;
}
}
用法:
boolAHandler.IfTrue( () => { doFunctionA(); } )
.IfFalse( () => { doFunctionB(); } );
当然,如果布尔a有意义,你也可以调整它的含义。如果它处理已发布状态,您可以将IfTrue
更改为IfAlreadyPublished
,将IfFalse
更改为IfNotPublished
。
答案 3 :(得分:1)
考虑国家转型的逻辑至关重要。我会更进一步,使用枚举清晰地定义你的状态。
public enum AppState {
ST1(false, false),
ST2(false, true),
ST3(true, false),
ST4(true, true);
private Boolean x, y;
}
使用枚举的一个特别有用的优点是能够定义模板方法 - Template methods using enums。将让您简化您的功能以匹配您的状态,并使其更加面向对象。