行为式:策略模式

1 基本介绍

​ 定义为:定义一些独立的类来封装不同的算法,并让它们可以相互替换。

image-20220320153127331

Context是用适用算法的角色

2 代码框架

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
abstract class AbstractStrategy { 
public abstract void algorithm(); //声明抽象算法
}

class ConcreteStrategyA extends AbstractStrategy {
//算法的具体实现
public void algorithm() {
//算法A
}
}

class Context {
private AbstractStrategy strategy;
//维持一个对抽象策略类的引用
public void setStrategy(AbstractStrategy strategy) {
this.strategy= strategy;
}
//调用策略类中的算法
public void algorithm() {
strategy.algorithm();
}
}

// 客户端代码...
Context context = new Context();
AbstractStrategy strategy;
strategy = new ConcreteStrategyA();
//可在运行时指定类型
context.setStrategy(strategy);
context.algorithm();

3 设计分析

​ 实现电影院打折方案

image-20220320153523078

​ 代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package DesignPatterns.JavaDesign.Strategy;

import DesignPatterns.JavaDesign.FactoryMethod.XMLUtil;

public class Test {
public static void main(String[] args) {
MovieTicket mt = new MovieTicket();
double originalPrice = 60.0;
double currentPrice; mt.setPrice(originalPrice); System.out.println("原始价为:" + originalPrice); System.out.println("---------------------------------");
Discount discount;
discount = new ChildrenDiscount(); // <-------可用xml优化
//读取配置文件并反射生成具体折扣对象
mt.setDiscount(discount);
//注入折扣对象
currentPrice = mt.getPrice();
System.out.println("折后价为:" + currentPrice);
}
}

//电影票类:环境类
class MovieTicket {
private double price;
private Discount discount;
//维持一个对抽象折扣类的引用
public void setPrice(double price) {
this.price = price;
}
//注入一个折扣类对象
public void setDiscount(Discount discount) {
this.discount = discount;
}public double getPrice() {
//调用折扣类的折扣价计算方法
return discount.calculate(this.price);
}
}

//折扣类:抽象策略类
interface Discount {
public double calculate(double price);
}

//学生票折扣类:具体策略类
class StudentDiscount implements Discount {
public double calculate(double price) {
System.out.println("学生票:");
return price * 0.8;
}
}

//儿童票折扣类:具体策略类
class ChildrenDiscount implements Discount {
public double calculate(double price) {
System.out.println("儿童票:");
return price - 10;
}
}

//VIP会员票折扣类:具体策略类
class VIPDiscount implements Discount {
public double calculate(double price) {
System.out.println("VIP票:");
System.out.println("增加积分!");
return price * 0.5;
}
}

4 总结

优缺点分析

优点:

  1. 符合“开闭原则”,用户可以在不修改原有系统的基础上选择算法或行为。
  2. 策略模式提供了管理相关的算法族的办法
  3. 策略模式提供了一种算法的复用机制
  4. 使用策略模式可以避免多重条件选择语句

缺点

  1. 客户端必须知道所有的策略类,并自行决定使用哪一个策略类
  2. 策略模式将造成系统产生很多具体策略类,任何细小的变化都将导致系统要增加一个新的具体策略类
  3. 无法同时在客户端使用多个策略类

适用场景

  • 一个系统需要动态地在几种算法中选择一种
  • 一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重条件选择语句来实现

行为式:策略模式
https://2w1nd.github.io/2022/03/15/设计模式/行为式:策略模式/
作者
w1nd
发布于
2022年3月15日
许可协议