您的位置:首页 > 其它

我的设计模式:从阿里巴巴设计规范到状态设计模式

2017-11-23 20:10 260 查看
阿里爸爸规范中提到了:"尽量不要使用else,if else语句,可使用卫语句或者状态设计模式来替换",那何谓状态设计模式呢?
问题:例如:电梯状态:开,关,运行,暂停,停电,故障等等... 电梯的行为:开门,升降,关门等...
状态决定了行为,行为又产生了某种状态,so很有意思吧,我们该如何合理的解决(遵循java设计的开闭原则)该问题呢?
解决方案:
1. 首先写个类A,里面定义所有的状态(常量 public static final),没毛病吧
2. 状态如何决定行为呢?每个状态都对应一个特定的类B,里面定义了各自的行为
3. 行为又如何产生特定的状态呢?
* 我们先得解决一个 隐藏的问题:这个状态是哪个对象的状态呢?现在我们就写了两种类AB,哈哈不妨我们把类A设置成该对象,类B中都持有类A的对象不就好了(好吗?)。
* 如何指定A对象的状态呢,A中现在只包含几个状态常量,肯定是不行的,得有一个变量哈,顺便私有了,提供set,get方法,可是这个变量的类型写啥啊?
* 我们不妨把每个状态类B提取出来一个接口C,统一管理起来,变量的类型就知道怎么写了吧。类A的对象在每个状态类中都写一遍,不妨在接口中统一管理,岂不更好。
* 那么这个变量代表啥含义呢?当前状态
4.指定了当前状态,那么如何执行当前的行为呢?当前状态直接调用你想要的行为不就好了,一切顺利成章的完成啦。
5.还差最后一个中间桥梁,接口C中类A对象还没指定呢(用于改变类A中的状态),啥时候指定好呢?肯定使用之前啦!!!类A初始化或者指定当前状态的时候
6.那么如何调用的呢?指定A对象的当前状态,调用A的行为方法(A方法调用的是状态类B中的方法)

初始化状态-->决定特定的行为-->改变了当前状态--->决定下一步的行为 无限循环,代码也就活起来了

经典电梯代码附上:

接口C代码:
package com.cbf4life.advance;
/**
* @author cbf4Life cbf4life@126.com
* I'm glad to share my knowledge with you all.
* 定义一个电梯的接口
*/
public abstract class LiftState{
//定义一个环境角色,也就是封装状态的变换引起的功能变化
protected Context context;
public void setContext(Context _context){
this.context = _context;
}
//首先电梯门开启动作
public abstract void open();
//电梯门有开启,那当然也就有关闭了
public abstract void close();
//电梯要能上能下,跑起来
public abstract void run();
//电梯还要能停下来,停不下来那就扯淡了
public abstract void stop();
}

类B代码(其中一个):
package com.cbf4life.advance;
/**
* @author cbf4Life cbf4life@126.com
* I'm glad to share my knowledge with you all.
* 在电梯门开启的状态下能做什么事情
*/
public class OpenningState extends LiftState {
//开启当然可以关闭了,我就想测试一下电梯门开关功能
@Override
public void close() {
//状态修改
super.context.setLiftState(Context.closeingState);
//动作委托为CloseState来执行
super.context.getLiftState().close();
}
//打开电梯门
@Override
public void open() {
System.out.println("电梯门开启...");
}
//门开着电梯就想跑,这电梯,吓死你!
@Override
public void run() {
//do nothing;
}
//开门还不停止?
public void stop() {
//do nothing;
}
}

类A代码如下:
package com.cbf4life.advance;
/**
* @author cbf4Life cbf4life@126.com
* I'm glad to share my knowledge with you all.
*/
public class Context {
//定义出所有的电梯状态
public final static OpenningState openningState = new OpenningState();
public final static ClosingState closeingState = new ClosingState();
public final static RunningState runningState = new RunningState();
public final static StoppingState stoppingState = new StoppingState();
//定一个当前电梯状态
private LiftState liftState;
public LiftState getLiftState() {
return liftState;
}
public void setLiftState(LiftState liftState) {
this.liftState = liftState;
//把当前的环境通知到各个实现类中
this.liftState.setContext(this);
}

public void open(){
this.liftState.open();
}
public void close(){
this.liftState.close();
}
public void run(){
this.liftState.run();
}
public void stop(){
this.liftState.stop();
}
}

调用类:
package com.cbf4life.advance;
/**
* @author cbf4Life cbf4life@126.com
* I'm glad to share my knowledge with you all.
* 模拟电梯的动作
*/
public class Client {
public static void main(String[] args) {
Context context = new Context();
context.setLiftState(new ClosingState());
context.open();
context.close();
context.run();
context.stop();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息