Java状态模式

状态模式:

允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。其别名为状态对象(Object for States),状态模式是一种对象行为型模式。《设计模式的艺术》

角色分析:

Context(环境类):环境类拥有各种不同状态的对象,作为外部使用的接口,负责调用状态类接口。
State(抽象状态):抽象状态既可以为抽象类,也可以直接定义成接口。主要用于定义状态抽象方法,具体实现由子类负责。
ConcreteState(具体状态类):具体状态类为抽象状态的实现者,不同的状态类对应这不同的状态,其内部实现也不相同。环境类中使用不同状态的对象时,能实现不同的处理逻辑。

很明显,处理逻辑的不是环境,而是各个状态。通过各个状态的处理,从而把逻辑流程处理完。

接下来我们就以一次网络连接作为示例,

网络请求过程一般为如下逻辑

步骤1: 初始化,看看符不符合连接协议,如果符合就到步骤2,如果不符合就到步骤5

步骤2:正式连接,连接成功,到步骤3,如果连接不成功就到步骤6

步骤3:连接成功,处理请求,处理完成到步骤4

步骤4:断开连接。

步骤5:连接失败

步骤6:尝试重连。连接成功到步骤3,连接不成功到步骤5

接下来我们就写代码来实现状态模式:

首先是简单的请求封装

public class MyRequest {

    private String url; // 请求地址

    private String method; // 请求方法

    private boolean isMethodNessary; // 是否需要请求方法

    public boolean isMethodNessary() {
        return isMethodNessary;
    }

    public void setMethodNessary(boolean methodNessary) {
        isMethodNessary = methodNessary;
    }

    public MyRequest(String url, String method, boolean isMethodNessary) {
        this.url = url;
        this.method = method;
        this.isMethodNessary = isMethodNessary;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getMethod() {
        return method;
    }

    public void setMethod(String method) {
        this.method = method;
    }
}

接下来是抽象的连接状态:

public interface ConnectState {

    void handleRequest(MyRequest request);

}

下面要实现6种连接状态:

初始化状态:

class InitState implements ConnectState{

    private ConnectMachine connectMachine;

    private boolean tryResult;

    public InitState(ConnectMachine connectMachine) {
        this.connectMachine = connectMachine;
    }

    @Override
    public void handleRequest(MyRequest myRequest) {
        tryConnect(myRequest);
    }

    /**
     * 初始化后,如果成功,就去连接,不成功就连接失败
     */
    private void tryConnect(MyRequest myRequest) {
        // 尝试去连接
        this.tryResult = this.tryToConnect(myRequest);
        if (this.tryResult) {
            this.connectMachine.goConnect(myRequest);
        } else {
            this.connectMachine.connectFailure(myRequest);
        }
    }

    /**
     * 初始化连接方法
     * 判断请求有没有url参数,有反true,无反false
     */
    private boolean tryToConnect(MyRequest myRequest){
        System.out.println("与"+ myRequest.getUrl() +"连接初始化。。。。。");
        if (myRequest.getUrl() != null){
            return true;
        }else{
            return false;
        }
    }
}

连接状态:

public class ConnectingState implements ConnectState {

    private ConnectMachine connectMachine;

    private boolean connectResult;

    public ConnectingState(ConnectMachine connectMachine) {
        this.connectMachine = connectMachine;
    }

    @Override
    public void handleRequest(MyRequest myRequest) {
        this.goConnect(myRequest);
    }

    /**
     * 连接方法, 连接成功就去成功处理,连接不成功就尝试重连
     */
    private void goConnect(MyRequest myRequest) {
        this.connectResult = this.goToConnect(myRequest);
        if (this.connectResult){
            this.connectMachine.connectSuccess(myRequest);
        }else{
            this.connectMachine.reConnect(myRequest);
        }
    }

    /**
     *  判断请求有没有方法,如果有true,没有就false
     */
    private boolean goToConnect(MyRequest myRequest) {
        System.out.println("正在连接。。。。。");
        if (myRequest.getMethod() != null){
            return true;
        } else{
            return false;
        }
    }
}

重连状态:

public class ReConnectingState implements ConnectState {

    private ConnectMachine connectMachine;

    private boolean reConnectResult;

    public ReConnectingState(ConnectMachine connectMachine) {
        this.connectMachine = connectMachine;
    }

    /**
     * 重连 连接成功 就到成功处理,连接失败就到连接失败处理
     */
    @Override
    public void handleRequest(MyRequest myRequest) {
        this.reConnectResult = this.reConnect(myRequest);
        if (this.reConnectResult){
            connectMachine.connectSuccess(myRequest);
        } else {
            connectMachine.connectFailure(myRequest);
        }
    }

    /**
     * 如果请求没有必要需要方法 反true,否则反false
     */
    private boolean reConnect(MyRequest myRequest) {
        System.out.println("尝试重连。。。。。。");
        if (!myRequest.isMethodNessary()){
            return true;
        } else {
            return false;
        }
    }
}

连接成功状态:

public class ConnectSuccessState implements ConnectState {

    private ConnectMachine connectMachine;

    private boolean handleResult;

    public ConnectSuccessState(ConnectMachine connectMachine) {
        this.connectMachine = connectMachine;
    }

    @Override
    public void handleRequest(MyRequest myRequest) {
        this.connectSuccessAndHandle(myRequest);
    }

    /**
     * 处理成功就断开连接
     */
    private void connectSuccessAndHandle(MyRequest myRequest) {
        this.handleResult = this.handle(myRequest);
        if (this.handleResult){
            connectMachine.disConnect(myRequest);
        }
    }

    /**
     * 处理请求 ,处理成功 反true 处理失败false
     */
    private boolean handle(MyRequest myRequest) {
        System.out.println(myRequest.getUrl() + " 连接成功了,正在处理。。。。");
        if (myRequest.getMethod() != null){
            System.out.println(myRequest.getMethod() + " 处理成功" );
        } else {
            System.out.println(" 处理成功" );
        }
        return true;
    }
}

断开连接状态:

public class DisconnectState implements ConnectState {

    private ConnectMachine connectMachine;

    public DisconnectState(ConnectMachine connectMachine) {
        this.connectMachine = connectMachine;
    }

    @Override
    public void handleRequest(MyRequest myRequest) {
        this.disConnect(myRequest);
    }

    /**
     * 断开连接
     */
    private void disConnect(MyRequest myRequest) {
        System.out.println("已经断开与" + myRequest.getUrl() + "连接");
    }
}

连接失败状态:

public class ConnectFailureState implements ConnectState {

    private ConnectMachine connectMachine;

    public ConnectFailureState(ConnectMachine connectMachine) {
        this.connectMachine = connectMachine;
    }

    @Override
    public void handleRequest(MyRequest myRequest) {
        this.connectFailure(myRequest);
    }

    private void connectFailure(MyRequest myRequest) {
        System.out.println(myRequest.getUrl() + "连接失败。。。");
    }
}

测试代码:

public class ConnectionTest {

    public static void main(String[] args) {
        ConnectMachine machine = new ConnectMachine();

        MyRequest request = new MyRequest("www.baidu.com","search food",true);

        machine.tryConnect(request);
    }

}

测试结果:

与www.baidu.com连接初始化。。。。。
正在连接。。。。。
www.baidu.com 连接成功了,正在处理。。。。
search food 处理成功
已经断开与www.baidu.com连接

以上就是使用模拟的网络连接来实现状态模式。

上面的各种状态如果都写再ConnectMachine里,那么将会有一大把的if else,耦合度很高。

状态模式优缺点分析:
优点:
1)面向接口式编程,将实现细节巧妙封装在各个不同的状态类中,状态转换交给状态类自己去实现,外部无需关心;
2)将由大量业务、大量逻辑判断的代码去除,状态类内部通过状态的转换实现相关逻辑,代码可读性更好;
缺点:
1)增加新的状态时会增加状态类,而且在增加新的状态类之后,环境类需要做相应的修改,不太符合开闭原则;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值