策略+工厂设计模式替代大量if-else

前言


先来看张经典的啊都给神图,感受下大量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;
    }
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值