策略模式概述
背景
在日常的开发过程中,我们实现功能的时候,对于业务逻辑或者相关算法,一般都是在某个类中使用不同的方法进行实现,完成业务以后,调用方调用相对应的方法完成业务,并获得返回,最终完成功能。一旦我们需要对相关业务功能进行功能的增加或者删减,,就必须重新对现有的代码进行修改,这种方式我们可以称之为硬编码或者强耦合。
这种开发方式,当代码规模比较小的时候,一般不会出现问题,但是一旦业务复杂化,代码量变大之后,代码之间的依赖或者修改,伴随着巨大的质量风险,所以我们需要从设计模式的角度,优化代码结构,降低耦合度。
代码的耦合一般可以理解为,代码之间具备直接的相互依赖,代码的更新需要对原有代码进行不断的修改。
实现
策略模式主要的使用场景以及实现的目的就是为了降低代码耦合度,主要思路是:
- 提取各个方法或者算法的公共部分,抽象为接口或者抽象类。
- 分离每个方法,每个业务方法或者算法实现公共接口,形成独立的实现类
- 考虑使用简单工厂方法,根据业务需求,有选择的对具体的实现类进行实例化
- 调用方仅仅针对工厂方法进行调用,实现整体功能
特点
- 可以使用工厂模式,动态的使用需要的算法
- 降低算法之间的代码耦合度,所有的算法依赖于抽象,符合依赖倒置原则
缺点
- 工厂方法需要对所有的算法进行统一管理,并采用一定的方式来决定实例化哪个算法类,这依然增加了工厂类的代码耦合
- 业务复杂的情况下,将导致算法类的量非常的多
代码实现
逻辑图
代码如下
设置需求如下:商场对商品进行促销打折,促销一共有三种方式,第一是没有折扣,第二是在原价的基础上进行打折,第三是满多少减多少
定义抽象类
/*
定义业务算法的公共方法,所有的折扣计算都需要实现本方法
*/
public abstract class MarketPeerCalcAbstract {
public abstract Double calcPeer(Double price);
}
具体的业务实现类
/*
第一种计费方法:没有任何折扣,原价销售
*/
public class MarketPeerCalcNormalImpl extends MarketPeerCalcAbstract {
@Override
public Double calcPeer(Double price){
return price;
}
}
/*
第二种计算方法:在原价的基础上进行打折
*/
public class MarkPeerCalcRebeatImpl extends MarketPeerCalcAbstract {
private Double rebeatRate;
public MarkPeerCalcRebeatImpl(Double rebeatRate){
this.rebeatRate = rebeatRate;
}
@Override
public Double calcPeer(Double price){
return price*rebeatRate;
}
}
/*
第三种计算方法:满减
*/
public class MarkerPeerCalcFullImpl extends MarketPeerCalcAbstract {
private Double fullPrice;
private Double subPrice;
public MarkerPeerCalcFullImpl(Double fullPrice,Double subPrice){
this.fullPrice = fullPrice;
this.subPrice = subPrice;
}
@Override
public Double calcPeer(Double price){
if(price > fullPrice){
return price - subPrice;
}
return price;
}
}
/*
简单工厂类,构造不同的初始化函数,用于根据具体的业务需求,进行对实现类进行实例化操作
*/
public class PolicyContext {
private MarketPeerCalcAbstract marketPeerCalcAbstract;
public PolicyContext(){
marketPeerCalcAbstract = new MarketPeerCalcNormalImpl();
}
public PolicyContext(double rebeat){
marketPeerCalcAbstract = new MarkPeerCalcRebeatImpl(rebeat);
}
public PolicyContext(double fullprice,double less){
marketPeerCalcAbstract = new MarkerPeerCalcFullImpl(fullprice,less);
}
public Double getCalcresult(Double price){
return marketPeerCalcAbstract.calcPeer(price);
}
}
*/
/*客户端代码:
*/
import org.testng.annotations.Test;
public class PolicyContextDemo {
@Test
public void policyContextTest(){
PolicyContext policyContextnormal = new PolicyContext();
System.out.println("付款200,正常收费为"+policyContextnormal.getCalcresult(200.0));
PolicyContext policyContextRebate = new PolicyContext(0.8);
System.out.println("付款200,打折8折后,收费为"+policyContextRebate.getCalcresult(200.0));
PolicyContext policyContextFull = new PolicyContext(500.0,100.0);
System.out.println("付款600,满500减100后,收费为"+policyContextFull.getCalcresult(600.0));
}
}
测试结果: