状态模式(State)

一、定义

允许一个对象在其内部状态改变时改变它的行为。

状态模式的角色

环境角色(Context):也称上下文,定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。

抽象状态角色(State):定义一个接口,用以封装环境对象的一个特定的状态所对应的行为。

具体状态角色(ConcreteState):每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。

二、案例

以酒店订房为例,房间的状态有:空闲、预订、入住。那么空闲房间的状态可以转变为:预订、入住。已预订状态房间的状态可以转变为:入住、取消预订。已入住房间的状态可以转变为:退房。

状态接口State:

package com.wuychn.state;

public interface State {
    void bookRoom();

    void unsubscribeRoom();

    void checkInRoom();

    void checkOutRoom();
}

房间类Room(环境角色):

package com.wuychn.state;

public class Room {
    private State freeTimeState;
    private State checkInState;
    private State bookedState;

    private State state;

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

    public void bookRoom() {
        state.bookRoom();
    }

    public void unsubscribeRoom() {
        state.unsubscribeRoom();
    }

    public void checkInRoom() {
        state.checkInRoom();
    }

    public void checkOutRoom() {
        state.checkOutRoom();
    }

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

    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;
    }
}

房间状态(具体状态角色):

空闲状态:

package com.wuychn.state;

public class FreeTimeState implements State {
    private Room hotelManagement;

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

    @Override
    public void bookRoom() {
        System.out.println("您已经预定成功了!");
        this.hotelManagement.setState(this.hotelManagement.getBookedState());
    }

    @Override
    public void unsubscribeRoom() {
    }

    @Override
    public void checkInRoom() {
        System.out.println("您已经入住了!");
        this.hotelManagement.setState(this.hotelManagement.getCheckInState());
    }

    @Override
    public void checkOutRoom() {
    }
}

入住状态:

package com.wuychn.state;

public class CheckInState implements State {
    private Room hotelManagement;

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

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

    @Override
    public void unsubscribeRoom() {
    }

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

    @Override
    public void checkOutRoom() {
        System.out.println("退房成功");
        this.hotelManagement.setState(this.hotelManagement.getFreeTimeState());
    }
}

预定状态:

package com.wuychn.state;

public class BookedState implements State {
    private Room hotelManagement;

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

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

    @Override
    public void unsubscribeRoom() {
        System.out.println("成功退订");
        this.hotelManagement.setState(this.hotelManagement.getFreeTimeState());
    }

    @Override
    public void checkInRoom() {
        System.out.println("入住成功");
        this.hotelManagement.setState(this.hotelManagement.getCheckInState());
    }

    @Override
    public void checkOutRoom() {
    }
}

测试代码:

package com.wuychn.state;

public class Test {

    public static void main(String[] args) {
        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]);

    }

}

输出:

您已经预定成功了!
入住成功
该房间已经入住了
该房间的状态是:com.wuychn.state.CheckInState
-------------
您已经入住了!
该房间已经入住了
退房成功
您已经预定成功了!
该房间的状态是:com.wuychn.state.BookedState

三、优缺点

优点:

1、封装了转换规则。

2、枚举可能的状态,在枚举状态之前需要确定状态种类。

3、将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。

4、允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。

缺点:

1、状态模式的使用必然会增加系统类的对象的个数。

2、状态模式的结构与实现都较为复杂,如果使用不当讲导致程序结构和代码的混乱。

3、状态模式对“开闭原则”的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码。

四、适用场景

1、对象的行为依赖于它的状态(属性)并且可以根据它的状态而改变它的相关行为

2、代码中包含大量与对象状态相关的条件语句


原文:https://blog.csdn.net/u013256816/article/details/51245024

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值