设计模式--第21篇(策略模式)

一,策略模式

策略模式:

  1. 定义算法族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户;
  2. 此算法把变化的代码从不变的代码中分离出来,针对接口编程而不是类(定义策略接口),通过组合/聚合方式使用策略;

二,原理类图

在这里插入图片描述
意图: 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
适用性:
许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间/时间权衡的算法。当这些变体实现为一个算法的类层次时 ,可以使用策略模式。
算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
一个类定义了多种行为, 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。

三,实例

strategy

package com.neei.strategy;

/**
 * @param
 * @Author: AaNeei
 * @Date: 2019/10/18  22:21
 * @Description: 游学网
 * @throws:
 */
public interface Strategy {
    public Double count(Double pay);
}

CocreteStrategy

package com.neei.strategy;
/**
 * @param
 * @Author: AaNeei
 * @Date: 2019/10/18  22:22
 * @Description: 游学网
 * @throws:
 */
public class StrategyNormal implements Strategy {

    @Override
    public Double count(Double pay) {
        return pay ;
    }
}

public class StrstegyPlatinum implements Strategy {
    @Override
    public Double count(Double pay) {
        return pay * 0.98;
    }
}

public class StrstegyDiamond implements Strategy {
    @Override
    public Double count(Double pay) {
        return pay * 0.9;
    }
}

context

package com.neei.strategy;
/**
 * @param
 * @Author: AaNeei
 * @Date: 2019/10/18  22:24
 * @Description: 游学网
 * @throws:
 */
public class Context {

    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }


    public Double count(Double pay){
        return strategy.count(pay);
    }
}

调用

package com.neei.strategy;
/**
 * @param
 * @Author: AaNeei
 * @Date: 2019/10/18  22:27
 * @Description: 游学网
 * @throws:
 */
public enum CustomerType {

    NORMAL(0, "member"),

    PLATINUM(1, "vip"),

    DUAMOND(2, "vvip");

    private int index;

    private String message;

    CustomerType(int index, String message) {
        this.index = index;
        this.message = message;
    }

    @Override
    public String toString() {
        return "CustomerType{" +
                "index=" + this.index +
                ", message='" + this.message + '\'' +
                '}';
    }
}


public class StrategyFactory {

    private static Map<CustomerType,Strategy> strstegyMap = new HashMap<CustomerType,Strategy>();

    static {
        strstegyMap.put(CustomerType.NORMAL ,new StrategyNormal());

        strstegyMap.put(CustomerType.PLATINUM,new StrstegyPlatinum());

        strstegyMap.put(CustomerType.DUAMOND,new StrstegyDiamond());
    }

    private StrategyFactory() {

    }

    public static  Strategy getInstance(CustomerType type){
        return strstegyMap.get(type);
    }

}

package com.neei.strategy;

/**
 * @param
 * @Author: AaNeei
 * @Date: 2019/10/18  22:30
 * @Description: 游学网
 * @throws:
 */
public class Client {
    public static void main(String[] args) {

        Double pay = 10000D;

        Strategy strategyNormal = StrategyFactory.getInstance(CustomerType.NORMAL);
        Context contextNormal  = new Context(strategyNormal);
        System.out.println(CustomerType.NORMAL.toString() + "应付:" + contextNormal.count(pay));

        Strategy strategyPlatinum = StrategyFactory.getInstance(CustomerType.PLATINUM);
        Context contextPlatinum  = new Context(strategyPlatinum);
        System.out.println(CustomerType.PLATINUM.toString() + "应付:" +contextPlatinum.count(pay));


        Strategy strategyDuamond = StrategyFactory.getInstance(CustomerType.DUAMOND);
        Context contextDuamond  = new Context(strategyDuamond);
        System.out.println(CustomerType.DUAMOND.toString() + "应付:"+contextDuamond.count(pay));

    }
}    

四,源码分析

JDK源码中使用的策略模式,如java.util.Arrays#sort(T[], java.util.Comparator<? super T>)

// Comparator<? super T> c 策略类
public static <T> void sort(T[] a, Comparator<? super T> c) {
        if (c == null) {
            sort(a);
        } else {
            if (LegacyMergeSort.userRequested)
                legacyMergeSort(a, c);
            else
                TimSort.sort(a, 0, a.length, c, null, 0, 0);
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值