状态机
我们先先来看看一般的做法
① 首先,我们找出蓝牙配网中的一些状态:
1. 蓝牙未连接
2. 蓝牙连接中
3. 蓝牙已连接
4. 路由信息已接收
5. WIFI连网中
6. 配网成功
② 然后,定义一些常量来指定各个状态:
const UNCONNECTED = 1;
const CONNECTING = 2;
const CONNECTED = 3;
const RECEIVED = 4;
const WIFI_CONNECTING = 5;
const WIFI_CONNECTED = 6;
let state = UNCONNECTED;
③ 最后我们创建一个状态机的类,比如在连接的函数里处理每个状态下的情况:
④ 使用状态机的类
这看起来没什么问题,也挺好用。但某次会议上,某人提出了现在的方式有缺陷,不是很安全,应该在蓝牙连接后进行设备的认证。最后领导拍板,在原来的基础上增加几个状态。
既然要更改,那就赶紧召集开发人员,结果开发人员一看,沃日要修改好多地方:
1.首先可能要增加两种新的状态:
const AUTHENTCATING = 7;
const AUTHENTCATED = 8;
2.然后在那些处理状态的方法里增加类似else if的东西,太多了,太多了。
就在程序员炸裂的边缘,你们的架构师瞄了眼说,怎么没有用状态模式,程序员一脸无奈的看着架构师。
好了题外话说到这,进入本次的正题——状态模式
什么是模式
模式是指在某种情境下,针对某问题的某种解决方案。
何时用设计模式
在设计的时候,如果遇到某个问题,而且该问题不能用简单的设计就能解决,那么可以试着利用某个模式帮助我们解决那个问题。
新的设计
我们把每个状态都看成一个对象,然后在动作发生时委托给当前状态。
首先,我们定义个抽象类State,在这个类内,蓝牙配网的每个动作都有一个对应的函数。
然后为每个状态实现状态类。这些类将负责对应状态下的行为。
最后,将动作委托到状态类。
重新定义State类
class AbstractState {
constructor(stateController) {
this.stateController = stateController; // 状态控制类
}
/\*\*
\* 连接蓝牙设备
\* @see UnConnectState
\*/
connect() {}
/\*\*
\* 断开蓝牙设备
\* @see UnConnectState
\*/
disconnect() {}
/\*\*
\* 蓝牙连接成功
\* @see UnConnectState
\*/
connectSuccess() {}
/\*\*
\* 蓝牙连接失败
\* @see UnConnectState
\*/
connectFail() {}
/\*\*
\* 路由数据接收完成
\* @see ReceivedState
\*/
received() {}
/\*\*
\* 认证中
\* @see AuthenticatingState
\*/
authenticating() {}
/\*\*
\* 认证完成
\* @see AuthenticatedState
\*/
authenticated() {}
/\*\*
\* 充电完成
\* @see WifiConnectingState
\*/
wifiConnecting() {}
/\*\*
\* 时间同步完成
\* @see WifiConnectedState
\*/
wifiConnected() {}
/\*\*
\* 获取状态ID
\*/
getStateId() {
return 0;
}
/\*\*
\* 释放资源
\* @see ConnectedState
\*/
onRelease() {}
}
module.exports = AbstractState
实现各状态类
UnConnectState类
import AbstractState from './AbstractState'
class UnConnectState extends AbstractState { // 未连接状态只处理连接的事件
constructor(stateController) {
super(stateController);
}
/\*\*
\* @override
\* @description 连接设备
\*/
connect() { // 这里只是实例,具体需要怎么处理还要更具体的业务逻辑
const ble = this.stateController.getBLE();
if (ble) {
this.stateController.setState(this.stateController.getConnectingState());
this.stateController.notifyAll();
ble.initBleAdapter();
}
}
getStateId() {
return 100;
}
}
module.exports = UnConnectState
ConnectingState类
import AbstractState from './AbstractState'
class ConnectingState extends AbstractState { // 蓝牙连接状态的类
constructor(stateController) {
super(stateController);
}
connectSuccess() {
this.stateController.setState(this.stateController.getConnectedState());
this.stateController.notifyAll();
}
connectFail() {
this.stateController.setState(this.stateController.getUnConnectState());
this.stateController.notifyAll();
}
disconnect() {
this.stateController.setState(this.stateController.getUnConnectState());
this.stateController.notifyAll();
}
getStateId() {
return 101;
}
}
module.exports = ConnectingState
ConnectedState类
import AbstractState from './AbstractState'
class ConnectedState extends AbstractState {
constructor(stateController) {
super(stateController);
}
connectFail() {
this.stateController.setState(this.stateController.getUnConnectState());
this.stateController.notifyAll();
// 结束发送路由的命令
}
authenticating() { this.stateController.setState(this.stateController.getAuthenticatingState());
// 发送认证的指令
}
disconnect() {
this.stateController.setState(this.stateController.getUnConnectState());
this.stateController.notifyAll();
}
getStateId() {
return 102;
}
onRelease() {
}
}
module.exports = ConnectedState
由于篇幅,其他的状态类就不在这里写了。
StateController类
import UnConnectState from './UnConnectState';
import ConnectingState from './ConnectingState';
import ConnectedState from './ConnectedState';
const DEBUG = true;
const TAG = 'StateController#';
let mUnConnectState = null;
let mConnectingState = null;
let mConnectedState = null;
let mState = null;
let mBle = null;
let STATE\_CONTROLLER = null;
/\*\* 页面监听器列表 \*/
let mPageObservers = new Set();
class StateController {
constructor() {
mUnConnectState = new UnConnectState(this);
mConnectingState = new ConnectingState(this);
mConnectedState = new ConnectedState(this);
mState = mUnConnectState;
}
static getInstance() {
if (STATE\_CONTROLLER == null) {
STATE\_CONTROLLER = new StateController();
}
return STATE\_CONTROLLER;
}
addPage(page) {
mPageObservers.add(page);
}
deletePage(page) {
mPageObservers.delete(page);
}
clearPages() {
mPageObservers.clear();
}
/\*\*
\* 连接设备,在调用之前确保已经调用过#setDeviceId(deviceId)
\*/
connect() {
mState.connect();
}
/\*\*
\* 断开设备连接
\*/
disconnect() {
mState.disconnect();
}
/\*\*
\* 设备连接成功
\*/
connectSuccess() {
mState.connectSuccess();
}
/\*\*
\* 设备连接失败
\*/
connectFail() {
## 最后
**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
**深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。**
**因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
![img](https://img-blog.csdnimg.cn/img_convert/1df1d8af7fe6b1ecd29ea6a2317abab4.png)
![img](https://img-blog.csdnimg.cn/img_convert/5f31d74cf458c609ba4d5f00eb4978d2.jpeg)
![img](https://img-blog.csdnimg.cn/img_convert/b07d0e6eb55411af40a1ca00992cdaca.png)
![img](https://img-blog.csdnimg.cn/img_convert/689780867b23c5dbce4a645d62474dda.png)
![img](https://img-blog.csdnimg.cn/img_convert/d1bd41bf2109a73348faafc8cc9a91e4.png)
![img](https://img-blog.csdnimg.cn/img_convert/5a27e558708d72fd1ff10ccf7da22f8c.png)
![](https://img-blog.csdnimg.cn/img_convert/6f8c449d3db8b48d0f91be8719c4efb5.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!**
[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618654289)
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**!!
存中...(img-iQndZxrx-1715713182307)]
[外链图片转存中...(img-y8hEzoet-1715713182307)]
[外链图片转存中...(img-LiJERrs1-1715713182308)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!**
[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618654289)
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**!!