Android--状态模式

关于设计模式的文章,后续依次会更新,这里先放个彩蛋。
学习设计模式,一定要有自己的想法并在项目运用起来才能体验到它强大的好处,不然都是自嗨,俺第一次使用这个模式的时候是在做手游的时候,当时在军团战的时候,会出现多达7个状态,并且是依次连续出现,不能跳过。这些是题外话了,下面正式分析这个模式。

状态模式和适用的场景


  • 类中定义了很多条件判断语句来进行不同的切换,并且下一个状态的切换是由上一个状态触发的
  • 不想把具体的状态实现细节,数据结构暴露给调用者。
  • 方便新增新的状态,也即方便扩展

这种说法好似放之四海而皆准,太过朦胧,有点雾里看花。下面使用一个网上下单的例子进行说明。下单的流程图如下:

Created with Raphaël 2.1.2 开始 搜索商品并下单 商家付款 核对定单信息 发货 结束

在操作订单的时候,有一个很明显的特性,就是订单的状态不能随机跳跃,如果从“商品下单之后” 直接跳到 发货状态,那你老板,肯定会杀了你这个程序员来祭天。。。。。

状态模式角色分析


  • 具体的状态类,这个可以上面这个流程图可以看出,在程序的角度,可以把各个状态抽象为一个类,这个类就用来处理这个状态所有的业务
  • 为了使得具体的状态类乱来(乱定义函数接口),需要一个小组长来规范它的 行为(当然具体的行为,这个小组长无权过问,你只要在它规定的范围内干活,就没事 )接口规范类,暂且给它命名为:BaseOrderState
  • 有了小组长之后,还需要一个调度员,它的角色就是告诉小组长,什么时候用什么状态,小组长收到通知之后就需要拿出具体的状态来应对,暂且将这个调度员命名为:StateContext

具体的代码实现


调度员类—状态管理类

public class StateContext {

    private BaseOrderState state;

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

    public void nextState(){
        this.state.nextState(this);
    }

    public void preState(){
        this.state.preState(this);
    }

    public String getCurState(){

        String curState = this.state.getCurState();
        System.out.println("27--------------State:"+curState);
        return this.state.getCurState();
    }
}

小组长类—具体状态函数接口约束类

/**
 * Created by liuxiaobing on 13/07/2018.
 *  所有订单的 基类,订单类,均需要扩展此类
 *  订单状态为:预订---》 付款---》 核对--》 发货
 */

public abstract class BaseOrderState {

    private StateContext context;

    public abstract void nextState(StateContext context);

    public abstract void preState(StateContext context);

    public abstract String getCurState();
}

具体状态类—预订状态

public class BookingState extends BaseOrderState {

    private static BookingState mState;
    public static BookingState getInstance(){
        if(mState == null){
            mState = new BookingState();
        }
        return mState;
    }


    /*预订状态下一个状态 付款状态*/
    @Override
    public void nextState(StateContext context) {
        context.setState(PayState.getInstance());
    }

    @Override
    public void preState(StateContext context) {

        System.out.println("-----回到了订单的初始状态了,没有上一个状态");
    }

    @Override
    public String getCurState() {
        return BookingState.class.getName();
    }
}

具体状态类—付款状态

public class PayState extends BaseOrderState {

    private static PayState mState;
    public static PayState getInstance(){
        if(mState == null){
            mState = new PayState();
        }
        return mState;
    }


    @Override
    public void nextState(StateContext context) {
        context.setState(CheckState.getInstance());
    }

    @Override
    public void preState(StateContext context) {
        context.setState(BookingState.getInstance());
    }

    @Override
    public String getCurState() {
        return PayState.class.getName();
    }
}

具体状态类—核对状态

public class CheckState extends BaseOrderState{

    private static CheckState mState;

    public static CheckState getInstance(){
        if(mState == null){
            mState = new CheckState();
        }
        return mState;
    }
    @Override
    public void nextState(StateContext context) {
        context.setState(DeliveryState.getInstance());
    }

    @Override
    public void preState(StateContext context) {
        context.setState(PayState.getInstance());
    }

    @Override
    public String getCurState() {
        return CheckState.class.getName();
    }
}

具体状态类—发货状态

public class DeliveryState extends BaseOrderState {

    private static DeliveryState mState;

    public static DeliveryState getInstance(){
        if(mState == null){
            mState = new DeliveryState();
        }
        return mState;
    }

    public DeliveryState(){
        try {
            throw new Exception("请走单例获取实例模式");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public void nextState(StateContext context) {
        System.out.println("29----------订单流程快要走完了,没有下一个状态");
    }

    @Override
    public void preState(StateContext context) {
        context.setState(CheckState.getInstance());
    }

    @Override
    public String getCurState() {
        return DeliveryState.this.getClass().getName();
    }
}

测试类:

package com.example.liuxiaobing.statemodel;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

import com.example.liuxiaobing.statemodel.state_model2.BookingState;
import com.example.liuxiaobing.statemodel.state_model2.StateContext;
import com.example.liuxiaobing.statemodel.statemodel.BlackState;
import com.example.liuxiaobing.statemodel.statemodel.Context;

public class MainActivity extends AppCompatActivity {

    private StateContext mStateMgr;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView(){
        mStateMgr = new StateContext();
        mStateMgr.setState(BookingState.getInstance());
        findViewById(R.id.next_state).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mStateMgr.nextState();
            }
        });

        findViewById(R.id.pre_state).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mStateMgr.preState();
            }
        });

        findViewById(R.id.cur_state).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mStateMgr.getCurState();
            }
        });
    }
}

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.liuxiaobing.statemodel.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal">

        <Button
            android:id="@+id/next_state"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="next_state"/>

        <Button
            android:id="@+id/pre_state"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="pre_state"/>

        <Button
            android:id="@+id/cur_state"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="cur_state"/>


    </LinearLayout>

</android.support.constraint.ConstraintLayout>

测试ui:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/d06110902002/article/details/81027097