大话设计模式:策略模式

策略模式一般用法就是一个接口有多个实现类,每个实现类都是对接口的不同实现,均代表了接口的不同实现形式,比如说,一个计算的接口,你不必在接口中定义加减乘除的抽象方法,仅需要一个抽象方法,多个实现类来实现这个接口中的抽象方法即可。

普通用法

抽象接口

/**
 * 计算接口
 *
 * @author zhangjianbing
 * time 2019/11/11
 */
public interface Calculate {

    BigDecimal doCalc(BigDecimal var1, BigDecimal var2);

}

接口的实现类

/**
 * 加法实现类{@link Calculate}
 *
 * @author zhangjianbing
 * time 2019/11/11
 */
public class CalcAdd implements Calculate {

    @Override
    public BigDecimal doCalc(BigDecimal var1, BigDecimal var2) {
        return var1.add(var2).setScale(2, BigDecimal.ROUND_HALF_UP);
    }

}
/**
 * 减法实现类{@link Calculate}
 *
 * @author zhangjianbing
 * time 2019/11/11
 */
public class CalcSub implements Calculate {

    @Override
    public BigDecimal doCalc(BigDecimal var1, BigDecimal var2) {
        return var1.subtract(var2).setScale(2, BigDecimal.ROUND_HALF_UP);
    }

}

测试类

/**
 * @author zhangjianbing
 * time 2019/11/11
 */
public class Test01 {

    public static void main(String[] args) {
        Calculate calculate1 = new CalcAdd();
        BigDecimal doCalc1 = calculate1.doCalc(new BigDecimal(1), new BigDecimal(2));
        System.out.println(doCalc1);
        System.out.println("-------------------------------------");
        Calculate calculate2 = new CalcSub();
        BigDecimal doCalc2 = calculate2.doCalc(new BigDecimal(1), new BigDecimal(2));
        System.out.println(doCalc2);
    }

}

优化if-else语句

其实感觉可读性并不强,不如直接if-else来的直接,大体思路就是:首先抽象出一个抽象类,这个抽象类的作用是规范if条件成立时候的处理逻辑,然后每一个if条件都当成一个抽象类的派生类,当遇到需要判断的条件的时候,把条件传到一个可以获取派生类的方法中,利用多态的特性,看起来仅需要一行代码就能搞定多个if,但其实,随着if的增多,代码维护以及可读性变得很低。比如:有很多种会员,不同的会员有不同的处理逻辑,举例如下。

会员枚举

/**
 * @author zhangjianbing
 * time 2019/11/11
 */
public enum MemberEnum {

    BRONZE("1", "青铜会员", "BronzeMember"),
    SILVER("2", "青铜会员", "SilverMember"),
    GOLD("3", "青铜会员", "GoldMember"),
    PLATINUM("4", "青铜会员", "PlatinumMember"),
    DIAMOND("5", "青铜会员", "DiamondMember");

    private String code;
    private String desc;
    private String name;

    MemberEnum(String code, String desc, String name) {
        this.code = code;
        this.desc = desc;
        this.name = name;
    }

    public static String getNameByCode(String code) {
        for (MemberEnum t : MemberEnum.values()) {
            if (t.getCode().equals(code)) {
                return t.name;
            }
        }
        return null;
    }


    // -----------------------------------------------------------------

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

抽象接口

/**
 * @author zhangjianbing
 * time 2019/11/11
 */
public interface IMemberService {

    void process(String message);

}

接口派生类

/**
 * @author zhangjianbing
 * time 2019/11/11
 */
public class BronzeMember implements IMemberService {

    @Override
    public void process(String message) {
        System.out.println("恭喜您," + message);
    }

}

/**
 * @author zhangjianbing
 * time 2019/11/11
 */
public class DiamondMember implements IMemberService {

    @Override
    public void process(String message) {
        System.out.println("恭喜您," + message);
    }

}

/**
 * @author zhangjianbing
 * time 2019/11/11
 */
public class GoldMember implements IMemberService {

    @Override
    public void process(String message) {
        System.out.println("恭喜您," + message);
    }

}

/**
 * @author zhangjianbing
 * time 2019/11/11
 */
public class PlatinumMember implements IMemberService {

    @Override
    public void process(String message) {
        System.out.println("恭喜您," + message);
    }

}

/**
 * @author zhangjianbing
 * time 2019/11/11
 */
public class SilverMember implements IMemberService {

    @Override
    public void process(String message) {
        System.out.println("恭喜您," + message);
    }

}

向容器中注入Bean

/**
 * @author Rednaxela
 * @Description: 向容器中注入条件判断的Bean
 * @date 2019/11/11
 * @From https://www.zhangjianbing.com
 */
@Configuration
public class BeanRegistryConfig {

    @Bean("BronzeMember")
    public BronzeMember bronzeMember() {
        return new BronzeMember();
    }

    @Bean("DiamondMember")
    public DiamondMember diamondMember() {
        return new DiamondMember();
    }

    @Bean("GoldMember")
    public GoldMember goldMember() {
        return new GoldMember();
    }

    @Bean("PlatinumMember")
    public PlatinumMember platinumMember() {
        return new PlatinumMember();
    }

    @Bean("SilverMember")
    public SilverMember silverMember() {
        return new SilverMember();
    }

}

测试类

/**
 * @author zhangjianbing
 * time 2019/11/11
 */
public class Test01 {

    public static void main(String[] args) {

        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanRegistryConfig.class);
        String name = MemberEnum.getNameByCode("1");
        IMemberService iMemberService = (IMemberService)applicationContext.getBean(name);
        iMemberService.process(name);
    }


}

总结

个人感觉策略模式的最大好处就是不改变源代码的基础上增加派生类,比如再多一个超级会员的等级,我只需要再写一个派生类就可以了,其它的代码以及用法完全不用变,缺点就是你在使用派生类的时候需要知道派生类的名字叫什么或者说判断的条件是什么,假如派生类很多,就很难维护,所谓有利有弊吧。

原文地址:https://www.cnblogs.com/zhangjianbing/p/13654982.html