设计模式之状态模式

定义

状态模式

状态模式(state pattern):属于对象的行为型模式。又叫状态对象模式(pattern of objects for state);当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变其了类。

这里写图片描述

涉及的角色

抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定的状态相关的行为。
环境(Context)角色:维护一个具体状态(ConcreteState)实例,这个实例定义当前的状态。
具体状态(ConcreteState)角色:每一个具体状态(ConcreteState)实例都实现了与环境(Context)对象的一个状态相关的行为。

例子

例如:酒店有预定,退订,入住和退房等各种状态。

状态流转图如下:
这里写图片描述

每个单元代表一种状态,箭头指向代表房间的状态转换。

酒店的UML类图:
这里写图片描述

抽象状态(State)角色:对应的状态接口:

public interface State {  
    /**  
     * @desc 预订房间  
     * @return void  
     */  
    public void bookRoom();  

    /**  
     * @desc 退订房间  
     * @return void  
     */  
    public void unsubscribeRoom();  

    /**  
     * @desc 入住  
     * @return void  
     */  
    public void checkInRoom();  

    /**  
     * @desc 退房  
     * @return void  
     */  
    public void checkOutRoom();  

}

房间类:

public class Room {  
    /*  
     * 房间的三个状态  
     */  
    State freeTimeState;    //空闲状态  
    State checkInState;     //入住状态  
    State bookedState;      //预订状态  

    State state ;    

    public Room(){  
        freeTimeState = new FreeTimeState(this);  
        checkInState = new CheckInState(this);  
        bookedState = new BookedState(this);  

        state = freeTimeState ;  //初始状态为空闲  
    }  

    /**  
     * @desc 预订房间  
     * @return void  
     */  
    public void bookRoom(){  
        state.bookRoom();  
    }  

    /**  
     * @desc 退订房间  
     * @return void  
     */  
    public void unsubscribeRoom(){  
        state.unsubscribeRoom();  
    }  

    /**  
     * @desc 入住  
     * @return void  
     */  
    public void checkInRoom(){  
        state.checkInRoom();  
    }  

    /**  
     * @desc 退房  
     * @return void  
     */  
    public void checkOutRoom(){  
        state.checkOutRoom();  
    }  

    public String toString(){  
        return "该房间的状态是:"+getState().getClass().getName();  
    }  

    /*  
     * getter和setter方法略  
     */  
      ...
}

三个状态类:

//预定状态房间只能退定
public class BookedState implements State {  
    Room hotelManagement;  

    public BookedState(Room hotelManagement) {  
        this.hotelManagement = hotelManagement;  
    }  

    public void bookRoom() {  
        System.out.println("该房间已近给预定了...");  
    }  

    public void checkInRoom() {  
        System.out.println("入住成功...");   
        hotelManagement.setState(hotelManagement.getCheckInState());         //状态变成入住  
    }  

    public void checkOutRoom() {  
        //不需要做操作  
    }  

    public void unsubscribeRoom() {  
        System.out.println("退订成功,欢迎下次光临...");  
        hotelManagement.setState(hotelManagement.getFreeTimeState());   //变成空闲状态  
    }  

}  
//入住可以退房
public class CheckInState implements State {  
    Room hotelManagement;  
    public CheckInState(Room hotelManagement) {  
        this.hotelManagement = hotelManagement;  
    }  

    public void bookRoom() {  
        System.out.println("该房间已经入住了...");  
    }  

    public void checkInRoom() {  
        System.out.println("该房间已经入住了...");  
    }  

    public void checkOutRoom() {  
        System.out.println("退房成功....");  
        hotelManagement.setState(hotelManagement.getFreeTimeState());     //状态变成空闲  
    }  

    public void unsubscribeRoom() {  
        //不需要做操作  
    }  

}
//空闲状态只能预订和入住 
public class FreeTimeState implements State {  

    Room hotelManagement;  

    public FreeTimeState(Room hotelManagement){  
        this.hotelManagement = hotelManagement;  
    }  

    public void bookRoom() {  
        System.out.println("您已经成功预订了...");  
        hotelManagement.setState(hotelManagement.getBookedState());   //状态变成已经预订  
    }  

    public void checkInRoom() {  
        System.out.println("您已经成功入住了...");  
        hotelManagement.setState(hotelManagement.getCheckInState());   //状态变成已经入住  
    }  

    public void checkOutRoom() {  
        //不需要做操作  
    }  

    public void unsubscribeRoom() {  
        //不需要做操作  
    }  

} 

测试类:

public class Test {  
    public static void main(String[] args) {  
        //有2间房  
        Room[] rooms = new Room[2];  
        //初始化  
        for(int i = 0 ; i < rooms.length ; i++){  
            rooms[i] = new Room();  
        }  
        //第一间房  
        rooms[0].bookRoom();    //预订  
        rooms[0].checkInRoom();   //入住  
        rooms[0].bookRoom();    //预订  
        System.out.println(rooms[0]);  
        System.out.println("---------------------------");  

        //第二间房  
        rooms[1].checkInRoom();  
        rooms[1].bookRoom();  
        rooms[1].checkOutRoom();  
        rooms[1].bookRoom();  
        System.out.println(rooms[1]);  
    }  

}

总结

状态模式应用

当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。

状态模式优点
  1. 状态模式将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。也就是说可以将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个 ConcreteState 中,所以通过定义新的子类可以很容易地增加行的状态和转换。这样可以消除庞大的条件分支语句。

  2. 状态模式通过把各种状态转移逻辑分布到 State 的子类之间,来减少相互间的依赖。

参考链接

hydraWindy
alexpdh’s blog

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值