# 23种设计模式-状态模式

# 1.状态模式

允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它所属的类。

# 优缺点

# 优点:

可以将不同的状态隔离; 每个状态都是一个单独的类 ;

可以将各种状态的转换逻辑 , 分布到状态的子类中,减少相互依赖 ;

增加新状态 , 操作简单;

# 缺点:

如果状态数量比较多,状态类的数量会增加, 业务场景系统变得很复杂;如果业务中某个对象由几十上百个状态 ,就会很复杂, 这时就需要对状态进行拆分处理 ;

# 使用场景

# 实现方式

# 状态接口:State

public interface State {
    /**
     * @desc 预订房间
     */
    public void bookRoom();
    
    /**
     * @desc 退订房间
     */
    public void unsubscribeRoom();
    
    /**
     * @desc 入住
     */
    public void checkInRoom();
    
    /**
     * @desc 退房
     */
    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 预订房间
     */
    public void bookRoom(){
        state.bookRoom();
    }
    
    /**
     * @desc 退订房间
     */
    public void unsubscribeRoom(){
        state.unsubscribeRoom();
    }
    
    /**
     * @desc 入住
     */
    public void checkInRoom(){
        state.checkInRoom();
    }
    
    /**
     * @desc 退房
     */
    public void checkOutRoom(){
        state.checkOutRoom();
    }
 
    public String toString(){
        return "该房间的状态是:"+getState().getClass().getName();
    }
    
    /*
     * getter和setter方法
     */
    public State getFreeTimeState() {
        return freeTimeState;
    }
 
    public void setFreeTimeState(State freeTimeState) {
        this.freeTimeState = freeTimeState;
    }
 
    public State getCheckInState() {
        return checkInState;
    }
 
    public void setCheckInState(State checkInState) {
        this.checkInState = checkInState;
    }
 
    public State getBookedState() {
        return bookedState;
    }
 
    public void setBookedState(State bookedState) {
        this.bookedState = bookedState;
    }
 
    public State getState() {
        return state;
    }
 
    public void setState(State state) {
        this.state = state;
    }
}

# 3个状态类,这个三个状态分别对于这:空闲、预订、入住。其中空闲可以完成预订和入住两个动作,预订可以完成入住和退订两个动作,入住可以退房。

/** 
 * @Description: 空闲状态只能预订和入住
 */
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() {
        //不需要做操作
    }
}

/** 
 * @Description: 入住状态房间只能退房
 */
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());   //变成空闲状态
    }
}

/** 
 * @Description: 入住可以退房
 */
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 Test {
    public static void main(String[] args) {
        //有3间房
        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]);
    }
}

参考博客:https://blog.csdn.net/a745233700/article/details/83720412