策略模式

定义
策略模式定义了算法家族,分别封装起来,让他们之间可以互相替换
应用场景
一个系统有很多个类,他们之间的区别就在于他们的行为不同。
Demo:模拟简单支付场景

package com.ns.strategy;

import java.math.BigDecimal;

/**
 * 各种支付方式的顶层抽象接口
 */
public interface IPayService {
    void pay(BigDecimal amt);
}

package com.ns.strategy;

import java.math.BigDecimal;

/**
 * QQ支付方式
 */
public class QQPay implements IPayService{
    @Override
    public void pay(BigDecimal amt) {
        System.out.println("通过QQ进行支付"+amt+"元");
    }
}

package com.ns.strategy;

import java.math.BigDecimal;

/**
 * 微信支付
 */
public class WechatPay implements IPayService{
    @Override
    public void pay(BigDecimal amt) {
        System.out.println("通过微信支付"+amt+"元");
    }
}

package com.ns.strategy;

import java.math.BigDecimal;

/**
 * 通过银行卡进行支付
 */
public class BankPay implements IPayService{
    @Override
    public void pay(BigDecimal amt) {
        System.out.println("通过银行卡支付"+amt+"元");
    }
}

package com.ns.strategy;

import java.math.BigDecimal;

/**
 * 默认支付方式:现金
 */
public class DefaultPay implements IPayService{
    @Override
    public void pay(BigDecimal amt) {
        System.out.println("使用现金支付"+amt+"元");
    }
}

package com.ns.strategy;

/**
 * 支付方式枚举类
 */
public enum PayTypeEnum {
    PAY_TYPE_QQ("QQ","QQ支付"),
    PAY_TYPE_WECHAT("WECHAT","微信支付"),
    PAY_TYPE_DEFAULT("DEFAULT","默认支付方式"),
    PAY_TYPE_BANK("BANK","银行卡支付");

    private String code;

    private String name;

    PayTypeEnum(String code, String name){
        this.code = code;
        this.name = name;
    }

    public String getCode() {
        return code;
    }

    public String getName() {
        return name;
    }
}

package com.ns.strategy;

import java.util.HashMap;
import java.util.Map;

/**
 * 支付策略类
 */
public class PayStrategy {
    private static Map<String,IPayService> PAY_MAP = new HashMap<>();

    //静态块,给PAY_MAP赋值
    static {
        PAY_MAP.put(PayTypeEnum.PAY_TYPE_QQ.getCode(),new QQPay());
        PAY_MAP.put(PayTypeEnum.PAY_TYPE_WECHAT.getCode(),new WechatPay());
        PAY_MAP.put(PayTypeEnum.PAY_TYPE_BANK.getCode(),new BankPay());
        PAY_MAP.put(PayTypeEnum.PAY_TYPE_DEFAULT.getCode(),new DefaultPay());
    }

    //单例模式的体现
    private PayStrategy(){}

    /**
     * 获取支付类型对应支付方式实例
     * @param type
     * @return
     */
    public static IPayService getInstance(String type){
        if(PAY_MAP.containsKey(type)){
            return PAY_MAP.get(type);
        }else{
            throw new RuntimeException("no bean found for type "+type);
        }
    }
}

package com.ns.strategy;

import java.math.BigDecimal;

/**
 * 订单类,简单的订单,只有金额字段
 */
public class Order {

    private BigDecimal amt;

    public Order(BigDecimal amt){
        this.amt = amt;
    }

    public void pay(String type) {
        if(null == type || type.trim().isEmpty()){
            type = PayTypeEnum.PAY_TYPE_DEFAULT.getCode();
        }
        IPayService payService = PayStrategy.getInstance(type);
        payService.pay(amt);
    }
}

package com.ns.strategy;

import java.math.BigDecimal;

/**
 * 测试类
 */
public class TestStrategy {

    public static void main(String[] args) {
        Order order = new Order(new BigDecimal(100));
        order.pay(PayTypeEnum.PAY_TYPE_BANK.getCode());
    }
}

策略模式优点
1.符合开闭原则
2.避免过多使用条件语句
3.提高算法的保密性和安全性
缺点
1.客户端必须先知道有多少种策略,并且什么场景调用哪个策略
2.代码中会产生很多的策略类,增加代码维护难度

注:真实业务场景很多都可以使用策略+模板+工厂+单例结合使用来实现

希望大家都可以学以致用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值