设计模式之策略模式

策略模式介绍

策略模式是将定义算法的家族分别封装起来,让他们之间可以相互替换,从而使算法的变化不会影响到客户端,属于行为型模式。

策略模式的应用场景

策略模式可以解决在多种算法相似的情况下,使用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),充分体现面向对象设计思想。

缺点

  • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
  • 策略模式将造成产生很多策略类,可以通过使用享元模式在一定程度上减少对象的数量。
  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值