设计模式笔记--状态模式

常用设计模式有23中,分为:

创建型模式(主要用于创建对象)

1、单例模式    2、工厂方法模式    3、抽象工厂模式    4、建造者模式     5、原型模式 
行为型模式 (主要用于描述对象或类是怎样交互和怎样分配职责)

1、模板方法模式  2、中介者模式  3、命令模式    4、责任链模式   5、策略模式   6、迭代器模式  

7、观察者模式      8、备忘录模式   9、访问者模式   10、状态模式   11、解释器模式

结构型模式(主要用于处理类或对象的组合)

1、代理模式  2、装饰模式   3、适配器模式   4、组合模式   5、外观模式(门面模式)   6、享元模式    7、桥梁模式



状态模式  

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

状态模式的核心是封装,状态的变更引起了行为的变更,从外部看起来就好像这个对象对应的类发生了改变一样  
设计模式笔记--状态模式_第1张图片


状态模式中的3个角色。

● State——抽象状态角色
接口或抽象类,负责对象状态定义,并且封装环境角色以实现状态切换。

● ConcreteState——具体状态角色
每一个具体状态必须完成两个职责:本状态的行为管理以及趋向状态处理,通俗地说,就是本状态下要做的事情,以及本状态如何过渡到其他状态。

● Context——环境角色
定义客户端需要的接口,并且负责具体状态的切换。  


状态模式相对来说比较复杂,它提供了一种对物质运动的另一个观察视角,通过状态变更促使行为的变化  


抽象环境角色,如代码清单26-14所示。
代码清单26-14 抽象环境角色
public abstract class State {
//定义一个环境角色,提供子类访问
protected Context context;
//设置环境角色
public void setContext(Context _context){
this.context = _context;
}
//行为1
public abstract void handle1();
//行为2
public abstract void handle2();
}
抽象环境中声明一个环境角色,提供各个状态类自行访问,并且提供所有状态的抽象行为,由各个实现类实现。


具体环境角色如代码清单26-15所示。
代码清单26-15 环境角色
public class ConcreteState1 extends State {
@Override
public void handle1() {
//本状态下必须处理的逻辑
}
@Override
public void handle2() {
//设置当前状态为stat2
super.context.setCurrentState(Context.STATE2);
//过渡到state2状态,由Context实现
super.context.handle2();
}
}
public class ConcreteState2 extends State {
@Override
public void handle1() {
//设置当前状态为state1
super.context.setCurrentState(Context.STATE1);
//过渡到state1状态,由Context实现
super.context.handle1();
}
@Override
public void handle2() {
//本状态下必须处理的逻辑
}
}
具体环境角色有两个职责:处理本状态必须完成的任务,决定是否可以过渡到其他状态。


我们再来看环境角色,如代码清单26-16所示。
代码清单26-16 具体环境角色
public class Context {
//定义状态
public final static State STATE1 = new ConcreteState1();
public final static State STATE2 = new ConcreteState2();
//当前状态
private State CurrentState;
//获得当前状态
public State getCurrentState() {
return CurrentState;
}
//设置当前状态
public void setCurrentState(State currentState) {
this.CurrentState = currentState;
//切换状态
this.CurrentState.setContext(this);
}
//行为委托
public void handle1(){
this.CurrentState.handle1();
}
public void handle2(){
this.CurrentState.handle2();
}
}
环境角色有两个不成文的约束:

● 把状态对象声明为静态常量,有几个状态对象就声明几个静态常量。

● 环境角色具有状态抽象角色定义的所有行为,具体执行使用委托方式。


我们再来看场景类如何执行,如代码清单26-17所示。
public class Client {
public static void main(String[] args) {
//定义环境角色
Context context = new Context();
//初始化状态
context.setCurrentState(new ConcreteState1());
//行为执行
context.handle1();
context.handle2();
}
}  

隐藏了状态的变化过程,它的切换引起了行为的变化。对外来说,我们只看到行为的发生改变,而不用知道是状态变化引起的。  


优点   

● 结构清晰  
避免了过多的switch...case或者if...else语句的使用,避免了程序的复杂性,提高系统的可维护性。 
 
● 遵循设计原则  

● 封装性非常好  


缺点  

子类会太多,也就是类膨胀。  


使用场景  

● 行为随状态改变而改变的场景 

● 条件、分支判断语句的替代者


注意事项  

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


建造模式+状态模式会起到非常好的封装作用。  


实例 电梯 


设计模式笔记--状态模式_第2张图片
设计模式笔记--状态模式_第3张图片


在类图中,定义了一个LiftState抽象类,声明了一个受保护的类型Context变量,这个是串联各个状态的封装类。封装的目的很明显,就是电梯对象内部状态的变化不被调用类知晓,也就是迪米特法则  


抽象电梯状态  
代码清单26-7 抽象电梯状态
public abstract class LiftState{
//定义一个环境角色,也就是封装状态的变化引起的功能变化
protected Context context;
public void setContext(Context _context){
this.context = _context;
}
//首先电梯门开启动作
public abstract void open();
//电梯门有开启,那当然也就有关闭了
public abstract void close();
//电梯要能上能下,运行起来
public abstract void run();
//电梯还要能停下来
public abstract void stop();
}


敞门状态的实现类  
代码清单26-8 敞门状态
public class OpenningState extends LiftState {
//开启当然可以关闭了,我就想测试一下电梯门开关功能
@Override
public void close() {
//状态修改
super.context.setLiftState(Context.closeingState);
//动作委托为CloseState来执行
super.context.getLiftState().close();
}
//打开电梯门
@Override
public void open() {
System.out.println("电梯门开启...");
}
//门开着时电梯就运行跑,这电梯,吓死你!
@Override
public void run() {
//do nothing;
}
//开门还不停止?
public void stop() {
//do nothing;
}
}


关闭状态  
public class ClosingState extends LiftState {
//电梯门关闭,这是关闭状态要实现的动作
@Override
public void close() {
System.out.println("电梯门关闭...");
}
//电梯门关了再打开
@Override
public void open() {
super.context.setLiftState(Context.openningState); //置为敞门状态
super.context.getLiftState().open();
}
//电梯门关了就运行,这是再正常不过了
@Override
public void run() {
super.context.setLiftState(Context.runningState); //设置为运行状态
super.context.getLiftState().run();
}
//电梯门关着,我就不按楼层
@Override
public void stop() {
super.context.setLiftState(Context.stoppingState); //设置为停止状态
super.context.getLiftState().stop();
}
}
另外两个实现类相识,不一一赘述


上下文类  
代码清单26-9 上下文类
public class Context {
//定义出所有的电梯状态
public final static OpenningState openningState = new OpenningState();
public final static ClosingState closeingState = new ClosingState();
public final static RunningState runningState = new RunningState();
public final static StoppingState stoppingState = new StoppingState();
//定义一个当前电梯状态
private LiftState liftState;
public LiftState getLiftState() {
return liftState;
}
public void setLiftState(LiftState liftState) {
this.liftState = liftState;
//把当前的环境通知到各个实现类中
this.liftState.setContext(this);
}
public void open(){
this.liftState.open();
}
public void close(){
this.liftState.close();
}
public void run(){
this.liftState.run();
}
public void stop(){
this.liftState.stop();
}
}


模拟场景类   
public class Client {
public static void main(String[] args) {
Context context = new Context();
context.setLiftState(new ClosingState());
context.open();
context.close();
context.run();
context.stop();
}
}




 

你可能感兴趣的:(Android之设计模式,状态模式,设计模式)