设计模式之策略模式

Strategy design pattern

策略模式的概念、策略模式的结构、策略模式的优缺点、策略模式的使用场景、策略模式的实现示例、策略模式的源码分析


1、策略模式的概念

  策略模式,即定义一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的用户。策略模式属于对象行为模式,它通过对算法进行封装,使把使用算法的责任和算法的实现分离开来,并委托给不同的对象对这些算法进行管理。

2、策略模式的结构

  • 抽象策略角色:定义算法的行为,通常是接口或抽象类。
  • 具体策略角色:实现抽象策略,实现其定义的算法行为。
  • 上下文类:持有一个策略的引用,以委托的方式调用策略中算法的行为,并将其暴露给外部。

strategy-class

3、策略模式的优缺点

  • 优点:
    • 算法(策略)可以自由切换。
    • 避免使用 if else 等多重条件判断。
    • 扩展性良好。
  • 缺点:
    • 当策略过多时会导致系统类爆炸。
    • 所有策略类都需对外暴露。

4、策略模式的使用场景

  • 当系统需要动态的在几种算法中选择一种时,可将每个算法封装到策略类中。
  • 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支用策略类代替。
  • 系统中算法彼此完全独立,且要求对用户隐藏算法的具体实现细节时。
  • 多个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择要执行的行为。

5、策略模式的实现示例

抽象策略类:

public interface Equipment {

    /**
     * 定义算法
     */
    void equipment();
}

具体策略一:

public class OneEquipment implements Equipment {

    @Override
    public void equipment() {
        System.out.println("明朗之靴 德拉克撒的慕刃 赛瑞尔达的怨恨 幽梦之灵 夜之锋刃 守护天使");
    }
}

具体策略二:

public class TwoEquipment implements Equipment {

    @Override
    public void equipment() {
        System.out.println("水银之靴 星蚀 贪欲九头蛇 死亡之舞 玛莫提乌斯之噬 黑色切割着");
    }
}

上下文:

public class Context {

    private Equipment equipment;

    public Context(Equipment equipment) {
        this.equipment = equipment;
    }

    public void setEquipment(Equipment equipment) {
        this.equipment = equipment;
    }

    public void equipment() {
        this.equipment.equipment();
    }
}

测试:

public class StrategyTest {

    public static void main(String[] args) {
        Context client = new Context(new OneEquipment());
        client.equipment();

        client.setEquipment(new TwoEquipment());
        client.equipment();
    }
}

测试结果:

明朗之靴 德拉克撒的慕刃 赛瑞尔达的怨恨 幽梦之灵 夜之锋刃 守护天使
水银之靴 星蚀 贪欲九头蛇 死亡之舞 玛莫提乌斯之噬 黑色切割着

6、策略模式的源码分析

  spring security 中的 SecurityContextRepository 类的设计就用到了策略模式。其定义了操作 SecurityContext 的各种方法,然后交由子实现类去实现具体的操作细节。这是典型的策略模式的应用,同样,SessionRegistory 也用到了策略模式。

public interface SecurityContextRepository {
	@Deprecated
	SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder);

	default Supplier<SecurityContext> loadContext(HttpServletRequest request) {
		return () -> loadContext(new HttpRequestResponseHolder(request, null));
	}

	void saveContext(SecurityContext context, HttpServletRequest request, HttpServletResponse response);

	boolean containsContext(HttpServletRequest request);
}

  其子实现类 HttpSessionSecurityContextRepository、NullSecurityContextRepository、RequestAttributeSecurityContextRepository 等都是具体的策略类,当然我们也可以自定义策略类,如在实现分布式权限认证时。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值