行为型模式(Behavioral Pattern)是对不同的对象之间划分责任和算法的抽象化;
行为型模式共有11种:
■ 模板方法模式
■ 命令模式
■ 责任链模式
■ 策略模式
■ 迭代器模式
■ 中介者模式
■ 观察者模式
■ 备忘录模式
■ 访问者模式
■ 状态模式
■ 解释器模式
一、策略模式的简介
定义一组算法,将每个算法都封装起来,并且使它们之间可以互换;

image.png
策略模式3个角色
■ 环境(Context)角色:
该角色也叫上下文角色,起到承上启下的作用;
屏蔽高层模块对策略、算法的直接访问,它持有一个Strategy类的引用;
■ 抽象策略(Strategy)角色:
该角色对策略、算法进行抽象;
通常定义每个策略或算法必须具有的方法和属性;
■ 具体策略(Concrete Strategy)角色:
该角色实现抽象策略中的具体操作,含有具体的算法;
/**
* 抽象策略
*/
public abstract class Strategy {
// 抽象方法
public abstract void strategyInterface();
}
/**
* 具体策略
*/
public class ConcreteStrategy extends Strategy{
/**
* 实现策略方法
*/
@Override
public void strategyInterface() {
// 具体方法
System.out.println("具体方法");
}
}
/**
* 环境角色
*/
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void contextInterface(){
this.strategy.strategyInterface();
}
}
/**
* 应用代码
*/
public class Client {
public static void main(String[] args){
Strategy strategy = new ConcreteStrategy();
Context context = new Context(strategy);
context.contextInterface();
}
}
# 控制台输出:
具体方法
二、策略模式的优缺点
■ 策略模式的优点
策略模式提供了管理相关的算法族的办法;
策略模式提供了可以替换继承关系的办法;
使用策略模式可以避免使用多重条件转移语句;
■ 策略模式的缺点
客户端必须知道所有的策略类,并自行决定使用哪一个策略类;
策略模式造成很多的策略类;
三、策略模式的应用场景
■ 多个类只是在算法或行为上稍有不同的场景;
■ 算法需要自由切换的场景;
■ 需要屏蔽算法规则的场景;
四、策略模式的实例
使用图书销售中不同的折扣算法演示策略模式;
■ 算法1:对有些图书没有折扣,即折扣算法中折扣值为0;
■ 算法2:对有些图书的折扣是固定值为1元;
■ 算法3:对有些图书的折扣是15%;

image.png
/**
* 抽象折扣算法
*/
public abstract class DiscountStrategy {
// 书的价格
private double price = 0;
// 书的数量
private int number = 0;
public DiscountStrategy(double price, int number) {
this.price = price;
this.number = number;
}
public double getPrice() {
return price;
}
public int getNumber() {
return number;
}
// 策略方法、计算折扣额
public abstract double calculateDiscount();
}
/**
* 折扣算法1
* 对有些图书没有折扣,即折扣算法中折扣值为0;
*/
public class NoDiscountStrategy extends DiscountStrategy{
// 构造函数
public NoDiscountStrategy(double price, int number) {
super(price, number);
}
// 实现策略方法:0折扣
@Override
public double calculateDiscount() {
return 0;
}
}
/**
* 折扣算法2
* 对有些图书的折扣是固定值为1元;
*/
public class FixDiscountStrategy extends DiscountStrategy{
// 构造函数
public FixDiscountStrategy(double price, int number) {
super(price, number);
}
// 实现策略方法:固定值折扣1元
@Override
public double calculateDiscount() {
return getNumber() * 1;
}
}
/**
* 折扣算法3
* 对有些图书的折扣是15%;
*/
public class PercentageDiscountStrategy extends DiscountStrategy{
// 构造函数
public PercentageDiscountStrategy(double price, int number) {
super(price, number);
}
// 实现策略方法:折扣是15%
@Override
public double calculateDiscount() {
return getNumber() * getPrice() * 0.15;
}
}
/**
* 环境角色
*/
public class ContextClient {
private DiscountStrategy ds;
// 构造函数
public ContextClient(DiscountStrategy ds) {
this.ds = ds;
}
// 调用策略模式,计算折扣额
public double contextCalDisc(){
return ds.calculateDiscount();
}
}
/**
* 应用代码
*/
public class ClientDemo {
public static void main(String[] args){
ContextClient c0 = new ContextClient(new NoDiscountStrategy(100 , 2));
System.out.println("0折扣 : " + c0.contextCalDisc());
ContextClient c1 = new ContextClient(new FixDiscountStrategy(100 , 2));
System.out.println("固定折扣 : " + c1.contextCalDisc());
ContextClient c2 = new ContextClient(new PercentageDiscountStrategy(100 , 2));
System.out.println("15%折扣 : " + c2.contextCalDisc());
}
}
# 控制台输出:
0折扣 : 0.0
固定折扣 : 2.0
15%折扣 : 30.0
参考:
摘录 《设计模式(Java版)》韩敬海主编;(微信读书APP中有资源,可以直接阅读)
网友评论