设计模式之禅之设计模式-状态模式

简介: 一:状态模式定义        --->当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类        --->状态模式的核心是封装,状态的变更引起了行为的变更,从外部看起来就好像这个对象对应的类发生了改变一样        --->状态模式相对来说比较复杂,它提供了一种对物质运动...

一:状态模式定义
        --->当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类
        --->状态模式的核心是封装,状态的变更引起了行为的变更,从外部看起来就好像这个对象对应的类发生了改变一样
        --->状态模式相对来说比较复杂,它提供了一种对物质运动的另一个观察视角,通过状态变更促使行为的变化,就类似水的状态变更一样,一碗水的初始状态是液态,通过加热转变为气态,状态的改变同时也引起体积的扩大,然后就产生了一个新的行为:鸣笛或顶起壶盖,瓦特就是这么发明蒸汽机的
        
二:状态模式角色

        ● State——抽象状态角色接口或抽象类
                负责对象状态定义,并且封装环境角色以实现状态切换。
        ● ConcreteState——具体状态角色
                每一个具体状态必须完成两个职责:本状态的行为管理以及趋向状态处理,通俗地说,就是本状态下要做的事情,以及本状态如何过渡到其他状态。
        ● Context——环境角色
                定义客户端需要的接口,并且负责具体状态的切换。


【*****】环境角色不成文的约束
        ● 把状态对象声明为静态常量,有几个状态对象就声明几个静态常量。
        ● 环境角色具有状态抽象角色定义的所有行为,具体执行使用委托方式。
三:状态模式的应用
【1】状态模式的优点
● 结构清晰
        避免了过多的switch...case或者if...else语句的使用,避免了程序的复杂性,提高系统的可维护性。
● 遵循设计原则
        很好地体现了开闭原则和单一职责原则,每个状态都是一个子类,你要增加状态就要增加子类,你要修改状态,你只修改一个子类就可以了。
● 封装性非常好
        这也是状态模式的基本要求,状态变换放置到类的内部来实现,外部的调用不用知道类内部如何实现状态和行为的变换。

【2】状态模式的缺点
        状态模式既然有优点,那当然有缺点了。但只有一个缺点,子类会太多,也就是类膨胀。如果一个事物有很多个状态也不稀奇,如果完全使用状态模式就会有太多的子类,不好管理,这个需要大家在项目中自己衡量。其实有很多方式可以解决这个状态问题,如在数据库中建立一个状态表,然后根据状态执行相应的操作,这个也不复杂,看大家的习惯和嗜好了。

【3】状态模式的使用场景
● 行为随状态改变而改变的场景
          这也是状态模式的根本出发点,例如权限设计,人员的状态不同即使执行相同的行为结果也会不同,在这种情况下需要考虑使用状态模式。
● 条件、分支判断语句的替代者
        在程序中大量使用switch语句或者if判断语句会导致程序结构不清晰,逻辑混乱,使用状态模式可以很好地避免这一问题,它通过扩展子类实现了条件的判断处理。


【4】状态模式的注意事项
        状态模式适用于当某个对象在它的状态发生改变时,它的行为也随着发生比较大的变化,也就是说在行为受状态约束的情况下可以使用状态模式,而且使用时对象的状态最好不要超过5个


四:状态模式的案例

【1】电梯四个状态所作的固定的反应

【1】电梯的状态抽象

 1 package com.yeepay.sxf.template21;
 2 /**
 3  * 抽象电梯状态
 4  * 
 5  * (1)依赖:环境角色
 6  * (2)不同状态下的行为
 7  * @author sxf
 8  *
 9  */
10 public  abstract class LiftState {
11 
12     //定义一个环境角色,也就是封装状态的变化引起功能的变化
13     protected Context context;
14     
15     public void setContext(Context context){
16         this.context=context;
17     }
18     //电梯的开启门行为
19     public abstract void open();
20     //电梯的关闭们行为
21     public abstract void close();
22     //电梯要能上能下,运行起来的行为
23     public abstract void run();
24     //电梯停下来的行为
25     public abstract void stop();
26 }
View Code

【2】环境角色

 1 package com.yeepay.sxf.template21;
 2 /**
 3  * 环境类(上下文类)
 4  * (1)依赖:电梯的状态
 5  * (2)同时具有电梯不同状态的行为,类似代理
 6  * @author sxf
 7  *
 8  */
 9 public class Context {
10 
11     //定义出电梯所有的状态
12     public final static OpenningState openningState=new OpenningState();
13     public final static ClosingState closingState=new ClosingState();
14     public final static RunningState runningState=new RunningState();
15     public final static StoppingState stoppingState=new StoppingState();
16     
17     //定义一个当前的电梯状态
18     private LiftState liftState;
19     
20     public LiftState getLiftState(){
21         return this.liftState;
22     }
23     
24     public void setLiftState(LiftState liftState){
25         this.liftState=liftState;
26         this.liftState.setContext(this);
27     }
28     //开启电梯门
29     public void open(){
30         this.liftState.open();
31     }
32     //关闭电梯门
33     public void close(){
34         this.liftState.close();
35     }
36     //停止电梯
37     public void stop(){
38         this.liftState.stop();
39     }
40     //运行电梯
41     public void run(){
42         this.liftState.run();
43     }
44 }
View Code

【3】电梯开启状态的实现类

 1 package com.yeepay.sxf.template21;
 2 /**
 3  * 电梯开启状态
 4  * @author sxf
 5  *
 6  */
 7 public class OpenningState extends LiftState {
 8     
 9 
10     //开启当然可以关闭了
11     @Override
12     public void open() {
13         System.out.println("OpenningState.open(电梯门开启......)");
14     }
15 
16     @Override
17     public void close() {
18         //修改状态
19         super.context.setLiftState(Context.closingState);
20         //动作委托为CloseState来执行
21         super.context.getLiftState().close();
22         
23     }
24 
25     //电梯门若是开着,则不能运行
26     @Override
27     public void run() {
28         //do nothing;
29     }
30     //电梯门是开着,则不能让其停止
31     @Override
32     public void stop() {
33         //do nothing
34     }
35 
36     
37 }
View Code

【4】电梯停止状态的实现类

 1 package com.yeepay.sxf.template21;
 2 /**
 3  * 电梯停止的行为
 4  * @author sxf
 5  *
 6  */
 7 public class StoppingState extends LiftState {
 8 
 9     
10 
11     //电梯处于停止状态是可以打开的
12     @Override
13     public void open() {
14         //将电梯的状态设置为打开
15         super.context.setLiftState(Context.openningState);
16         //执行打开的动作
17         super.context.getLiftState().open();
18     }
19 
20     //电梯处于停止状态,门本来就关着
21     @Override
22     public void close() {
23         //do nothing
24     }
25 
26     //电梯处于停止状态,再次运行起来很正常
27     @Override
28     public void run() {
29         //将电梯的状态设置为运行状态
30         super.context.setLiftState(Context.runningState);
31         //执行运行动作
32         super.context.getLiftState().run();
33     }
34 
35     //停止状态要实现的行为
36     @Override
37     public void stop() {
38         System.out.println("StoppingState.stop(电梯停止了.....)");
39     }
40 
41     
42 }
View Code

【5】电梯运行状态的实现类

 1 package com.yeepay.sxf.template21;
 2 /**
 3  * 电梯运行时的状态
 4  * @author sxf
 5  *
 6  */
 7 public class RunningState  extends LiftState{
 8 
 9     //运行时,电梯门不允许打开。
10     @Override
11     public void open() {
12         //do nothing
13     }
14     //运行时,电梯门关闭,这是正常的。
15     @Override
16     public void close() {
17         //do nothing
18     }
19 
20     //运行状态下,要实现的行为
21     @Override
22     public void run() {
23         System.out.println("RunningState.run(电梯上下运动.....)");
24     }
25 
26     //这是合理的。运行时,是可以停止的
27     @Override
28     public void stop() {
29         //将电梯的状态设置为停止状态
30         super.context.setLiftState(context.stoppingState);
31         //执行停止的动作
32         super.context.getLiftState().stop();
33     }
34 
35     
36 }
View Code

【6】电梯关闭状态的实现类

 1 package com.yeepay.sxf.template21;
 2 /**
 3  * 电梯关闭的状态
 4  * @author sxf
 5  *
 6  */
 7 public class ClosingState extends LiftState {
 8 
 9 
10     //电梯门关了再打开
11     @Override
12     public void open() {
13         //将电梯门的状态该为打开状态
14         super.context.setLiftState(Context.openningState);
15         //执行相应的动作
16         super.context.getLiftState().open();
17     }
18 
19     //电梯们关闭,这是关闭状态要实现的动作
20     @Override
21     public void close() {
22         System.out.println("ClosingState.close(电梯门关闭.....)");
23     }
24 
25     //电梯门关了就运行,这是再正常不过了
26     @Override
27     public void run() {
28         //将电梯门的状态改为运行状态
29         super.context.setLiftState(context.runningState);
30         //执行运行状态的动作
31         super.context.getLiftState().run();
32     }
33 
34     //电梯门关着,我就不按楼层
35     @Override
36     public void stop() {
37         //将电梯门的状态改为停止状态
38         super.context.setLiftState(context.stoppingState);
39         //执行停止动作
40         super.context.getLiftState().stop();
41     }
42 
43     
44 }
View Code

【4】客户端测试

 1 package com.yeepay.sxf.template21;
 2 /**
 3  * 客户端测试
 4  * @author sxf
 5  *
 6  */
 7 public class ClientTest {
 8 
 9     public static void main(String[] args) {
10         //初始化上下文环境
11         Context context=new Context();
12         //设置初始化状态
13         context.setLiftState(Context.closingState);
14         //打开门
15         context.open();
16         //运行
17         context.run();
18         //关闭门
19         context.close();
20         //停止门
21         context.stop();
22         
23     }
24 }
View Code

 

相关文章
|
7月前
|
设计模式
设计模式之 State(状态模式)
设计模式之 State(状态模式)
45 0
|
3月前
|
设计模式 Java 测试技术
Java设计模式-状态模式(18)
Java设计模式-状态模式(18)
|
4月前
|
设计模式 网络协议 Java
【十五】设计模式~~~行为型模式~~~状态模式(Java)
文章详细介绍了状态模式(State Pattern),这是一种对象行为型模式,用于处理对象在其内部状态改变时的行为变化。文中通过案例分析,如银行账户状态管理和屏幕放大镜工具,展示了状态模式的应用场景和设计方法。文章阐述了状态模式的动机、定义、结构、优点、缺点以及适用情况,并提供了Java代码实现和测试结果。状态模式通过将对象的状态和行为封装在独立的状态类中,提高了系统的可扩展性和可维护性。
【十五】设计模式~~~行为型模式~~~状态模式(Java)
|
5月前
|
设计模式 JavaScript Go
js设计模式【详解】—— 状态模式
js设计模式【详解】—— 状态模式
90 7
|
6月前
|
设计模式
状态模式-大话设计模式
状态模式-大话设计模式
|
6月前
|
设计模式 存储
行为设计模式之状态模式
行为设计模式之状态模式
|
7月前
|
设计模式 Go
[设计模式 Go实现] 行为型~状态模式
[设计模式 Go实现] 行为型~状态模式
|
7月前
|
设计模式 Java
23种设计模式,状态模式的概念优缺点以及JAVA代码举例
【4月更文挑战第9天】状态模式是一种行为设计模式,允许一个对象在其内部状态改变时改变它的行为,这个对象看起来似乎修改了它的类。
61 4
|
7月前
|
设计模式 JavaScript Java
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
|
7月前
|
设计模式 Java
【设计模式系列笔记】状态模式
在Java中,状态模式是一种行为设计模式,它允许对象在其内部状态改变时改变其行为。状态模式的关键思想是将对象的状态封装成独立的类,并将对象的行为委托给当前状态的对象。这样,当对象的状态发生变化时,其行为也会相应地发生变化。
80 0