设计模式(十六)——状态模式

Posted 知止

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式(十六)——状态模式相关的知识,希望对你有一定的参考价值。

1.描述

允许一个对象在其内部状态改变时改变他的行为,对象看起来似乎修改了他的类。

2.模式的使用

·环境(Context):环境是一个类,该类含有抽象状态(State)的声明,可以引用任何具体状态类的实例。用户对该环境(Context)类的实例在某种状态下的行为感兴趣。

·抽象状态(State):抽象状态是一个接口或抽象类。抽象状态中定义了与环境(Context)的一个特定状态相关的若干个方法。

·具体状态(Concrete State):具体状态是实现(扩展)抽象状态的类。

3.使用情景

·一个对象的行为依赖他的状态,并且他必须在运行时根据状态改变他的行为。

·需要编写大量的条件分支语句来决定一个操作的行为,并且这些条件恰好表示对象的一种状态。

4.优点

·容易增加新的状态。

·环境(Context)中不必出现大量条件语句。

·可以让用户方便的切换环境(Context)实例的状态。

·避免环境(Context)实例出现内部状态不一致的情况。

·当状态对象没有实例变量时,环境(Context)的各个实例可以共享一个状态对象。

5.UML

 

6案例

案例一

一个温度计(环境),在不同温度(状态)时显示不同信息。

 

 1 package 状态模式;
 2 
 3 public class test1 {
 4 
 5     public static void main(String[] args) {
 6         Thermometer t = new Thermometer();
 7         HeightState h = new HeightState(20);
 8         LowState l = new LowState(-20);
 9         t.setState(h);
10         t.show();
11         t.setState(l);
12         t.show();
13     }
14 
15 }
16 
17 /*
18  * 环境
19  */
20 class Thermometer {
21     TemperatureState state;
22     public void setState(TemperatureState temperatureState){
23         this.state = temperatureState;
24     }
25     public void show(){
26         System.out.println("**********");
27         state.showTemperature();
28         System.out.println("**********");
29     }
30 }
31 
32 /*
33  * 抽象状态
34  */
35 interface TemperatureState {
36     public void showTemperature();
37 }
38 
39 /*
40  * 具体状态
41  */
42 class LowState implements TemperatureState {
43     double n = 0;
44     LowState(double n){
45         if(n <= 0)
46             this.n = n;
47     }
48     public void showTemperature() {
49         System.out.println("现在的温度是:" + n + "°,属于低温");    
50     }
51     
52 }
53 
54 /*
55  * 具体状态
56  */
57 class HeightState implements TemperatureState {
58     double n = 0;
59     HeightState(double n){
60         if(n > 0)
61             this.n = n;
62     }
63     public void showTemperature() {
64         System.out.println("现在的温度是:" + n + "°,属于高温");    
65     }
66     
67 }

 

 

案例二:状态切换(环境实例在某种状态下执行一个方法后,可能导致该实例的状态发生变化)

一把枪(环境),有2颗子弹、一颗子弹、无子弹三种状态,有开枪和装弹两种操作。在有子弹时才能开枪,在无子弹时才能装弹。

  1 package 状态模式;
  2 
  3 public class test2 {
  4 
  5     public static void main(String[] args) {
  6         Gun gun = new Gun();
  7         gun.fire();
  8         gun.fire();
  9         gun.fire();
 10         gun.load();
 11     }
 12 
 13 }
 14 
 15 /*
 16  * 环境
 17  */
 18 class Gun {
 19     State state1, state2, state3;
 20     State state;
 21     Gun(){
 22         this.state1 = new State1(this);
 23         this.state2 = new State2(this);
 24         this.state3 = new State3(this);
 25         state = state1;
 26     }
 27     
 28     public void setState(State state){
 29         this.state = state;
 30     }
 31 
 32     public State getState1() {
 33         return state1;
 34     }
 35 
 36     public State getState2() {
 37         return state2;
 38     }
 39 
 40     public State getState3() {
 41         return state3;
 42     }
 43 
 44     public State getState() {
 45         return state;
 46     }
 47     
 48     public void fire(){
 49         state.fire();
 50     }
 51     
 52     public void load(){
 53         state.loadBullet();
 54     }
 55 }
 56 
 57 /*
 58  * 抽象状态
 59  */
 60 interface State {
 61     public void fire();
 62     public void loadBullet();
 63     public String showStateMess();
 64 }
 65 
 66 /*
 67  * 具体状态
 68  */
 69 class State1 implements State {
 70     Gun gun;
 71     State1(Gun gun){
 72         this.gun = gun;
 73     }
 74     public void fire() {
 75         // TODO Auto-generated method stub
 76         System.out.println("射出一颗子弹");
 77         gun.setState(gun.getState2());
 78         System.out.println("进入" + gun.getState2().showStateMess());
 79     }
 80 
 81     public void loadBullet() {
 82         // TODO Auto-generated method stub
 83         
 84     }
 85 
 86     public String showStateMess() {
 87         // TODO Auto-generated method stub
 88         return "2颗子弹状态";
 89     }
 90     
 91 }
 92 
 93 /*
 94  * 具体状态
 95  */
 96 class State2 implements State {
 97     Gun gun;
 98     State2(Gun gun){
 99         this.gun = gun;
100     }
101     public void fire() {
102         // TODO Auto-generated method stub
103         System.out.println("射出一颗子弹");
104         gun.setState(gun.getState3());
105         System.out.println("进入" + gun.getState3().showStateMess());
106     }
107 
108     public void loadBullet() {
109         System.out.println("无法装弹");
110         
111     }
112 
113     public String showStateMess() {
114         // TODO Auto-generated method stub
115         return "一颗子弹状态";
116     }
117     
118 }
119 
120 /*
121  * 具体状态,空弹夹
122  */
123 class State3 implements State {
124     Gun gun;
125     State3(Gun gun){
126         this.gun = gun;
127     }
128     public void fire() {
129         // TODO Auto-generated method stub
130         System.out.println("无法射出子弹");
131         System.out.println("目前是" + showStateMess() + "");
132     }
133 
134     public void loadBullet() {
135         System.out.println("装弹");
136         gun.setState(gun.getState1());
137         System.out.println("进入" + gun.getState1().showStateMess());
138     }
139 
140     public String showStateMess() {
141         // TODO Auto-generated method stub
142         return "无子弹状态";
143     }
144     
145 }

 

案例三:共享状态(多个实例共享同一个状态)

一列火车的各个车厢同时处于运动状态或静止状态,为了实现这个目的需要将状态设置为静态变量。

 1 package 状态模式;
 2 
 3 public class test3 {
 4 
 5     public static void main(String[] args) {
 6         Vehicle car1 = new Vehicle("卧铺车厢");
 7         Vehicle car2 = new Vehicle("硬座车厢");
 8         car1.startUp();
 9         car2.startUp();
10         car2.stop();
11         car1.stop();
12     }
13 
14 }
15 
16 /*
17  * 环境
18  */
19 class Vehicle {
20     static StateOne moveState, stopState;
21     static StateOne state;
22     String name;
23     Vehicle(String name){
24         this.name = name;
25         this.moveState = new VehicleMoveState();
26         this.stopState = new VehicleStopState();
27         state = stopState;
28     }
29     
30     public void startUp(){
31         state.startUp(this);
32     }
33     
34     public void stop(){
35         state.stop(this);
36     }
37     
38     public void setState(StateOne state){
39         this.state = state;
40     }
41 
42     public static StateOne getMoveState() {
43         return moveState;
44     }
45 
46     public static StateOne getStopState() {
47         return stopState;
48     }
49 
50     public static StateOne getState() {
51         return state;
52     }
53 
54     public String getName() {
55         return name;
56     }
57 }
58 
59 /*
60  * 抽象状态
61  */
62 interface StateOne {
63     public void startUp(Vehicle vehicle);
64     public void stop(Vehicle vehicle);
65 }
66 
67 class VehicleMoveState implements StateOne{
68 
69     public void startUp(Vehicle vehicle) {
70         System.out.println(vehicle.getName() + "已经在运动状态");
71     }
72 
73     public void stop(Vehicle vehicle) {
74         System.out.println(vehicle.getName() + "停止运动");
75         vehicle.setState(vehicle.getStopState());
76     }
77     
78 }
79 
80 class VehicleStopState implements StateOne{
81 
82     public void startUp(Vehicle vehicle) {
83         System.out.println(vehicle.getName() + "开始运动");
84         vehicle.setState(vehicle.getMoveState());
85     }
86 
87     public void stop(Vehicle vehicle) {
88         System.out.println(vehicle.getName() + "已经在静止状态");
89     }
90     
91 }

 

以上是关于设计模式(十六)——状态模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式(十六)——状态模式

两种语言实现设计模式(C++和Java)(十六:状态模式)

23种设计模式(十六)——备忘录模式状态变化

(十六)设计模式总结

设计模式(十六)——观察者模式

Java 设计模式系列(十六)观察者模式(Observer)