java设计模式-策略模式

策略模式

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

设计原则:

  • 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
  • 针对接口编程,而不是针对实现编程。
  • 多用组合,少用继承。

总结:将变化之处独立出来,变化之处采用接口,非变化处采用继承实现代码复用,父类将接口作为成员变量,已达到运行时变化接口的实现,继承组合接口使用

策略模式-定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户

设计背景

我们现在线下的支付方式也有了很多种选择,以前在外面忘了带钱的话可能一瓶水都难以买到,现在只要我们手机在身上,可以用微信或者支付宝。

在这里插入图片描述

在软件设计层面,我们把各种支付方式叫做策略。如果不考虑设计模式的话,我们可能会在一个类中用if…else方式来选择支付方式。

if(type == 1){
     //微信支付   
}else if(type == 2){
     // 支付宝支付
}else if(type == 3){
    //现金支付  
}

但如果以后要改变支付方式,比如不能用微信支付了,或者新增了其他支付方式,我们就要改变这个类,这会带来代码维护的麻烦。
**

模式结构和定义

下图为策略模式的结构:
在这里插入图片描述

从图中我们看到,客户context拥有成员变量strategy(策略),至于需要用到那种策略,我们可以在构造器中指定。
策略模式的定义是:定义算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

这算法体现了几个设计原则,
第一、把变化的代码从不变的代码中分离出来;
第二、针对接口编程而不是具体类(定义了策略接口);
第三、多用组合,少用继承(客户通过组合方式使用策略)。

应用实例

/**
 * 付款方式接口
 *
 * @author shengyong.huang
 * @date 2020-06-07
 */
public interface IPaymentPattern {
    /**
     * 付款
     */
    void pay();
}
/**
 * 客户
 *
 * @author shengyong.huang
 * @date 2020-06-07
 */
public class Person {
    /**
     * 付款方式
     */
    IPaymentPattern paymentPattern;
    /**
     * 购物
     */
    public void shopping() {
        System.out.println("购物...");
        paymentPattern.pay();
    }
    public IPaymentPattern getPaymentPattern() {
        return paymentPattern;
    }
    public void setPaymentPattern(IPaymentPattern paymentPattern) {
        this.paymentPattern = paymentPattern;
    }
}
/**
 * 支付宝付款方式实现
 *
 * @author shengyong.huang
 * @date 2020-06-07
 */
public class AlipayPayment implements IPaymentPattern {
    @Override
    public void pay() {
        System.out.println("支付宝付款");
    }
}
/**
 * 微信付款方式实现
 *
 * @author shengyong.huang
 * @date 2020-06-07
 */
public class WechatPayment implements IPaymentPattern {
    @Override
    public void pay() {
        System.out.println("使用微信付款");
    }
}
/**
 * 钱包付款方式
 *
 * @author shengyong.huang
 * @date 2020-06-07
 */
public class WalletPayment implements IPaymentPattern {
    @Override
    public void pay() {
        System.out.println("使用钱包付款");
    }
}
/**
 * 测试方式
 *
 * @author shengyong.huang
 * @date 2020-06-07
 */
public class TestMain {
    public static void main(String[] args) {
        IPaymentPattern alipayPayment = new AlipayPayment();
        IPaymentPattern wechatPayment = new WechatPayment();
        IPaymentPattern walletPayment = new WalletPayment();
        Person person = new Person();
        // 设置付款策略
        person.setPaymentPattern(alipayPayment);
        person.shopping();
        // 切换付款策略
        person.setPaymentPattern(wechatPayment);
        person.shopping();
        // 切换付款策略
        person.setPaymentPattern(walletPayment);
        person.shopping();
    }
}

运行结果

购物...
支付宝付款
购物...
使用微信付款
购物...
使用钱包付款

优点和不足

优点

  • 体现了“对修改关闭,对扩展开放”原则,客户端增加行为不用修改原有代码,只要添加一种策略即可。
  • 避免了使用多重转移语句(if…else if…else)。
  • 提供了可以替换继承关系的办法: 继承提供了另一种支持多种算法或行为的方法。你可以直接生成一个Context类的子类,从而给它以不同的行为。但这会将行为硬行编制到 Context中,而将算法的实现与Context的实现混合起来,从而使Context难以理解、难以维护和难以扩展,而且还不能动态地改变算法。最后你得到一堆相关的类 , 它们之间的唯一差别是它们所使用的算法或行为。 将算法封装在独立的Strategy类中使得你可以独立于其Context改变它,使它易于切换、易于理解、易于扩展。

缺点

  • 每添加一个策略就要增加一个类,当策略过多是会导致类数目庞大。
  • 客户端需明确知道系统有哪些策略可以使用,当策略过多时客户端的学习成本较高。

使用场景

  • 如果一个系统里有很多类,他们只是某个行为不同时,使用策略模式可以让一个对象在许多行为中选择一种行为。
  • 一个系统需要动态地在几种算法中选择一种。
  • 有多重转移条件语句考虑使用策略模式。

参考:https://www.cnblogs.com/jenkinschan/p/5645300.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值