策略模式

策略模式简介

1.策略模式的定义: 定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
2.策略模式举例: 先举个简单的例子:不通年纪的人买保险的需求不一样,买保险的时候一般会根据人的情况来买的。给儿童买保险是为了保护他快乐成长,给中年人买保险是为了财产安全,给老年人买保险是为了生病时候不会损失过大。 面对的情况,如果我们把所有的打折可能性都写到 if/else 里面,那只要有新的人群需求(比如青年人群)出现我们就会去改动这块的代码,我们都知道只要修改代码就有可能会引入新的问题,为了避免修改代码带来新的问题 我们可以使用策略模式来解决。

策略模式的结构和代码示例

1.策略模式的结构图
在这里插入图片描述
 Strategy: 抽象策略类,用来约束一系列具体的策略算法。Context使用这个接口来调用具体的策略实现定义的算法。
 ConcreteStrategy: 具体的策略实现,也就是具体的算法实现。
 Context: 上下文,负责和具体的策略类交互。通常上下文会持有一个真正的策略实现。
 
 2.使用策略模式编写上面买保险的案例
先定义一个接口,这个接口就是抽象策略类,该接口定义了买保险的方法,具体的实现由具体的策略类来完成.

package com.i2fly.strategy;

//策略接口
public interface InsuredStrategy {
	//定义的抽象算法方法 来约束具体的算法实现方法  买保险
	public void buyInsures();
}

针对不同的人群,定义三种具体的策略类来买保险,以下几个类体现了封装变化的设计原则,不同的人群有不同的买保险策略,它们之间相互没有影响。

package com.i2fly.strategy;

public class ChildInsuredStrategy implements InsuredStrategy {
	// 儿童购买保险的具体方法
	@Override
	public void buyInsures() {
		System.out.println("购买儿童保险,保障儿童快乐成长。。。");
	}

}

package com.i2fly.strategy;

public class MiddleAgedInsuredStrategy implements InsuredStrategy{
	//中年人购买保险的具体方法
	@Override
	public void buyInsures() {
		System.out.println("中年人购买保险,保障家庭财产安全。。。。");
	}

}

package com.i2fly.strategy;

public class OldInsuredStrategy implements InsuredStrategy {
	//老年人购买保险的具体方法
	@Override
	public void buyInsures() {
		System.out.println("老年人购买保险,保障身体生病花钱少。。。。");
	}
}

上下文定义

package com.i2fly.strategy;

//策略上下文
public class InsuredStrategyContext {
	//持有一个策略实现的引用
	private InsuredStrategy insuredStrategy;
	
	public void excuteBuyInsures(){
		//调用策略实现的方法   这里执行买保险的动作
		insuredStrategy.buyInsures();
	}

	public InsuredStrategyContext(InsuredStrategy insuredStrategy) {
		this.insuredStrategy = insuredStrategy;
	}
}

测试类

package com.i2fly.strategy;

public class Client {
	public static void main(String[] args) {
		InsuredStrategyContext insuredStrategyContext;
		System.out.println("要给小孩买保险");
		insuredStrategyContext = new InsuredStrategyContext(new ChildInsuredStrategy());
		
		insuredStrategyContext.excuteBuyInsures();
		
		System.out.println("要给中年人买保险");
		insuredStrategyContext = new InsuredStrategyContext(new MiddleAgedInsuredStrategy());
		
		insuredStrategyContext.excuteBuyInsures();
		
		System.out.println("要给老年人买保险");
		insuredStrategyContext = new InsuredStrategyContext(new OldInsuredStrategy());
		
		insuredStrategyContext.excuteBuyInsures();
		
	}
}

运行结果

要给小孩买保险
购买儿童保险,保障儿童快乐成长。。。
要给中年人买保险
中年人购买保险,保障家庭财产安全。。。。
要给老年人买保险
老年人购买保险,保障身体生病花钱少。。。。

策略模式就是采用了面向对象的继承和多态机制,其他没什么玄机。但是真实的业务环境有这么简单吗?一个类实现多个接口很正常,我们需要看清楚哪个接口是抽象策略接口,哪些是和策略模式没有任何关系。

策略模式的应用

策略模式调用的时序图在这里插入图片描述

策略模式的优点

1.算法可以自由切换
这是策略模式本身定义的,只要实现抽象策略,它就成为策略家族的一个成员,通过封装角色对其进行封装,保证对外提供“可自由切换”的策略。
2. 避免使用多重条件判断
如果没有策略模式,我们想想看会是什么样子?一个策略家族有5个策略算法,一会要使用A策略,一会要使用B策略,怎么设计呢?使用多重的条件语句?多重条件语句不易维护,而且出错的概率大大增强。使用策略模式后,可以由其他模块决定采用何种策略,策略家族对外提供的访问接口就是封装类,简化了操作,同时避免了条件语句判断。
3.扩展性良好
这甚至都不用说是它的优点,因为它太明显了。在现有的系统中增加一个策略太容易了,只要实现接口就可以了,其他都不用修改,类似于一个可反复拆卸的插件,这大大地符合了OCP原则。

策略模式的缺点

1.策略类数量增多
每一个策略都是一个类,复用的可能性很小,类数量增多。
2.所有的策略类都需要对外暴露
上层模块必须知道有哪些策略,然后才能决定使用哪一个策略,这与迪米特法则是相违背的,我只是想使用了一个策略,我凭什么就要了解这个策略呢?那要你的封装类还有什么意义?这是原装策略模式的一个缺点,幸运的是,我们可以使用其他模式来修正这个缺陷,如工厂方法模式、代理模式或享元模式。

策略模式的使用场景

1.多个类只有在算法或行为上稍有不同的场景。
2.算法需要自由切换的场景。
例如,算法的选择是由使用者决定的,或者算法始终在进化,特别是一些站在技术前沿的行业,连业务专家都无法给你保证这样的系统规则能够存在多长时间,在这种情况下策略模式是你最好的助手。
3.需要屏蔽算法规则的场景。
现在的科技发展得很快,人脑的记忆是有限的(就目前来说是有限的),太多的算法你只要知道一个名字就可以了,传递相关的数字进来,反馈一个运算结果就可以了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值