设计模式❤状态机模式
2018-02-27 本文已影响0人
miyakee
状态模式把所研究的对象的行为包装在不同的状态对象里,每一个状态对象都属于一个抽象状态类的一个子类。通过改变对象内部的状态,使得你可以在运行时动态改变一个对象的行为。
状态模式的示意性类图首先我们设定一个奥特曼的接口
interface Ultraman {
void attackMonster();
void shapeShift();
void shooting();
void usePower();
}
这个奥特曼有3种状态:
/**人类状态**/
public class personState implements Ultraman {
private Context context;
personState(Context context){
System.out.println("我是一个人 !!");
this.context=context;
}
@Override
public void attackMonster(){
System.out.println("人类打不赢怪兽,快变身吧");
}
@Override
public void shapeShift(){
System.out.println("变成奥特曼了");
context.setState(context.becomeUltraman());
}
@Override
public void shooting(){
System.out.println("射击!!");
}
@Override
public void usePower() {
//do nothing
}
}
/**力量用完的状态**/
class powerOffState implements Ultraman {
private Context context;
powerOffState(Context context) {
this.context = context;
}
@Override
public void attackMonster() {
}
@Override
public void shapeShift() {
System.out.println("变成人了");
context.setState(context.becomePeople());
}
@Override
public void shooting() {
System.out.println("手太大,射击技能不能使用");
}
@Override
public void usePower() {
System.out.println("能量用完了");
}
}
/**正常奥特曼状态**/
public class ultramanState implements Ultraman {
private Context context;
ultramanState(Context context) {
this.context = context;
}
@Override
public void attackMonster() {
System.out.println("攻击小怪兽");
context.resultMonster();
}
@Override
public void shapeShift() {
System.out.println("变成人了");
context.setState(context.becomePeople());
}
@Override
public void shooting() {
System.out.print("手太大,射击技能不能使用");
}
@Override
public void usePower() {
System.out.println("消耗能量一颗");
}
}
这是一个环境角色部分,定义用户需要或者说感兴趣的接口
public class Context {
private Ultraman personState;
private Ultraman powerOffState;
private Ultraman ultramanState;
private Ultraman ultraman;
private int powerValue;
public Context() {
this.personState = new personState(this);
this.powerOffState = new powerOffState(this);
this.ultramanState = new ultramanState(this);
this.ultraman = personState;
}
//设置当前处于的状态
void setState(Ultraman ultraman) {
this.ultraman = ultraman;
}
//变身 变身前初始化能量
public void shapeShift(int powerValue) {
this.powerValue = powerValue;
ultraman.shapeShift();
}
//变成人
Ultraman becomePeople() {
return personState;
}
//变成怪兽
Ultraman becomeUltraman() {
return ultramanState;
}
//打怪兽的结果
void resultMonster() {
if (powerValue > 0) { //能量没有用完
ultraman.usePower();
System.out.println("哈哈哈 恭喜击败小怪兽1只");
powerValue--;
} else {
//能量用完转化成能量用完状态
this.setState(powerOffState);
ultraman.usePower();
System.out.println("你被小怪兽击败了");
}
}
//攻击怪兽
public void battle() {
ultraman.attackMonster();
}
//射击
public void shooting() {
ultraman.shooting();
}
}
实际调用部分
public class battleTest {
public static void main(String[] args){
int powerValue=1; //初始化奥特曼的能量为5
Context context=new Context();
System.out.println("怪兽出现了0口0");
context.shooting(); //人类可以射击
context.battle(); //人类可以射击
context.shapeShift(powerValue); //射击不成功,变身
for(int i=0;i<1;i++){ //出现了四只怪兽,打败了所有怪兽
context.battle();
}
context.shapeShift(powerValue); //打完怪兽,变回人
context.shooting(); //人类可以射击
context.shapeShift(powerValue); //又变成怪兽
for(int i=0;i<2;i++){ //出现了六只怪兽,被打败
context.battle();
}
}
}
和策略模式存在的区别:【自己切换和主动切换】
状态模式将各个状态所对应的操作分离开来,即对于不同的状态,由不同的子类实现具体操作,不同状态的切换由子类实现,当发现传入参数不是自己这个状态所对应的参数,则自己给Context类切换状态;而策略模式是直接依赖注入到Context类的参数进行选择策略,不存在切换状态的操作练习。
在jdk里的应用:
java.util.Iterator
javax.faces.lifecycle.LifeCycle#execute()
参考:http://blog.csdn.net/seacean2000/article/details/10528153