策略模式介绍
策略模式是将定义算法的家族分别封装起来,让他们之间可以相互替换,从而使算法的变化不会影响到客户端,属于行为型模式。
策略模式的应用场景
策略模式可以解决在多种算法相似的情况下,使用if+else 或者switch+case带来的复杂性和臃肿性。应用于以下场景:
- 针对同一类型问题,有多种处理方式,每一种都能独立解决问题。
- 算法可以自由切换的场景。
- 需要屏蔽算法规则的场景。
if (string.equals(PAYEnum.JD.getName())){
//可以提取算法
System.out.println("京东支付");
}else if (string.equals(PAYEnum.Ali.getName())){
//可以提取算法
System.out.println("阿里支付");
}else if (string.equals(PAYEnum.Wechat.getName())){
//可以提取算法
System.out.println("微信支付");
}
代码示例
抽象策略
package com.example.proxy.designpatten.strategy;
/**
* @author ludengke
* @title: IPayStrategy
* @projectName alibabatest
* @description: TODO
* @date 2024/6/1415:43
*/
public interface IPayStrategy {
void pay();
}
具体策略
package com.example.proxy.designpatten.strategy;
/**
* @author ludengke
* @title: JDPay
* @projectName alibabatest
* @description: TODO
* @date 2024/6/1415:46
*/
public class JDPay implements IPayStrategy {
@Override
public void pay() {
System.out.println("京东支付");
}
}
package com.example.proxy.designpatten.strategy;
/**
* @author ludengke
* @title: WeChatPay
* @projectName alibabatest
* @description: TODO
* @date 2024/6/1415:47
*/
public class WeChatPay implements IPayStrategy {
@Override
public void pay() {
System.out.println("微信支付");
}
}
package com.example.proxy.designpatten.strategy;
/**
* @author ludengke
* @title: AliPay
* @projectName alibabatest
* @description: TODO
* @date 2024/6/1415:46
*/
public class AliPay implements IPayStrategy {
@Override
public void pay() {
System.out.println("阿里支付");
}
}
环境和上下文类
package com.example.proxy.designpatten.strategy;
/**
* @author ludengke
* @title: PayActivety
* @projectName alibabatest
* @description: TODO
* @date 2024/6/1416:01
*/
public class PayContext {
private IPayStrategy payStrategy;
public IPayStrategy getPayStrategy() {
return payStrategy;
}
public void setPayStrategy(IPayStrategy payStrategy) {
this.payStrategy = payStrategy;
}
public PayContext(IPayStrategy payStrategy) {
this.payStrategy = payStrategy;
}
/**
* 支付接口,payStrategy可以通过set方法或者构造方法传进来
*/
public void pay(){
this.payStrategy.pay();
}
}
策略工厂
正常是没有的,这是策略模式+工厂模式。
package com.example.proxy.designpatten.strategy;
import java.util.HashMap;
import java.util.Map;
/**
* @author ludengke
* @title: PayFactory
* @projectName alibabatest
* @description: TODO
* @date 2024/6/1416:03
*/
public class PayFactory {
private static Map<String,IPayStrategy> PAYS=new HashMap<>();
static {
PAYS.put(PAYEnum.JD.getName(),new JDPay());
PAYS.put(PAYEnum.Ali.getName(),new AliPay());
PAYS.put(PAYEnum.Wechat.getName(),new WeChatPay());
}
public IPayStrategy getPayStrategy(String strategyName){
return PAYS.get(strategyName);
}
}
客户端
package com.example.proxy.designpatten.strategy;
/**
* @author ludengke
* @title: TestPay
* @projectName alibabatest
* @description: TODO
* @date 2024/6/1415:47
*/
public class TestPay {
public static void main(String[] args) {
String string=PAYEnum.JD.getName();
PayFactory payFactory=new PayFactory();
new PayContext(payFactory.getPayStrategy(string)).pay();
// if (string.equals(PAYEnum.JD.getName())){
// //可以提取算法
// System.out.println("京东支付");
// }else if (string.equals(PAYEnum.Ali.getName())){
// //可以提取算法
// System.out.println("阿里支付");
// }else if (string.equals(PAYEnum.Wechat.getName())){
// //可以提取算法
// System.out.println("微信支付");
// }
new PayContext(new JDPay()).pay();
}
}
枚举类
package com.example.proxy.designpatten.strategy;
/**
* @author ludengke
* @title: PAYEnum
* @projectName alibabatest
* @description: TODO
* @date 2024/6/1416:05
*/
public enum PAYEnum {
JD(1,"JD"),Ali(2,"Ali"),Wechat(3,"Wechat");
private Integer index;
private String name;
PAYEnum(Integer index, String name) {
this.index = index;
this.name = name;
}
public Integer getIndex() {
return index;
}
public void setIndex(Integer index) {
this.index = index;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
策略模式的优缺点
优点
- 策略类之间可以自由切换.由于策略类都实现同一个接口,所以使它们之间可以自由切换。
- 易于扩展。增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码,符合“开闭原则“
- 避免使用多重条件选择语句(if else),充分体现面向对象设计思想。
缺点
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
- 策略模式将造成产生很多策略类,可以通过使用享元模式在一定程度上减少对象的数量。