设计模式之状态模式

状态模式

状态模式允许对象内部状态改变的时候改变其行为。状态模式是对象的行为模式。

状态模式就是把对象的状态封装在一个状态对象中,每个状态一个类。
图如下:
在这里插入图片描述
抽象的状态角色TcpState封装了一个特定的状态对应的行为;具体状态角色TcpEstablesedSate(已连接状态),TcpListeningSate(监听状态),TcpClosedState(关闭状态)代表了tcp连接的所有状态(模拟),TcpConnection环境类。

Tcp连接环境类TcpConnection中包含了所有的状态,以及连接状态的初始化

package com.headFirst.state;

/**
 *  LISTEN - 侦听来自远方TCP端口的连接请求; 
	SYN-SENT -在发送连接请求后等待匹配的连接请求; 
	SYN-RECEIVED - 在收到和发送一个连接请求后等待对连接请求的确认; 
	ESTABLISHED- 代表一个打开的连接,数据可以传送给用户; 
	FIN-WAIT-1 - 等待远程TCP的连接中断请求,或先前的连接中断请求的确认;
	FIN-WAIT-2 - 从远程TCP等待连接中断请求; 
	CLOSE-WAIT - 等待从本地用户发来的连接中断请求; 
	CLOSING -等待远程TCP对连接中断的确认; 
	LAST-ACK - 等待原来发向远程TCP的连接中断请求的确认; 
	TIME-WAIT -等待足够的时间以确保远程TCP接收到连接中断请求的确认; 
	CLOSED - 没有任何连接状态;
	============================================================
 *  服务器端正常情况下TCP状态迁移:
 *	CLOSED->LISTEN->SYN收到 ->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED
 * @author jwt 
 * @date 2019年9月3日
 */
public class TcpConnection {

	private TcpState establisedState;//已连接,代表一个打开的连接,数据可以传送给用户; 
	private TcpState closedState;   //关闭,没有任何连接状态;
	private TcpState listeningState; //监听,侦听来自远方TCP端口的连接请求;
	private TcpState state; 

	public TcpConnection() {
		establisedState = new TcpEstablisedState(this);
		closedState = new TcpClosedState(this);
		listeningState = new TcpListeningState(this);
		state = closedState;//默认是关闭状态
	}
	public void open(){
		state.open();
	}
	public void close(){
		state.close();
	}
	public void acknowledge(){
		state.acknowledge();
	}
	
	
	
	
	public TcpState getEstablisedState() {
		return establisedState;
	}
	public TcpState getClosedState() {
		return closedState;
	}
	public TcpState getListeningState() {
		return listeningState;
	}
	public TcpState getState() {
		return state;
	}
	public void setState(TcpState state) {
		this.state = state;
	}
	
}


TcpState封装了一个特定的状态对应的行为

package com.headFirst.state;

public interface TcpState {

	void open();
	void close();
	void acknowledge();
	
}

具体的状态类

package com.headFirst.state;

public class TcpClosedState implements  TcpState {

	private TcpConnection connection;
	public TcpClosedState(TcpConnection connection){
		this.connection = connection;
	}
	@Override
	public void open() {
		System.out.println("CLOSED -> LISTEN:开始监听来自远方的tcp连接!");
		connection.setState(connection.getListeningState());
	}
	@Override
	public void close() {
	
	}

	@Override
	public void acknowledge() {
		
	}

}

package com.headFirst.state;

public class TcpEstablisedState implements TcpState {
	private TcpConnection tcpConnection;
	public TcpEstablisedState(TcpConnection tcpConnection) {
		this.tcpConnection = tcpConnection;
	}

	@Override
	public void open() {
		
	}

	@Override
	public void close() {
		System.out.println("ESTABLISHED -> CLOSED:连接已关闭!");
		tcpConnection.setState(tcpConnection.getClosedState());
	}

	@Override
	public void acknowledge() {
		
	}

}

package com.headFirst.state;

public class TcpListeningState implements TcpState{
	private TcpConnection tcpConnection;
	public TcpListeningState(TcpConnection tcpConnection) {
		this.tcpConnection = tcpConnection;
	}
	@Override
	public void open() {
		
	}
	@Override
	public void close() {
		
	}
	@Override
	public void acknowledge() {
		System.out.println("LISTEN->ESTABLISHED:确认,已连接!");
		tcpConnection.setState(tcpConnection.getEstablisedState());
	}

}

测试结果

package com.headFirst.state;

public class App {

	public static void main(String[] args) {
		TcpConnection connection = new TcpConnection();
		connection.open();//开始监听tcp请求
		connection.acknowledge();//已连接
		connection.close();//关闭
		
	}
}

在这里插入图片描述

状态机

可以看到为每个状态都创建一个类并不太友好,下面使用状态机实现:

package com.headFirst.state.machine;
//CLOSED->LISTEN->SYN收到 ->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED
public enum TcpStateMachine {

	//已关闭
	CLOSED{
		@Override
		public TcpStateMachine nextState(){
			return LISTEN;
		}
		@Override
		public TcpStateMachine prevState(){
			return ESTABLISHED;
		}
	},
	//监听
	LISTEN{
		@Override
		public TcpStateMachine nextState(){
			return ESTABLISHED;
		}
		@Override
		public TcpStateMachine prevState(){
			return CLOSED;
		}
	},
	//已连接
	ESTABLISHED{
		@Override
		public TcpStateMachine nextState(){
			return CLOSED;
		}
		@Override
		public TcpStateMachine prevState(){
			return LISTEN;
		}
	};
	
	public abstract TcpStateMachine nextState();
	public abstract TcpStateMachine prevState();
	
}

package com.headFirst.state.machine;

public class TcpConnection {

	private TcpStateMachine stateMachine = TcpStateMachine.CLOSED;
	
	public TcpConnection nextState(){
		this.stateMachine = this.stateMachine.nextState();
		return this;
	}
	
	public void log(){
		System.out.println(this.stateMachine.prevState()+"-->"+this.stateMachine.name());
	}
	
}

package com.headFirst.state.machine;

public class App {

	public static void main(String[] args) {
		TcpConnection conn = new TcpConnection();
		conn.nextState();
		conn.log();
		conn.nextState();
		conn.log();
		conn.nextState();
		conn.log();
		conn.nextState();
		conn.log();
		conn.nextState();
		conn.log();
	}
}

在这里插入图片描述

TcpStateMachine中的CLOSED,LISTEN,ESTABLISHED相当于TcpStateMachine的一个实例,且每个实例都重写了nextState,prevState两个抽象方法,用于指向上一个和下一个状态。
TcpConnection在初始化时默认含有一个Closed的引用,每次调用nextState方法,内部委托TcpStateMachine去转换成下一个状态。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jwt_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值