前言
先来看张经典的啊都给神图,感受下大量if-else的“魅力”
有时候业务上的拖拉可能要求我去写出如上的多层if-else嵌套代码,如果你碰上了一个对团队成员要求相对比较严格的主管的话,那么恭喜你,死定了……脾气比较爆的大佬可能直接就跟你说要么解决上面问题,要么收拾包袱滚蛋了。
那上述代码能否用设计模式相关解决呢,答案是:YES,可以用策略模式+工厂模式。
限于本文篇幅,上述的两种模式这边就不详细介绍了,不懂的可以直接百度,本篇博文简单粗暴,会以最暴力的代码来解决问题。
原始代码
public class Coffee {
public int getPrice(int type){
if(type==1){
System.out.println("卡布奇诺");
return 22;
}
if(type==2){
System.out.println("拿铁");
return 25;
}
if(type==3){
System.out.println("美咖");
return 20;
}
return 21;
}
}
优化后代码
策略模式
分别定义这几个咖啡
// 策略接口
public interface Coffee {
int getPrice();
}
// 三种不同咖啡的实现类
public class Cappuccino implements Coffee {
@Override
public int getPrice() {
return 22;
}
}
public class AmericanoCafe implements Coffee {
@Override
public int getPrice() {
return 20;
}
}
public class Latte implements Coffee {
@Override
public int getPrice() {
return 25;
}
}
那就可以根据type来new相应对象了,但实质还没有解决上述多if问题。
工厂模式
//咖啡工厂
public class CoffeeFactory {
private static Map<Integer,Coffee> coffeeMap=new HashMap<>();
public static Coffee buildCoffee(int type){
return coffeeMap.get(type);
}
public static void register(int type,Coffee coffee){
coffeeMap.put(type,coffee);
}
}
优化后的策略
此处会发现,每个具体的Coffee必须在初始化的时候将自身注册到这个对应的coffeeMap中,否则在buildCoffee的时候会返回null,那该如何修改呢?看下面代码
//三种不同实现类的调整
@Component
public class Cappuccino implements Coffee, InitializingBean {
@Override
public int getPrice() {
return 22;
}
@Override
public void afterPropertiesSet() throws Exception {
CoffeeFactory.register(1,this);
}
}
@Component
public class AmericanoCafe implements Coffee, InitializingBean {
@Override
public int getPrice() {
return 20;
}
@Override
public void afterPropertiesSet() throws Exception {
CoffeeFactory.register(2,this);
}
}
@Component
public class Latte implements Coffee, InitializingBean {
@Override
public int getPrice() {
return 25;
}
@Override
public void afterPropertiesSet() throws Exception {
CoffeeFactory.register(3,this);
}
}
之所以要实现InitializingBean接口是为了Spring初始化的时候,创建对应的Coffee Bean的时候将其注册到工厂map中
其他方式
1.利用三元运算符,在if else分支较少的情况下
原始代码:
public static String choice(String type){
if("Integer".equals(type)){
return "this is Integer";
}
return null;
}
优化后的代码
public static String choice(String type){
return "Integer".equals(type)?"this is Integer":null;
}
2-3的原始代码
public static String choice(String type){
if("Integer".equals(type)){
return "this is Integer";
}
if("Long".equals(type)){
return "this is Long";
}
if("String".equals(type)){
return "this is String";
}
else {
return "null";
}
}
2.传参为byte,char,short,int 的时候,可以使用switch case
public static String choice(String type) {
TypeEnum typeEnum = TypeEnum.getTypeEnumFromValue(type);
switch (typeEnum.getCode()) {
case 1:
return "this is Integer";
case 2:
return "this is Long";
case 3:
return "this is String";
default:
return "null";
}
}
3.将各种类型通过枚举方式定义
public enum TypeEnum {
NULL(-1,"null"),
INTEGER(1,"Integer"),
LONG(2,"Long"),
STRING(3,"String");
int code;
String value;
TypeEnum(int code,String value){
this.code=code;
this.value=value;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public static HashMap<String,TypeEnum> allValues=new HashMap<String, TypeEnum>(){
{
TypeEnum[] values=TypeEnum.values();
for(int i=0;i<values.length;i++){
this.put(values[i].value,values[i]);
}
}
};
public static TypeEnum getTypeEnumFromValue(String value){
if(allValues.containsKey(value)) {
return allValues.get(value);
}
return NULL;
}
}