别院牧志知识库 别院牧志知识库
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2025 面试记录
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2025 面试记录
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 辨析

  • Sockets编程

  • Django

  • stackoverflow

  • Flask

  • 全栈之路

  • 面试

  • 代码片段

  • 异步编程

  • 😎Awesome资源

  • PEP

  • Python工匠系列

  • 高阶知识点

  • Python 学习资源待整理
  • 设计模式

    • Python 设计模式
    • 装饰器模式
    • 抽象工厂模式
    • 建造者模式/生成器模式
    • 原型模式
    • 单例模式
    • 设计模式(2)——工厂方法模式
    • 设计模式(3)——抽象工厂模式
    • 设计模式(4)——模板方法模式
    • 设计模式(5)——代理模式
    • 设计模式(6)——建造者模式
    • 设计模式(7)——策略模式
    • 设计模式(8)——命令模式
    • 设计模式(9)——原型模式
    • 设计模式(10)——中介者模式
    • 设计模式(11)——责任链模式
    • 设计模式(12)——装饰器模式
    • 设计模式(13)——适配器模式
    • 设计模式(14)——迭代器模式
    • 设计模式(15)——观察者模式
    • 设计模式(16)——外观模式
    • 设计模式(17)——状态模式
      • 基本思想和原则
      • 动机
      • 实现
      • 优点
      • 缺点
    • 设计模式(18)——桥接模式
    • 设计模式(19)——享元模式
    • 设计模式(20)——解释器模式
    • 设计模式(21)——组合模式
    • 设计模式(23)——备忘录模式
    • Python 全栈之路系列之单例设计模式
    • 设计模式(22)——访问者模式
    • 工厂方法模式
    • Python 设计模式资源收集
  • 好“艹蛋”的 Python 呀!
  • FIFO | 待学清单📝
  • pip 安装及使用
  • 数据分析

  • 源码阅读计划

  • OOP

  • 关于 python 中的 setup.py
  • 并行分布式框架 Celery
  • 七种武器,让你的代码提高可维护性
  • 使用 pdb 调试 Python 代码
  • 每周一个 Python 标准库
  • 🐍Python
  • 设计模式
佚名
2017-12-19
目录

设计模式(17)——状态模式

本文介绍状态模式的概念和应用。

# 基本思想和原则

当一个对象内在状态改变时允许改变其行为,这个对象看起来像改变了其类。

# 动机

当某个对象的状态改变时,其行为也会发生改变,就可以考虑使用状态模式来处理。

# 实现

我们用一个水三态转换的例子来说明状态模式,正常情况水有三种形态:液态、固态和气态,分别对应水、冰和水蒸气。水的三态转换过程如下图:

水的三态转换

三种状态之间可以任意转换,我们下面就模拟这个过程。

public abstract class WaterState {
    protected Context context;

    public void setContext(Context context) {
        this.context = context;
    }

    // 液化
    public abstract void liquefy();

    // 汽化
    public abstract void evaporate();

    // 凝固
    public abstract void freeze();

    // 熔化
    public abstract void melt();

    // 凝华
    public abstract void desublimate();

    // 升华
    public abstract void sublimate();
}

public class LiquidState extends WaterState {
    @Override
    public void liquefy() {
        System.out.println("水蒸气->水:液化过程");
    }

    @Override
    public void evaporate() {
        this.context.setCurrentState(Context.gasState);
        this.context.getCurrentState().evaporate();
    }

    @Override
    public void freeze() {
        this.context.setCurrentState(Context.solidState);
        this.context.getCurrentState().freeze();
    }

    @Override
    public void melt() {
        System.out.println("冰->水:熔化过程");
    }

    @Override
    public void desublimate() {
        // do nothing
    }

    @Override
    public void sublimate() {
        // do nothing
    }
}

public class SolidState extends WaterState {
    @Override
    public void liquefy() {
        // do nothing
    }

    @Override
    public void evaporate() {
        // do nothing
    }

    @Override
    public void freeze() {
        System.out.println("水->冰:凝固过程");
    }

    @Override
    public void melt() {
        this.context.setCurrentState(Context.liquidState);
        this.context.getCurrentState().melt();
    }

    @Override
    public void desublimate() {
        System.out.println("水蒸气->冰:凝华过程");
    }

    @Override
    public void sublimate() {
        this.context.setCurrentState(Context.gasState);
        this.context.getCurrentState().sublimate();
    }
}

public class GasState extends WaterState {
    @Override
    public void liquefy() {
        this.context.setCurrentState(Context.liquidState);
        this.context.getCurrentState().liquefy();
    }

    @Override
    public void evaporate() {
        System.out.println("水->水蒸气:气化过程");
    }

    @Override
    public void freeze() {
        // do nothing
    }

    @Override
    public void melt() {
        // do nothind
    }

    @Override
    public void desublimate() {
        this.context.setCurrentState(Context.solidState);
        this.context.getCurrentState().desublimate();
    }

    @Override
    public void sublimate() {
        System.out.println("冰->水蒸气:升华过程");
    }
}

public class Context {
    private WaterState currentState;
    public final static WaterState liquidState = new LiquidState();
    public final static WaterState solidState = new SolidState();
    public final static WaterState gasState = new GasState();

    public void setCurrentState(WaterState currentState) {
        this.currentState = currentState;
        this.currentState.setContext(this);
    }

    public WaterState getCurrentState() {
        return this.currentState;
    }

    public void liquefy() {
        this.currentState.liquefy();
    }

    public void evaporate() {
        this.currentState.evaporate();
    }

    public void freeze() {
        this.currentState.freeze();
    }

    public void melt() {
        this.currentState.melt();
    }

    public void desublimate() {
        this.currentState.desublimate();
    }

    public void sublimate() {
        this.currentState.sublimate();
    }
}

public class Test {
    public static void main(String[] args) {
        Context context = new Context();
        context.setCurrentState(new LiquidState());

        context.evaporate();    // 水->水蒸气:汽化过程
        context.desublimate();  // 水蒸气->冰:凝华过程
        context.melt();         // 冰->水:熔化过程
        context.freeze();       // 水->冰:凝固过程
        context.sublimate();    // 冰->水蒸气:升华过程
        context.liquefy();      // 水蒸气->水:液化过程
    }
}
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181

输出如下:

水->水蒸气:气化过程
水蒸气->冰:凝华过程
冰->水:熔化过程
水->冰:凝固过程
冰->水蒸气:升华过程
水蒸气->水:液化过程
1
2
3
4
5
6

简单分析一下这个例子,我们有一个 State 的继承体系,WaterState是一个抽象类,定义了所有状态间转换的方法,并且在内部持有一个Context类实例,这个实例在状态转换过程中会使用到。LiquidState、SolidState和GasState是具体的状态类,需要实现WaterState定义的所有抽象方法。Context类持有一个状态实例currentState,表示水当前的状态,很重要的一点是Context类中也定义了所有状态转换的方法,调用时会委托给currentState来处理。

# 优点

状态模式避免了过多的 switch-case 和 if-else 语句,代码清晰。符合开闭原则、单一职责原则,当需要增加状态时,只需要增加子类,不需要修改原有的代码。封装性很好,外部不需要了解状态之间具体是如何转换的,所有的状态间过渡方式都由各个状态子类负责。

# 缺点

状态模式的缺点是有可能会导致过多的状态子类。

编辑 (opens new window)
#设计模式
上次更新: 2024-07-23, 01:00:43
设计模式(16)——外观模式
设计模式(18)——桥接模式

← 设计模式(16)——外观模式 设计模式(18)——桥接模式→

最近更新
01
2025 面试记录
05-28
02
提升沟通亲和力的实用策略
03-26
03
工作
07-15
更多文章>
Theme by Vdoing | Copyright © 2019-2025 IMOYAO | 别院牧志
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式