一文读懂经典设计模式—— 策略模式

1、含义

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

2、多态

在说策略模式之前说 面向对象编程三大特性中的多态;
所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。策略模式正是借助于多态这一特性。

3、组成:

1、抽象策略角色:这个是一个抽象的角色,通常情况下使用接口或者抽象类去实现。对比来说,就是我们的Comparator接口。
2、具体策略角色:包装了具体的算法和行为。对比来说,就是实现了Comparator接口的实现一组实现类。
3、环境角色:内部会持有一个抽象角色的引用,给客户端调用。对比来说,就是我们的TreeSet类。说明:TreeSet内部一定会有一个策略类的一个成员变量,这样做的目的在于可以当我们在去创建TreeSet对象的时候,可以接收我们向TreeSet类中传递的具体的策略类。

4、代码

在理解以上的内容之后,我们编写一个实现加减乘除的小Demo。从代码的角度剖析一下策略模式。

4.1 定义抽象策略角色
/**
 * @Author: LX 17839193044@162.com
 * @Description: 声明抽象策略角色
 * @Date: 20:14 2019/1/4
 * @Version: V1.0
 */
public interface Strategy {

    /**
     * @Author: LX 17839193044@162.com
     * @Description: 声明抽象策略方法  返回值、参数根据业务自行添加
     * @Date: 2019/1/4 20:15
     * @Version: V1.0
     */
    int getResult(int numOne, int numTwo);
}
4.2 定义具体策略角色

具体策略角色一:数据相加

import cn.thislx.strategy.Strategy;

/**
 * @Author: LX 17839193044@162.com
 * @Description: 具体策略角色一
 * @Date: 20:16 2019/1/4
 * @Version: V1.0
 */
public class OneStrategy implements Strategy {

    /**
     * @param numOne: 数值一
     * @param numTwo: 数值二
     * @Author: LX 17839193044@162.com
     * @Description: 具体策略实现方法一
     * @Date: 2019/1/4 20:42
     * @Version: V1.0
     */
    @Override
    public int getResult(int numOne, int numTwo) {
        // 进行相应的业务处理
        System.out.println("具体策略角色一执行,数值相加");
        return numOne + numTwo;
    }
}

具体策略角色二:数值相减

import cn.thislx.strategy.Strategy;

/**
 * @Author: LX 17839193044@162.com
 * @Description: 具体策略角色二
 * @Date: 20:16 2019/1/4
 * @Version: V1.0
 */
public class TwoStrategy implements Strategy {

    /**
     * @param numOne: 数值一
     * @param numTwo: 数值二
     * @Author: LX 17839193044@162.com
     * @Description: 具体策略实现方法二
     * @Date: 2019/1/4 20:42
     * @Version: V1.0
     */
    @Override
    public int getResult(int numOne, int numTwo) {
        // 进行相应的业务处理
        System.out.println("具体策略角色二执行,数值相减");
        return numOne - numTwo;
    }
}

具体策略角色三:数据相乘

import cn.thislx.strategy.Strategy;

/**
 * @Author: LX 17839193044@162.com
 * @Description: 具体策略角色三
 * @Date: 20:17 2019/1/4
 * @Version: V1.0
 */
public class ThreeStrategy implements Strategy {

    /**
     * @param numOne: 数值一
     * @param numTwo: 数值二
     * @Author: LX 17839193044@162.com
     * @Description: 具体策略实现方法三
     * @Date: 2019/1/4 20:42
     * @Version: V1.0
     */
    @Override
    public int getResult(int numOne, int numTwo) {
        // 进行相应的业务处理
        System.out.println("具体策略角色三执行,数值相乘");
        return numOne * numTwo;
    }
}
4.3 定义环境角色
import cn.thislx.strategy.Strategy;
import cn.thislx.strategy.impl.OneStrategy;
import cn.thislx.strategy.impl.ThreeStrategy;
import cn.thislx.strategy.impl.TwoStrategy;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: LX 17839193044@162.com
 * @Description: 环境角色  内部持有一个抽象策略角色,给客户端调用
 * @Date: 20:20 2019/1/4
 * @Version: V1.0
 */
public class Context {

    private static final String STRATEGY_ONE = "one";
    private static final String STRATEGY_TWO = "two";
    private static final String STRATEGY_THREE = "three";

    /**
     * 将全部具体策略角色放到map中。map类似于一个锦囊
     */
    public static Map<String, Strategy> strategyMap = new HashMap<String, Strategy>() {{
        put(STRATEGY_ONE, new OneStrategy());
        put(STRATEGY_TWO, new TwoStrategy());
        put(STRATEGY_THREE, new ThreeStrategy());
    }};

    /**
     * 抽象策略角色 给客户端调用
     */
    private Strategy strategy;

    /**
     * @param name: 锦囊中的key
     * @Author: LX 17839193044@162.com
     * @Description: 有参构造方法 使抽象策略角色实例化为具体策略角色
     * @Date: 2019/1/4 20:50
     * @Version: V1.0
     */
    public Context(String name) {
        strategy = strategyMap.get(name);
    }

    /**
     * @param numOne 策略角色所需要的参数(根据业务需求选择参数类型)
     * @param numTwo 策略角色所需要的参数(根据业务需求选择参数类型)
     * @Author: LX 17839193044@162.com
     * @Description: 策略角色的执行方法(调用的入口)
     * @Date: 2019/1/4 20:51
     * @Version: V1.0
     */
    public int excute(int numOne, int numTwo) {
        int result = strategy.getResult(numOne, numTwo);
        return result;
    }
}
4.4 编写测试方法
public class Main {
    public static void main(String[] args) {      
        //实际开发中一定要避免硬编码问题,在此我不再提取。
        int oneStrategyResult = new Context("one").excute(1, 2);
        System.out.println("策略一执行结果:" + oneStrategyResult);
        int twoStrategyResult = new Context("two").excute(1, 2);
        System.out.println("策略二执行结果:" + twoStrategyResult);
        int threeStrategyResult = new Context("three").excute(1, 2);
        System.out.println("策略三执行结果:" + threeStrategyResult);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
责任链设计模式是一种行为型设计模式,用于将请求的发送者和接收者解耦,使多个对象都有机会处理该请求。该模式将这些对象串成链,并沿着这条链传递请求,直到有一个对象能够处理它为止。 责任链模式的核心是定义一个处理请求的抽象类或接口,然后让多个具体的处理者对象继承或实现这个类/接口。每个具体的处理者对象都包含一个对下一个处理者对象的引用,形成一个链式结构。 当一个请求进入责任链时,责任链中的每个处理者都有机会处理该请求。如果可以处理请求,则进行处理;如果不能处理,则将请求传递给下一个处理者,直到有一个处理者能够处理它。 责任链模式的关键点是要找到合适的处理者顺序和条件。通常情况下,责任链模式适用于以下情况: 1. 有多个对象可以处理同一类型的请求,但具体由哪个对象来处理由运行时决定。 2. 不明确请求的接收者,希望请求在一个对象链中流动,直到被处理。 3. 需要动态地指定可以处理请求的对象集合。 使用责任链模式可以实现请求发送者和接收者的解耦,增加代码的灵活性和可扩展性。但同时也需要注意责任链的长度和效率问题,避免责任链过长或造成性能问题。 总结一下,责任链设计模式是一种将请求发送者和接收者解耦的设计模式,通过将多个处理者对象串成链,沿着这条链传递请求,直到有一个处理者能够处理它。这样可以增加代码的灵活性和可扩展性,适用于有多个对象可以处理同一类型请求的情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值