6、中介者模式
Mediator Pattern
[ˈmiːdieɪtər]
1)基本介绍
- 中介者模式(Mediator Pattern),用一个中介对象来封装一系列的对象交互。中介者使各个对象不需要显式地相互引用,从而使其解耦,而且可以独立地改变它们之间的交互
- 中介者模式属于行为型模式,使代码易于维护
- MVC模式,C(Controller控制器)是 M(Model模型)和 V(View视图)的中介者,在前后端交互时起到了中间人的作用
2)原理类图
- Mediator 就是抽象中介者,定义了同事对象到中介者对象的接口
- Colleague是抽象同事类
- ConcreteMediator具体的中介者对象 ,实现抽象方法,需要知道所有的具体的同事类,即以一个集合来管理 HashMap,并接受某个同事对象消息,完成相应的任务
- ConcreteColleague 具体的同事类,会有很多,每个同事只知道自己的行为,而不了解其他同事类的行为(方法),但是他们都依赖中介者对象;同事间实现解耦,提高了扩展性
3)案例分析
智能家庭项目
- 智能家庭包括各种设备,闹钟、咖啡机、电视机、窗帘等
- 主人要看电视时,各个设备可以协同工作,自动完成看电视的准备工作,比如流程为:
- 闹铃响起
- 咖啡机开始做咖啡
- 窗帘自动落下
- 电视机开始播放
同事之间(闹钟、咖啡机、电视、窗帘、电话)实现解耦,方便扩展
每个同事都与中介关联,图中只展示 闹钟和中介的关联,其余省略
中介抽象类 Mediator
package mediator.mediator;
import mediator.colleague.Colleague;
/**
* @author 土味儿
* Date 2021/7/29
* @version 1.0
* 中介抽象类
*/
public abstract class Mediator {
/**
* 注册特定同事,放入集合中
* @param colleagueName
* @param colleague
*/
public abstract void register(String colleagueName, Colleague colleague);
/**
* 获取特定同事发出的消息
* @param stateChange
* @param colleagueName
*/
public abstract void getMessage(int stateChange,String colleagueName);
/**
* 发送消息
*/
public abstract void sendMessage();
}
具体中介实现者 ConcreteMediator
package mediator.mediator;
import mediator.colleague.*;
import java.util.HashMap;
import java.util.Map;
/**
* @author 土味儿
* Date 2021/7/29
* @version 1.0
* 具体中介实现者
*/
public class ConcreteMediator extends Mediator {
// 集合,放入同事对象
private Map<String,Colleague> colleagueMap;
// 集合,存放同事名称
private HashMap<String, String> interMap;
/**
* 构造器
*/
public ConcreteMediator() {
this.colleagueMap = new HashMap<String,Colleague>();
this.interMap = new HashMap<String,String>();
}
/**
* 注册同事对象
* @param colleagueName
* @param colleague
*/
@Override
public void register(String colleagueName, Colleague colleague) {
colleagueMap.put(colleagueName,colleague);
if (colleague instanceof AlarmColleague) {
interMap.put("Alarm", colleagueName);
} else if (colleague instanceof CoffeeMachineColleague) {
interMap.put("CoffeeMachine", colleagueName);
}
}
/**
* 核心方法
* 获取消息并处理
* @param stateChange
* @param colleagueName
*/
@Override
public void getMessage(int stateChange, String colleagueName) {
// 闹钟
if(colleagueMap.get(colleagueName) instanceof AlarmColleague){
if(stateChange == 0 ){// 闹钟响起:开始
// 开始制作咖啡
((CoffeeMachineColleague)(colleagueMap.get(interMap.get("CoffeeMachine")))).startCoffee();
// 落下窗帘
// 打开电视
}else if(stateChange == 1){// 闹钟响起:结束
// 关闭电视
// 升级窗帘
}
}
}
@Override
public void sendMessage() {
}
}
抽象同事类 Colleague
package mediator.colleague;
import mediator.mediator.Mediator;
/**
* @author 土味儿
* Date 2021/7/29
* @version 1.0
* 抽象同事类
*/
public abstract class Colleague {
// 中介者
private Mediator mediator;
// 同事名称
private String name;
/**
* 构造器
* @param mediator
* @param name
*/
public Colleague(Mediator mediator, String name) {
this.mediator = mediator;
this.name = name;
}
/**
* 发送消息
* @param stateChange
*/
public abstract void sendMessage(int stateChange);
public String getName() {
return name;
}
public Mediator getMediator() {
return mediator;
}
}
具体同事实现类
package mediator.colleague;
import mediator.mediator.Mediator;
/**
* @author 土味儿
* Date 2021/7/29
* @version 1.0
* 闹钟
*/
public class AlarmColleague extends Colleague {
/**
* 构造器
*
* @param mediator
* @param name
*/
public AlarmColleague(Mediator mediator, String name) {
super(mediator, name);
mediator.register(name,this);
}
/**
* 闹钟发声
* @param stateChange
*/
public void sendAlarm(int stateChange){
if(stateChange == 0 ){// 闹钟响起:开始
System.out.println("闹钟响起开始");
}else if(stateChange == 1){// 闹钟响起:结束
System.out.println("闹钟响起结束");
}
sendMessage(stateChange);
}
/**
* 发送消息
* @param stateChange
*/
@Override
public void sendMessage(int stateChange) {
this.getMediator().getMessage(stateChange,this.getName());
}
}
package mediator.colleague;
import mediator.mediator.Mediator;
/**
* @author 土味儿
* Date 2021/7/29
* @version 1.0
* 咖啡机
*/
public class CoffeeMachineColleague extends Colleague{
/**
* 构造器
*
* @param mediator
* @param name
*/
public CoffeeMachineColleague(Mediator mediator, String name) {
super(mediator, name);
mediator.register(name,this);
}
@Override
public void sendMessage(int stateChange) {
this.getMediator().getMessage(stateChange,this.getName());
}
/**
* 开始制作咖啡
*/
public void startCoffee(){
System.out.println("开始制作咖啡");
}
/**
* 咖啡制作完成
*/
public void finishCoffee(){
System.out.println("咖啡制作完成");
}
}
客户端
package mediator;
import mediator.colleague.*;
import mediator.mediator.*;
/**
* @author 土味儿
* Date 2021/7/29
* @version 1.0
* 客户端
*/
public class Client {
public static void main(String[] args) {
// 创建中介者对象
Mediator mediator = new ConcreteMediator();
// 创建闹钟
AlarmColleague alarmColleague = new AlarmColleague(mediator, "闹钟");
// 创建咖啡机
CoffeeMachineColleague coffeeMachineColleague = new CoffeeMachineColleague(mediator, "咖啡机");
alarmColleague.sendAlarm(0);
alarmColleague.sendAlarm(1);
}
}
运行结果
闹钟响起开始
开始制作咖啡
闹钟响起结束
7、备忘录模式
Memento Pattern
1)基本介绍
- 备忘录模式(Memento Pattern)在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态
- 可以这样理解备忘录模式:现实生活中的备忘录是用来记录某些要去做的事情,或者是记录已经达成的共同意 见的事情,以防忘记了。而在软件层面,备忘录模式有着相同的含义,备忘录对象主要用来记录一个对象的某 种状态,或者某些数据,当要做回退时,可以从备忘录对象里获取原来的数据进行恢复操作
- 备忘录模式属于行为型模式
2)原理类图
- Originator :对象(需要保存状态的对象)
- Memento:备忘录对象,负责保存记录,即 Originator 内部状态
- Caretaker:守护者对象,负责保存多个备忘录对象,使用集合管理,提高效率
- 如果希望保存多个 originator 对象的不同时间的状态,也可以,只需要 HashMap <String,集合>
3)案例分析
游戏角色有攻击力和防御力,在大战 Boss前保存自身的状态(攻击力和防御力),当大战 Boss后攻击力和防御力下降,从备忘录对象恢复到大战前的状态
可以存储多个角色的状态,每个角色有多个状态
备忘录对象 Memento
package memento.originator.more;
/**
* @author 土味儿
* Date 2021/7/30
* @version 1.0
* 备忘录对象
*/
public class Memento {
// 攻击力
private int vit;
// 防御力
private int def;
public Memento(int vit, int def) {
this.vit = vit;
this.def = def;
}
public int getVit() {
return vit;
}
public int getDef() {
return def;
}
}
游戏角色 GameRole
GameRole1、GameRole2、GameRole3
package memento.originator.more.gamerole;
import memento.originator.more.Memento;
/**
* @author 土味儿
* Date 2021/7/30
* @version 1.0
* 游戏角色1
*/
public class GameRole1 {
// 角色名称
private String name;
// 攻击力
private int vit;
// 防御力
private int def;
public GameRole1() {
this.name = "角色1";
this.vit = 100;
this.def = 100;
}
/**
* 创建当前状态的备忘录
*
* @return
*/
public Memento createMemento() {
return new Memento(vit, def);
}
/**
* 从备忘录中恢复状态
*/
public void recoverFromMemento(Memento memento) {
this.vit = memento.getVit();
this.def = memento.getDef();
}
/**
* 显示
*/
public void display() {
System.out.println(name + " 攻击力:" + vit + " 防御力:" + def);
}
public String getName() {
return name;
}
public void setVit(int vit) {
this.vit = vit;
}
public void setDef(int def) {
this.def = def;
}
}
守护者对象 Caretaker
package memento.originator.more;
import java.util.*;
/**
* @author 土味儿
* Date 2021/7/30
* @version 1.0
* 守护者对象
* 存储备忘录
*/
public class Caretaker {
// 存储某个角色备忘录集合
private List<Memento> mementoList;
// 存储所有角色的备忘录集合
private HashMap<String,List<Memento>> mementoMap;
/**
* 构造器
*/
public Caretaker() {
//this.mementoList = new ArrayList<>();
this.mementoMap = new HashMap<>();
}
/**
* 添加
* @param gameRoleName
* @param memento
*/
public void add(String gameRoleName,Memento memento){
// 检查Map中是否存当前角色
Set<String> keySet = mementoMap.keySet();
// Map中是否包含当前角色:默认不包含
boolean include = false;
for (String k : keySet) {
if(k.equals(gameRoleName)){
include = true;
break;
}
}
// 不存在:直接添加
if(!include){
mementoList = new ArrayList<>();
mementoList.add(memento);
// HashMap 如果添加相同的key,后面的会替换前面的key-value(key不会替换,value会替换)
mementoMap.put(gameRoleName,mementoList);
return;
}
// 存在:从Map中取出List,把状态加入List,再把List存入Map
mementoList = mementoMap.get(gameRoleName);
mementoList.add(memento);
// HashMap 如果添加相同的key,后面的会替换前面的key-value(key不会替换,value会替换)
mementoMap.put(gameRoleName,mementoList);
}
/**
* 获取
* @param gameRoleName
* @param index
* @return
*/
public Memento get(String gameRoleName,int index){
return mementoMap.get(gameRoleName).get(index);
}
/**
* 删除
* @param index
*/
public void remove(String gameRoleName,int index){
mementoMap.get(gameRoleName).remove(index);
}
}
客户端 Client
package memento.originator.more;
import memento.originator.more.gamerole.GameRole1;
import memento.originator.more.gamerole.GameRole2;
import memento.originator.more.gamerole.GameRole3;
/**
* @author 土味儿
* Date 2021/7/30
* @version 1.0
* 客户端
*/
public class Client {
public static void main(String[] args) {
// 创建守护者
Caretaker caretaker = new Caretaker();
// 创建游戏角色1
GameRole1 gameRole1 = new GameRole1();
// 设置状态
gameRole1.setVit(80);
gameRole1.setDef(70);
caretaker.add(gameRole1.getName(),gameRole1.createMemento());
// 设置状态
gameRole1.setVit(60);
gameRole1.setDef(50);
caretaker.add(gameRole1.getName(),gameRole1.createMemento());
// 设置状态
gameRole1.setVit(50);
gameRole1.setDef(40);
caretaker.add(gameRole1.getName(),gameRole1.createMemento());
gameRole1.display();
gameRole1.recoverFromMemento(caretaker.get(gameRole1.getName(),1));
gameRole1.display();
// 创建游戏角色2
GameRole2 gameRole2 = new GameRole2();
// 设置状态
gameRole2.setVit(82);
gameRole2.setDef(72);
caretaker.add(gameRole2.getName(),gameRole2.createMemento());
// 创建游戏角色3
GameRole3 gameRole3 = new GameRole3();
// 设置状态
gameRole3.setVit(83);
gameRole3.setDef(73);
caretaker.add(gameRole3.getName(),gameRole3.createMemento());
// 设置状态
gameRole2.setVit(62);
gameRole2.setDef(52);
caretaker.add(gameRole2.getName(),gameRole2.createMemento());
gameRole2.display();
gameRole2.recoverFromMemento(caretaker.get(gameRole2.getName(),0));
gameRole2.display();
}
}
运行结果
角色1 攻击力:50 防御力:40
角色1 攻击力:60 防御力:50
角色2 攻击力:62 防御力:52
角色2 攻击力:82 防御力:72
4)注意事项和细节
-
给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态
-
实现了信息的封装,使得用户不需要关心状态的保存细节
-
如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存,这个需要注意
-
适用的应用场景:
- 后悔药
- 打游戏时的存档
- Windows里的 ctri + z
- IE中的后退
- 数据库的事务管理
-
为了节约内存,备忘录模式可以和原型模式配合使用
8、解释器模式
Interpreter Pattern
1)基本介绍
- 在编译原理中,一个算术表达式通过词法分析器形成词法单元,而后这些词法单元再通过语法分析器构建语法分析树,最终形成一颗抽象的语法分析树。这里的词法分析器和语法分析器都可以看做是解释器
- 解释器模式(Interpreter Pattern):是指给定一个语言(表达式),定义它的文法的一种表示,并定义一个解释器,使用该解释器来解释语言中的句子(表达式)
- 应用场景
- 编译器
- 运算表达式计算
- 正则表达式
- 机器人等
2)原理类图
- Context:是环境角色,含有解释器之外的全局信息
- AbstractExpression:抽象表达式,声明一个抽象的解释操作,这个方法为抽象语法树中所有的节点所共享
- TerminalExpression:为终结符表达式,实现与文法中的终结符相关的解释操作
- NonTermialExpression:为非终结符表达式,为文法中的非终结符实现解释操作
- 通过 Client 输入 Context 和 TerminalExpression 信息
3)案例分析
通过解释器模式来实现加减运算, 如计算 a+b-c 的值
-
Expression 抽象表达式(a+b-c)
- VarExpression 变量表达式(a、b、c)
- SymbolExpression 运算符表达式(+、-)
- AddExpression 加法表达式
- SubExpression 减法表达式
-
Calculator 计算器
4)Spring中的应用
Spring框架中 SpelExpressionParser 就使用到解释器模式
5)注意事项和细节
- 当有一个语言需要解释执行,可将该语言中的句子表示为一个抽象语法树,就可以考虑使用解释器模式,让程 序具有良好的扩展性
- 可能带来的问题:会引起类膨胀,解释器模式采用递归调用方法,将会导致调试非常复杂、效率可能降低
9、状态模式
State Pattern
1)基本介绍
- 状态模式(State Pattern):它主要用来解决对象在多种状态转换时,需要对外输出不同的行为的问题。状态和行为是一一对应的,状态之间可以相互转换
- 当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类
2)原理类图
- Context 类为环境角色,用于维护 State 实例,这个实例定义当前状态
- State 是抽象状态角色,定义一个接口封装与 Context 的一个特定接口相关行为
- ConcreteState 具体的状态角色,每个子类实现一个与 Context 的一个状态相关行为
3)抽奖案例
APP抽奖活动
具体要求如下:
- 假如每参加一次这个活动要扣除用户 50 积分,中奖概率是 10%
- 奖品数量固定,抽完就不能抽奖
- 活动有四个状态:可以抽奖、待抽奖、发放奖品和奖品领完
- 状态转换关系图
抽奖状态接口 RaffleState
package state.raffle;
/**
* @author 土味儿
* Date 2021/7/30
* @version 1.0
* 抽奖状态接口
*/
public interface RaffleState {
/**
* 扣积分
*/
void deductIntegral();
/**
* 抽奖
*/
boolean raffle();
/**
* 发奖品
*/
void dispensePrize();
}
具体状态实现类
package state.raffle.state;
import state.raffle.RaffleActivity;
import state.raffle.RaffleState;
/**
* @author 土味儿
* Date 2021/7/30
* @version 1.0
* 待抽奖状态
*/
public class WaitRaffleState implements RaffleState {
// 抽奖活动
private RaffleActivity raffleActivity;
/**
* 构造器
* @param raffleActivity
*/
public WaitRaffleState(RaffleActivity raffleActivity) {
this.raffleActivity = raffleActivity;
}
/**
* 扣积分
* 只有 待抽奖状态 可以扣积分,扣除后将状态设置成 可抽奖状态
*/
@Override
public void deductIntegral() {
System.out.println("扣除 50 积分成功!您可以抽奖了!");
// 把状态设置为 可抽奖状态
raffleActivity.setState(raffleActivity.getCanRaffleState());
}
/**
* 抽奖
* 待抽奖状态 不能抽奖
* @return
*/
@Override
public boolean raffle() {
System.out.println("扣除积分后才可以抽奖哟");
return false;
}
/**
* 发奖品
*/
@Override
public void dispensePrize() {
System.out.println("待抽奖状态不能发放奖品哟");
}
}
package state.raffle.state;
import state.raffle.RaffleActivity;
import state.raffle.RaffleState;
import java.util.Random;
/**
* @author 土味儿
* Date 2021/7/30
* @version 1.0
* 可抽奖状态
*/
public class CanRaffleState implements RaffleState {
// 抽奖活动
private RaffleActivity raffleActivity;
/**
* 构造器
*
* @param raffleActivity
*/
public CanRaffleState(RaffleActivity raffleActivity) {
this.raffleActivity = raffleActivity;
}
/**
* 扣积分
*/
@Override
public void deductIntegral() {
System.out.println("已经扣过积分了,请抽奖!");
}
/**
* 抽奖
*
* @return
*/
@Override
public boolean raffle() {
System.out.println("正在抽奖,请稍候...");
// 随机抽奖:中奖概率30%
int i = new Random().nextInt(100);
// 中奖了
if (i < 30) {
System.out.println("㳟喜您!中奖了...");
// 把状态设置为 发放奖品状态
raffleActivity.setState(raffleActivity.getDispensePrizeState());
return true;
}
System.out.println("很遗憾没有中奖!");
// 把状态设置为 待抽奖状态
raffleActivity.setState(raffleActivity.getWaitRaffleState());
return false;
}
/**
* 发放奖品
*/
@Override
public void dispensePrize() {
System.out.println("中奖后才可以发放奖品!");
}
}
package state.raffle.state;
import state.raffle.RaffleActivity;
import state.raffle.RaffleState;
/**
* @author 土味儿
* Date 2021/7/30
* @version 1.0
* 发放奖品状态
*/
public class DispensePrizeState implements RaffleState {
// 抽奖活动
private RaffleActivity raffleActivity;
/**
* 构造器
* @param raffleActivity
*/
public DispensePrizeState(RaffleActivity raffleActivity) {
this.raffleActivity = raffleActivity;
}
/**
* 扣积分
*/
@Override
public void deductIntegral() {
System.out.println("发放奖品状态不扣积分!");
}
/**
* 抽奖
* @return
*/
@Override
public boolean raffle() {
System.out.println("发放奖品状态不能抽奖");
return false;
}
/**
* 发放奖品
* 根据奖品数量,判断状态
*/
@Override
public void dispensePrize() {
if(raffleActivity.getCount() > 0){
System.out.println("请领奖....");
// 奖品数量减1
raffleActivity.setCount(raffleActivity.getCount()-1);
// 判断最新奖品数量,然后设置状态
if(raffleActivity.getCount() > 0){
// 把状态设置为 待抽奖状态
raffleActivity.setState(raffleActivity.getWaitRaffleState());
return;
}
// 把状态设置为 奖品发完状态
raffleActivity.setState(raffleActivity.getPrizeOverState());
return;
}
System.out.println("没有奖品了...");
// 把状态设置为 奖品发完状态
raffleActivity.setState(raffleActivity.getPrizeOverState());
}
}
package state.raffle.state;
import state.raffle.RaffleActivity;
import state.raffle.RaffleState;
/**
* @author 土味儿
* Date 2021/7/30
* @version 1.0
* 奖品发完状态
*/
public class PrizeOverState implements RaffleState {
// 抽奖活动
private RaffleActivity raffleActivity;
/**
* 构造器
* @param raffleActivity
*/
public PrizeOverState(RaffleActivity raffleActivity) {
this.raffleActivity = raffleActivity;
}
@Override
public void deductIntegral() {
System.out.println("奖品发完了!不扣积分");
}
@Override
public boolean raffle() {
System.out.println("奖品发完了!不能抽奖");
return false;
}
@Override
public void dispensePrize() {
System.out.println("奖品发完了!");
}
}
抽奖活动类 RaffleActivity
package state.raffle;
import state.raffle.state.CanRaffleState;
import state.raffle.state.DispensePrizeState;
import state.raffle.state.PrizeOverState;
import state.raffle.state.WaitRaffleState;
/**
* @author 土味儿
* Date 2021/7/30
* @version 1.0
* 抽奖活动
*/
public class RaffleActivity {
// 当前状态
private RaffleState state = null;
// 四种状态
private WaitRaffleState waitRaffleState;
private CanRaffleState canRaffleState;
private DispensePrizeState dispensePrizeState;
private PrizeOverState prizeOverState;
// 奖品数量
private int count = 0;
/**
* 构造器
*
* @param count
*/
public RaffleActivity(int count) {
this.waitRaffleState = new WaitRaffleState(this);
this.canRaffleState = new CanRaffleState(this);
this.dispensePrizeState = new DispensePrizeState(this);
this.prizeOverState = new PrizeOverState(this);
this.state = waitRaffleState;
this.count = count;
}
/**
* 扣积分
*/
public void deductIntegral() {
state.deductIntegral();
}
/**
* 抽奖
*/
public void raffle() {
if (state.raffle()) {
// 抽奖成功,发放奖品
//setCount(getCount()-1);
state.dispensePrize();
}
}
public void setState(RaffleState state) {
this.state = state;
}
public WaitRaffleState getWaitRaffleState() {
return waitRaffleState;
}
public CanRaffleState getCanRaffleState() {
return canRaffleState;
}
public DispensePrizeState getDispensePrizeState() {
return dispensePrizeState;
}
public PrizeOverState getPrizeOverState() {
return prizeOverState;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
调用客户端 Client
package state.raffle;
/**
* @author 土味儿
* Date 2021/7/30
* @version 1.0
* 客户端
*/
public class Client {
public static void main(String[] args) {
// 创建抽奖活动:奖品数 2
RaffleActivity raffleActivity = new RaffleActivity(2);
// 循环抽奖,如果没有奖品就退出
int i = 0;
while(raffleActivity.getCount() > 0){
System.out.println("\n===== 第" + ++i + "次抽奖 (剩余奖品数:" + raffleActivity.getCount() + ") =====");
// 扣积分
raffleActivity.deductIntegral();
// 抽奖
raffleActivity.raffle();
}
/* // 循环抽奖30次,即使没有奖品了,仍然抽奖
for (int i = 1; i < 31; i++) {
System.out.println("\n===== 第" + i + "次抽奖 (剩余奖品数:" + raffleActivity.getCount() + ") =====");
// 扣积分
raffleActivity.deductIntegral();
// 抽奖
raffleActivity.raffle();
}*/
}
}
运行结果
===== 第1次抽奖 (剩余奖品数:2) =====
扣除 50 积分成功!您可以抽奖了!
正在抽奖,请稍候...
很遗憾没有中奖!
===== 第2次抽奖 (剩余奖品数:2) =====
扣除 50 积分成功!您可以抽奖了!
正在抽奖,请稍候...
㳟喜您!中奖了...
请领奖....
===== 第3次抽奖 (剩余奖品数:1) =====
扣除 50 积分成功!您可以抽奖了!
正在抽奖,请稍候...
很遗憾没有中奖!
===== 第4次抽奖 (剩余奖品数:1) =====
扣除 50 积分成功!您可以抽奖了!
正在抽奖,请稍候...
㳟喜您!中奖了...
请领奖....
4)借贷平台案例
- 借贷平台的订单,有审核-发布-完结等等步骤,随着操作的不同,会改变订单的状态,项目中的这个模块实 现就会使用到状态模式
- 通常通过 if/else 判断订单的状态,从而实现不同的逻辑,伪代码如下
5)注意事项和细节
-
代码有很强的可读性:状态模式将每个状态的行为封装到对应的一个类中
-
维护方便:将容易产生问题的 if-else 语句删除了,如果把每个状态的行为都放到一个类中,每次调用方法时都要判断当前是什么状态,不但会产出很多 if-else 语句,而且容易出错
-
符合 OCP开闭原则:容易增删状态
-
缺点:会产生很多类:每个状态都要一个对应的类,当状态过多时会产生很多类,加大维护难度
-
应用场景:当一个事件或者对象有很多种状态,状态之间会相互转换,对不同的状态要求有不同的行为的时候, 可以考虑使用状态模式