Java设计模式——策略模式

1. 策略模式简介

策略模式: 策略模式是一种行为型模式, 它将对象和行为分开, 将行为定义为一个行为接口和具体行为的实现 策略模式最大的特点是行为的变化, 行为之间可以相互替换 每个if判断都可以理解为一个策略. 本模式是的算法可独立于使用它的用户而变化

2. 模式结构

策略模式包括如下角色:

  • Strategy: 抽象策略类: 策略是一个接口,  该接口定义若干个算法标识, 即定义了若干个抽象方法(入下图algorithm())
  • Context: 上下文类:

        1. 上下文依赖于接口的类(是面向策略设计的类, 如下图Context类), 即上下文包含用策略声                  明的变量(如下图的strategy成员变量)

        2. 上下文提供一个方法(如下图Context类中的lookAlrorithm()方法), 持有一个策略类的引用,              最终给客户端嗲用, 该方法委托策略变量调用具体策略所实现的策略接口中的方法(实现接口            的类重写策略(接口)中的方法, 来完成具体的功能)

  • ConcreteStategy: 具体策略类: 具体策略是实现策略接口的类(如下图中的ConcreteStrategyA类和ConcreteStrategyB类) 具体策略实现策略接口所定义的方法, 即给出算法标识的具体方法(说白了就是重写策略类的方法)

在这里插入图片描述

 3. 案例

 1)传统模式实现

  public Double calculationPrice(String type, Double originalPrice, int n) {

        //中级会员计费
        if (type.equals("intermediateMember")) {
            return originalPrice * n - originalPrice * 0.1;
        }
        //高级会员计费
        if (type.equals("advancePrimaryMember")) {
            return originalPrice * n - originalPrice * 0.2;
        }
        //普通会员计费
        return originalPrice;
    }

传统的实现方式, 通过传统if代码判断, 这样就会导致后期维护性很差, 当后期需要新增计费方式, 还需要在这里再加上if(), 也不符合设计模式的开闭原则

2)策略模式的实现

抽象类策略

public interface MemberStrategy {
    // 一个计算价格的抽象方法
    //price商品的价格 n商品的个数
    public double calcPrice(double price, int n);
}

具体实现类

// 普通会员——不打折
public class PrimaryMemberStrategy implements MemberStrategy { // 实现策略
    //重写策略方法具体实现功能
    @Override
    public double calcPrice(double price, int n) {
        return price * n;
    }
}
// 中级会员 打百分之10的折扣
public class IntermediateMemberStrategy implements MemberStrategy{
    @Override
    public double calcPrice(double price, int n) {
        double money = (price * n) - price * n * 0.1;
        return money;
    }
}

/ 高级会员类 20%折扣
public class AdvanceMemberStrategy implements MemberStrategy{
    @Override
    public double calcPrice(double price, int n) {
        double money = price * n - price * n * 0.2;
        return money;
    }
}

上下文类

也叫上下文或者环境类, 承上启下的作用

/**
 * 负责和具体的策略类交互
 * 这样的话,具体的算法和直接的客户端调用分离了,使得算法可以独立于客户端独立的变化。
 */

// 上下文类/环境类
public class MemberContext {
    // 用户折扣策略接口
    private MemberStrategy memberStrategy;

    // 注入构造方法
    public MemberContext(MemberStrategy memberStrategy) {
        this.memberStrategy = memberStrategy;
    }

    // 计算价格
    public double qoutePrice(double goodsPrice, int n){
        // 通过接口变量调用对应的具体策略
        return memberStrategy.calcPrice(goodsPrice, n);
    }

}

测试类

// 测试类
public class Application {
    public static void main(String[] args) {

        // 具体行为策略
        MemberStrategy primaryMemberStrategy = new PrimaryMemberStrategy(); // 接口回调
        MemberStrategy intermediateMemberStrategy = new IntermediateMemberStrategy();
        MemberStrategy advanceMemberStrategy = new AdvanceMemberStrategy();

        // 用户选择不同策略
        MemberContext primaryContext = new MemberContext(primaryMemberStrategy);
        MemberContext intermediateContext = new MemberContext(intermediateMemberStrategy);
        MemberContext advanceContext = new MemberContext(advanceMemberStrategy);

        //计算一本300块钱的书
        System.out.println("普通会员的价格:"+ primaryContext.qoutePrice(300,1));//300
        System.out.println("中级会员的价格:"+ intermediateContext.qoutePrice(300,1));//270
        System.out.println("高级会员的价格:"+ advanceContext.qoutePrice(300,1));//240
    }
}

上述案例UML类图

在这里插入图片描述

 4. 策略模式优缺点

1)优点

  • 策略模式提供了不同的实现方法(算法)
  • 策略模式提供了可以替换继承关系的办法
  • 使用策略欧式可以避免使用多重条件转移语句

2)缺点

  • 客户端必须知道所有的策略类, 并自行决定使用哪一个策略类
  • 策略模式将造成很多策略类

5.策略模式的应用场景

  • 如果一个系统里面有很多类, 它们之间的区别仅在于它们的行为, 那么使用策略模式可以动态让一个对象在许多行为中选择一个行为
  • 一个系统需要动态的在几种算法中选择一种
  • 不希望客户端知道复杂的, 与算法相关的数据结构, 提高算法的保密性和安全性

在我们生活中常见的应用模式有:

1、电商网站支付方式,一般分为银联、微信、支付宝,可以采用策略模式
2、电商网站活动方式,一般分为满减送、限时折扣、包邮活动,拼团等可以采用策略模式

6. 总结: 核心思想就是多态

  • 在策略模式中定义了一系列算法, 将每一个算法封装起来, 策略模式让算法独立, 随着使用它的客户而变化
  • 策略模式包含3个角色: 上下文解决某个问题时可以采用多种策略, 在上下文中维护一个对抽象策略类的引用实例; 抽象策略类为所支持的算法声明了抽象的方法, 是所有策略类的父类; 具体策略类实现了在抽象策略类中定义的算法
  • 策略模式的使用情况: 在一个系统中许多类, 它们之间区别仅在于它们的行为, 使用策略模式可以动态的让一个对象在许多行为中选择一种行为

​​​​​​​        

你可能感兴趣的:(策略模式,java,设计模式)