工厂+策略解决ifelse复用问题

 

最近代码之中遇到了以下问题:在我们的商城中根据活动类型计算满减金额的问题,大致代码如下:

public class orderCalculate {


    public BigDecimal getDiscount(String type) {
        BigDecimal discount = BigDecimal.ZERO;
        if(type.equals("fullDiscount")){
            //....................满减计算方法
        } else if (type.equals("platFormDiscount")) {
            //....................平台满减计算方法
        } else if (type.equals("coupon")) {
            //.....................优惠券计算方法
        }else {
            //没有优惠
        }
        return discount;
    }
}

这种处理方式的缺点在于:

1.if else的判断逻辑很复杂,代码的可读性很差

2.代码的扩展性很差,一旦添加活动会造成代码大幅度修改

3.强迫症看了很难受

基于以上,尤其是第三点,我们决定对代码进行处理

首先我们不难想到利用接口的方式对代码进行优化。首先我们定义一个公共接口 Activity和他的一些实现类

public interface Activity {
    public BigDecimal getDiscount(BigDecimal amount);

}



public class fullDiscountActivity implements Activity {
    @Override
    public BigDecimal getDiscount(BigDecimal amount) {
        BigDecimal discount=BigDecimal.ZERO;
        //计算逻辑
        return discount;
    }
}

public class coupon implements Activity {
    @Override
    public BigDecimal getDiscount(BigDecimal amount) {
        BigDecimal discount=BigDecimal.ZERO;
        //计算逻辑
        return discount;
    }
}

@Override
    public BigDecimal getDiscount(BigDecimal amount) {
        BigDecimal discount=BigDecimal.ZERO;
        //计算逻辑
        return discount;
    }

public class noActivity implements Activity {

    @Override
    public BigDecimal getDiscount(BigDecimal amount) {
        return amount;
    }
}

这样我们的getDiscount方法就变成了如下:

public BigDecimal getDiscount(BigDecimal amount,String type) {
        BigDecimal discount = BigDecimal.ZERO;
        if(type.equals("fullDiscount")){
            fullDiscountActivity fullDiscountActivity = new fullDiscountActivity();
            return fullDiscountActivity.getDiscount(amount);
        } else if (type.equals("platFormDiscount")) {
            platFormDiscount platFormDiscount = new platFormDiscount();
            return platFormDiscount.getDiscount(amount);
        } else if (type.equals("coupon")) {
            coupon coupon = new coupon();
            return coupon.getDiscount(amount);
        }else {
            //没有优惠
        }
        return discount;
    }

这里我们把每个优惠的具体实现方法放在了各自的类中,一定程度上提高了代码的可读性。接下来我们做进一步代码优化

public BigDecimal getDiscount(BigDecimal amount,String type) {
       
        Activity activity;
        if(type.equals("fullDiscount")){
            activity = new fullDiscountActivity();
        } else if (type.equals("platFormDiscount")) {
            activity = new fullDiscountActivity();
        } else if (type.equals("coupon")) {
            activity = new fullDiscountActivity();
        }else {
            activity = new noActivity();
        }
        return activity.getDiscount(amount);
    }

这样代码似乎变得含看一下了呢。但是实际上我们并没有去掉if else。我们接下来思考,我们的type字段都是放在我们的方法中处理的,我们能不能找个方法把type也作为字段传输过去,这样不就是可以去掉if else了吗。这样的话我们就需要用到工厂模式,在一个处理类中对类型进行处理并匹配到相应的活动类。

首先我们在接口中增加getType方法,为每个特定的实现类返回特定的方法

public interface Activity {
    public BigDecimal getDiscount(BigDecimal amount);

    public String getType();
}


public class coupon implements Activity {
    @Override
    public BigDecimal getDiscount(BigDecimal amount) {
        BigDecimal discount=BigDecimal.ZERO;
        //计算逻辑
        return discount;
    }

    @Override
    public String getType() {
        return "coupon";
    }
}

public class fullDiscountActivity implements Activity {
    @Override
    public BigDecimal getDiscount(BigDecimal amount) {
        BigDecimal discount=BigDecimal.ZERO;
        //计算逻辑
        return discount;
    }

    @Override
    public String getType() {
        return "fullDiscount";
    }
}


public class noActivity implements Activity {

    @Override
    public BigDecimal getDiscount(BigDecimal amount) {
        return amount;
    }

    @Override
    public String getType() {
        return "noActivity";
    }
}


public class platFormDiscount implements Activity {
    @Override
    public BigDecimal getDiscount(BigDecimal amount) {
        BigDecimal discount=BigDecimal.ZERO;
        //计算逻辑
        return discount;
    }

    @Override
    public String getType() {
        return "platFormDiscount";
    }
}

接下来我们新建活动工厂类:

该类需要处理type并且能返回对应的工厂类;

public class ActivityFactory {

    private Map<String, Activity> map;

    private ActivityFactory() {
        List<Activity> activities = new ArrayList<>();
        activities.add(new coupon());
        activities.add(new fullDiscountActivity());
        activities.add(new platFormDiscount());
        activities.add(new noActivity());

        //LIST转化为map以做匹配
        for (Activity activity : activities) {
            map.put(activity.getType(), activity);
        }
    }


    //静态内部类
    public static class Holder {
        public static ActivityFactory instance = new ActivityFactory();
    }

    //单例方法
    public ActivityFactory getInstance() {
        return Holder.instance;
    }

    //获取对应的活动类
    public Activity getActivity(String type) {
        return map.get(type);
    }



}

该类主要实现了以下功能:

1.私有化构造方法,并通过getInstance获取实例来实现单例模式;

2.静态内部类加载对象

3.构造方法中把所有的活动对象根据type作为key存入map中

4.getActivity方法通过map匹配到对应的activity对象并返回

这样,我们就可以高兴的(for处女座)的来写我们的getDiscount方法了,是不是很简洁。

public BigDecimal getDiscount(BigDecimal amount,String type) {
        Activity activity =ActivityFactory.getInstance().getActivity(type);
        return activity.getDiscount(amount);
    }
发布了8 篇原创文章 · 获赞 3 · 访问量 282

猜你喜欢

转载自blog.csdn.net/qq_33146819/article/details/103729513