欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android 中设计模式 ----状态模式

程序员文章站 2022-07-03 11:40:00
Android 中设计模式 ----状态模式。 首先来看下状态模式的UML 类图: 看过UML 类图,是不是发现跟策略模式的UML类图基本一样,只不过是抽象接口一个是Str...

Android 中设计模式 ----状态模式。


首先来看下状态模式的UML 类图:
看过UML 类图,是不是发现跟策略模式的UML类图基本一样,只不过是抽象接口一个是Stragety,一个是State。从结构上可能还无法区分两者,后面解释两者的区别。

组成:

Context:环境类,用于客户端调用,会有个State 的引用,这个引用代表着当前状态。 State:状态模式的抽象类,提供各种状态的抽象接口。 ConcreteState:状态的实现类,不同的行为在不同的状态类中会有不一样的处理方式。

简单示例:
用电视和遥控器为例,电视在开的时候可以关机,可以换台,可以调节音量,但是在关的时候只能开机。
对于开机和关机两种状态,同样的行为会有不一样的处理方式。
来看下State类:

public interface TvState {
    void tvOn();
    void tvOff();
    void nextChannel();
    void preChannel();
}

public class OnState implements TvState {
    @Override
    public void tvOn() {

    }

    @Override
    public void tvOff() {
        System.out.println("关机");
    }

    @Override
    public void nextChannel() {
        System.out.println("下个频道");
    }

    @Override
    public void preChannel() {
        System.out.println("上个频道");
    }
}

public class OffState implements TvState {
    @Override
    public void tvOn() {
        System.out.println("开机");
    }

    @Override
    public void tvOff() {

    }

    @Override
    public void nextChannel() {

    }

    @Override
    public void preChannel() {

    }
}

再来看下Context 类:

public class Controller {
    private TvState mState;

    public Controller(TvState state) {
        this.mState = state;
    }

    public void setState(TvState state){
        this.mState=state;
    }

    public void turnOn(){
        mState = new OnState();
        mState.tvOn();
    }
    public void turnOff(){
        mState = new OffState();
        mState.tvOff();
    }
    public void nextChannel(){
        mState.nextChannel();
    }
    public void preChannel(){
        mState.preChannel();
    }
}

其实对于状态模式,客户端并不一定要知道当前状态,Context只需要提供给Client 一定的接口使用。
例如,同样用上面的例子,用户按遥控器调节音量,Context中来处理状态,如果当前TV 为on,那么当然音量是可以调节的,如果是TV是off,电视可能用个红灯提示当前TV 是off 状态。也就是说当前TV 的状态在Context 中控制即可,Client端并不一定要关心。

状态模式的优点:
将所有跟一个特定状态相关的行为都放入到一个状态对象中,提供了一个更好的方式来组织和管理与特定状态相关的代码,将繁琐的状态判断转换成结构清晰的状态类族,在避免代码膨胀的同时也保证了可扩展性和可维护性。
缺点:
必然会增加系统类的个数和对象的个数。

状态模式和策略模式的区别:
1、状态模式是跟状态密切相关,同样的行为可能不同的状态会有不同的处理方式,状态是平行的。
策略模式是根据策略分类,不同的策略,不同的算法会使用不同的策略,策略间是相互独立的。
2、对于Client 端两种模式是两种不同的存在方式
状态模式中不同的状态类在Client端并不需要出现,Client 只需要调用Context的接口就可以。
策略模式中不同的策略必须是在Client 端出现的,Client会根据不同的需要选择不同的策略,这一点Context 无法去控制。
3、两种模式Context 类控制方式不同
状态模式中不同的状态类不需要在Client 中出现,Client只需要操作接口,例如上面例子中电视的频道调节,Client 只需要调用nextChannel() 即可,所以Context 的构造函数可以将State 作为参数,也可以不将其作为参数传入。
策略模式中Client 必须要知道策略,所以Context的构造函数或者其他接口必须要将Stragety 作为参数传入。