陈旧语法密度之七——用泛型消灭if-else if-else
原创
©著作权归作者所有:来自51CTO博客作者火星人陈勇的原创作品,请联系作者获取转载授权,否则将追究法律责任
用泛型消灭if – else if - else
消灭if-else if - else的方法多种多样,其中看似远在天边的泛型是一种方法。
这种方法多用在每个分支看上去非常相近,甚至有点眼花缭乱的情况。比如:
public class FormulaValueOld {
public enum Types {Integer, BigInteger, Float } //... 10 types
public Types type;
public Integer integerValue;
public BigInteger bigIntegerValue;
public Float floatValue;
//....10 types.
public void setValue(Object value) {
if (value instanceof Integer) {
this.type = Types.Integer;
this.integerValue = (Integer)value;
} else if (value instanceof BigInteger) {
this.type = Types.BigInteger;
this.bigIntegerValue = (BigInteger)value;
} else if (value instanceof Float) {
this.type = Types.Float;
this.floatValue = (Float)value;
} //... 10 branches.
}
public Integer integerValue() {
return integerValue;
}
public Object getValue() {
if (type.equals(Types.Integer)) {
return this.integerValue;
} else if (type.equals(Types.BigInteger)) {
return this.bigIntegerValue;
} else if (type.equals(Types.Float)) {
return this.floatValue;
} else {
return null;
}
} //... 10 types.
}
这个简单的例子来自2018年的一个Java项目,上面的类是一种“公式值”,希望能在一个类中存储10个不同类型的数值。
在这个例子中每个分支只有1~2行代码,而复杂的例子中可以达到10多行,但都具备一个特征:那就是每个分支结构非常类似。
很多人的第一直觉是可以存储在Object类型的公共值中(实际上在这个项目的其他代码中大量存在),但在getValue时,仍然不能解决需要用type来转换为实际类型的分支。
这种分支几乎完全相同的情况,应该使用泛型解决。
具体实现如下(实际代码中并不需要getValue方法,仅为示例):
public class FormulaValue<T> {
protected T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return this.value;
}
泛型的官方应用场景可以理解为:行为相同,类型不同。
尽管这是一个很容易理解的概念,然而在很多代码中极少发现除了标准库(List,Map等)之外项目自己创建的泛型类、泛型方法;反而是长相相似的switch case, if-else if-else一大堆。
这时候可以换一个表述或许更好:
泛型的应用场景可以理解为:替代行为相同,类型不同的switch case, if-else if-else。