5.3.1面向可维护性的构造技术
程序员文章站
2022-07-14 21:33:12
...
基于状态的构造
使用有限状态机来定义程序的行为、使用状态来控制程序的执行。我们以电梯为例,电梯的停止,上升,下降… 这些都被认为是一个状态,接下来会发生什么是由电梯的当前状态决定的。
下图是关于状态的转换
而我们在写代码的时候,在ADT内部进行自行管理状态的转换时,需要大量的if-else。同时在ADT的方法中,也需要根据当前状态做各种判断if-else,采取不同的行为。
比如说Elevator的实现
public class Elevator
{
ElevatorState currentState;
public Elevator(){
currentState = ElevatorState.CLOSED;
}
public void changeState(){
if(currentState == ElevatorState.OPEN){
currentState = ElevatorState.CLOSED;
closeDoors();
}
if(currentState == ElevatorState.CLOSED
&& upButtonIsPressed()){
currentState = ElevatorState.MOVING_UP;
moveElevatorUp();
}
if(currentState == ElevatorState.CLOSED
&&downButtonIsPressed()){
currentState = ElevatorState.MOVING_DOWN;
moveElevatorDown();
}
if((currentState == ElevatorState.MOVING_UP ||
currentState == ElevatorState.MOVING_DOWN)&&
reachedDestination()){
currentState = ElevatorState.STOP;
stopElevator();
}
if(currentState == ElevatorState.STOP){
currentState = ElevatorState.OPEN;
openDoors();
}
}
}
基于自动机的编程
核心思想:将程序看作是一个有限状态自动机,侧重于对“状态”及“状态转换”的抽象和编程。
内容:首先是把程序的执行分解为一组自动执行的步骤,而且八个步骤之间的通讯通过“状态变量”进行,程序执行就看作是各自动步骤的不断循环,而我们一般使用枚举类型enum或者更加复杂的数据类型定义找状态。并且常使用二维数组定义状态转换表。
状态模式
在根据状态决定方法内部行为的时候,我们一般习惯用if/else语句,但其实最后不要使用if/else结构在ADT的各方法内部根据状态决定行为(考虑将来的扩展和修改)。
我们要注意的是:
1.状态对象通常不包含任何属性
2.状态改变时,要修改状态对象
3.具体执行的方法,要委托给状态对象
状态模式的结构
下面以有穷自动机为例,分析状态模式
class Context{
State state;//保存对象的状态
//设置初始状态
public Context(State s){state = s;}
//接收外部输入,开启状态转换
public void move(char c){state = state.move(c);}
//判断是否达到合法的最终状态
public boolean accept(){return state.accept();}
public State getstate {return this.state;}
}
//状态接口
public interface State{
State move(char c);
boolean accept();
}
class State1 implements State{
static State1 instance = new State1();
private State1(){}//构造器私有,不可生成新实例,单例模式
public State move(char c){
switch(c){
case 'a': return State2.instance;
case 'b': return State1.instance;
default:throw new IllegalArgumentERxception();
}
}
public boolean accept(){
return false;
}//该状态为非可接受状态
}
class State2 implements State{
static State2 instance = new State2();
private State2(){}
public State move(char c){
switch(c){
case 'a':return State1.instance;
case 'b':return State1.instance;
default:throw new IllegalArgumentException();
}
}
public boolean accept(){return true;}
}
public static void main(String[] args){
Context context = new Context(State1.instance);
for(int i=0;i<args.length;i++){
context.move(args[i]);
if(context.accept()) break;
}
}
代码逻辑如图所示:
上一篇: 入门kafka
推荐阅读