首先要感谢大佬 杭州-java-牧头
的倾囊教授
大佬的博客地址:http://googlevip8.com/
平常使用过程中我们对于enum
很少使用,实际上枚举有很多用处,下面是一个关于用枚举代替if-else的一个案例。可以让你的代码更具可扩展性,减少加班改需求的可能。
下面是一个关于加减乘除四则运算的设计
一般的写法是if-else
If-else方式
public class IfElse的方式 {
public static void main(String[] args) {
int leftNum = 1;
int rightNum = 2;
int result = 0;
String start = "*";
if (start != null) {
if (start.equals("+")) {
result = leftNum + rightNum;
} else if (start.equals("-")) {
result = leftNum - rightNum;
} else if (start.equals("*")) {
result = leftNum * rightNum;
} else if (start.equals("/")) {
result = leftNum / rightNum;
}else {
throw new IllegalArgumentException("不支持该运算");
}
}else {
throw new NullPointerException(" start 运算符不能为空");
}
}
}
策略模式+工厂模式
import java.util.HashMap;
import java.util.Map;
public class 加减乘除策略模式加工厂模式Map {
private final static Map<String, ParentStart> map;
static {
map = new HashMap<>();
map.put("+", new Plus());
map.put("-", new Subtract());
map.put("*", new Multiply());
map.put("/", new Divide());
map.put(null, new MyException());
}
public static void main(String[] args) {
int leftNum = 1;
int rightNum = 2;
int result = 0;
String start = "*";
result = map.getOrDefault(start, new MyException()).run(leftNum, rightNum);
System.out.println(result);
}
}
/**
* 策略模式 中的父级
*/
abstract class ParentStart {
/**
*
* @param leftNum 运算符左边的操作数
* @param rightNum 运算符右边的操作数
* @return 计算后的结果
*/
int run(int leftNum, int rightNum);
}
/**
* 策略模式中的加的方法
*/
class Plus extends ParentStart {
@Override
int run(int leftNum, int rightNum) {
return leftNum + rightNum;
}
}
/**
* 策略模式中的减的方法
*/
class Subtract extends ParentStart {
@Override
int run(int leftNum, int rightNum) {
return leftNum - rightNum;
}
}
/**
* 策略模式中的乘的方法
*/
class Multiply extends ParentStart {
@Override
int run(int leftNum, int rightNum) {
return leftNum * rightNum;
}
}
/**
* 策略模式中的除的方法
*/
class Divide extends ParentStart {
@Override
int run(int leftNum, int rightNum) {
return leftNum / rightNum;
}
}
/**
* 策略模式中的非法操作
*/
class MyException extends ParentStart {
@Override
int run(int leftNum, int rightNum) {
throw new IllegalArgumentException("运算符不存在");
}
}
枚举方式+策略模式(推荐使用)
import java.util.HashMap;
import java.util.Map;
public class Enmu枚举方式 {
private final static Map<String, String> map;
static {
map = new HashMap<>();
map.put("+", "ADD");
map.put("-", "SUBTRACT");
map.put("*", "MULTIPLY");
map.put("/", "DIVIDION");
}
public static void main(String[] args) {
int leftNum = 1;
int rightNum = 2;
int result = 0;
String option= "*"; // 运算操作
String strategy = map.getOrDefault(option, "EXCEPTION");// 得到策略
result = CalculateEnum .valueOf(strategy).calculate(leftNum, rightNum);// 根据策略调用得到对应枚举,调用对应的方法得到计算的结果
System.out.println(result); // 打印计算后的结果
}
}
enum CalculateEnum {
ADD {
@Override
public int calculate(int leftNum, int rightNum) {
return leftNum + rightNum;
}
},
SUBTRACT {
@Override
public int calculate(int leftNum, int rightNum) {
return leftNum - rightNum;
}
},
MULTIPLY {
@Override
public int calculate(int leftNum, int rightNum) {
return leftNum * rightNum;
}
},
DIVIDION {
@Override
public int calculate(int leftNum, int rightNum) {
return leftNum / rightNum;
}
},
EXCEPTION {
@Override
public int calculate(int leftNum, int rightNum) {
throw new IllegalArgumentException("运算操作不支持");
}
};
/**
* 将操作数 leftNum,rightNum 运算得到新值
* return 计算后的结果值
*/
int calculate(int leftNum, int rightNum);
}
各种方式的优缺点
从代码量来说if-else的代码量是更少,但是if-else的代码会导致业务逻辑不具备可变性。
需求改变时会导致直接修改源代码。
if-else方式
:如果添加一个求余运算会导致直接修改if-else分支添加一个分支。如果需求多时会导致很多分支,代码看起来非常难受。
策略+工厂方式
:通过子类重写父类抽象方法可以扩展需求,有多少个功能就需要多少个子类。这种方式缺点就是子类太多,不方便管理
枚举 + 策略
:通过修改枚举,增加策略,实际和第二种差不多,但是比第二种方式更具灵活性。
第二种和第三种方式都起到了简化的作用,原先需要用if-else写一长串的代码,现在我们通过枚举或者工厂,简化成几行代码,主要是看起来很清晰(相当于起到了封装的作用)。