在之前的简单工厂模式中,使用了工厂方法来构建不同的算法实现类。在工厂类中使用了if语句,定义了许多的if规则来判断具体要构造哪个算法实现类,这样调用类无需知道要创建具体的哪个算法实现类。
但在工厂类中仍旧有许多if的分支,怎样消灭这些if呢?
在jdk5.0引入的枚举类型,似乎可以派上用场。
枚举类型可以在一个对象只生成特定的几种对象时候用,每个生成的对象只是单例的时候用。
在这里,可以将各种规则定义为枚举对象,实现规则的复用:
public enum CaculateType {
ADD('+') {
public Caculation getOpObject() {
return new OpAdd();
}
},
SUB('-') {
public Caculation getOpObject() {
return new OpSub();
}
},
DIV('/') {
public Caculation getOpObject() {
return new OpDiv();
}
},
MUL('*') {
public Caculation getOpObject() {
return new OpMul();
}
};
private char op;
private CaculateType(char op) {
this.op = op;
}
public char getOp() {
return op;
}
public abstract Caculation getOpObject();
public static Caculation getCaculation(char op) {
for (CaculateType type : CaculateType.values()) {
if (type.getOp() == op) {
return type.getOpObject();
}
}
return null;
}
}
这样,在使用时,通过枚举类的方法就可以了:
Caculation caculation = CaculateType.getCaculation(operator.charAt(0));
caculation.setNumberA(getNumber(numberA));
caculation.setNumberB(getNumber(numberB));
System.out.println("Result is:"+caculation.caculate());
照旧,列出相互的耦合关系:
调用类 | 枚举类 | 抽象类 | 具体算法实现类 | |
调用类 | 耦合 | 耦合 | ||
枚举类 | 耦合 | 耦合 | ||
抽象类 | ||||
具体算法实现类 | 继承 |
可以发现,耦合关系上,枚举类取代了工厂类的作用。
引入枚举类的优点:
- 规则的可复用
- 避免if代码,只要扩展枚举类就可以扩展规则(高可扩展性)
- 使用枚举类决定使用何种算法时,同样可扩展
对于范围字段,同样可以使用枚举定义规则:
public interface CheckUsable {
public boolean isOK(int value);
}
枚举类实现此接口,并进行检查:
public enum NumberState implements CheckUsable{
SMALL(1,100){
public boolean isOK(int value){
if(1<value&&value<=100){
return true;
}
return false;
}
},BIG(101,Integer.MAX_VALUE){
public boolean isOK(int value){
if(value>100){
return true;
}
return false;
}
};
private int min;
private int max;
private NumberState(int max , int min) {
this.max = max;
this.min = min;
}
/**
* 也可以不返回此State,可以直接返回在何种枚举类型下的算法类
* @param value
* @return
*/
public static NumberState checkProper(int value){
NumberState Estate = null;//也可以设为default的那个
for(NumberState state: NumberState.values()){
if(state.isOK(value)){
Estate = state;
}
}
return Estate;
}
}
OK,一切都是可复用的
实际上,对于避免if的高扩展类,还可使用状态模式,以后我再研究...