java设计模式系列之《三》----- 状态模式

状态模式,我是这么理解的:用多态实现替换多重if嵌套

它和策略模式看起来很像,都可以消除if else,但是策略模式针对点在于算法,而状态模式针对点在于状态的切换

demo:宾馆对房间的操作

首先,假设他有这么几种状态:空闲、预订、入住

有这么几种操作:预订、取消预定、入住、退房

针对这种有多个状态且互相之间有操作的情景就可以使用状态模式,消除大量if else

接下来:No code No BB

1>状态接口:State

public interface State {

    String getStateDescription();//显示状态

    void Book(Room room);//预定

    void checkin(Room room);//入住

    void unBook(Room room);//取消预定

    void checkout(Room room);//退房
}

2>状态实现类:FreeState

@Slf4j
public class FreeState implements State {

    @Override
    public String getStateDescription() {
        return "当前为空闲状态";
    }

    @Override
    public void Book(Room room) {
        //进行预定操作。。。。。。
        //状态便成为已预定状态
        room.setState(new BookState());
    }

    @Override
    public void checkin(Room room) {
        //进行入住操作
        //状态变更为已入住
        room.setState(new CheckinState());
    }

    @Override
    public void unBook(Room room) {
        //空闲状态无法执行--取消预定操作
        log.info("空闲状态无法取消预定");
    }

    @Override
    public void checkout(Room room) {
        //空闲状态无法进行退房操作
        log.info("空闲状态无法退房");
    }
}

BookState:

@Slf4j
public class BookState implements State {

    @Override
    public String getStateDescription() {
        return"当前为预定状态";
    }

    @Override
    public void Book(Room room) {
        log.info("当前已经为预定状态");
    }

    @Override
    public void checkin(Room room) {
        room.setState(new CheckinState());
    }

    @Override
    public void unBook(Room room) {
        room.setState(new FreeState());
    }

    @Override
    public void checkout(Room room) {
        log.info("预定状态无法退房");
    }
}

CheckInState:

@Slf4j
public class CheckinState implements State {

    @Override
    public String getStateDescription() {
        return "当前状态为入住状态";
    }

    @Override
    public void Book(Room room) {
        log.info("入住状态无法预定");
    }

    @Override
    public void checkin(Room room) {
        log.info("已入住状态无法入住");
    }

    @Override
    public void unBook(Room room) {
        log.info("已入住状态无法取消预定");
    }

    @Override
    public void checkout(Room room) {
        room.setState(new FreeState());
    }
}

3>需要一个包含状态的实体,状态必须是指某个东西的状态,不然没有存在的意义

Room:

@Data
@Slf4j
public class Room {

    private State state;

    private String roomNum;

    /**
     * 功能描述: 预定
     */
    public void bookRoom() {
        state.Book(this);
    }

    /**
     * 功能描述: 取消预定
     */
    public void unBookRoom() {
        state.unBook(this);
    }

    /**
     * 功能描述: 入住
     */
    public void checkinRoom() {
        state.checkin(this);
    }

    /**
     * 功能描述: 退房
     */
    public void checkoutRoom() {
        state.checkout(this);
    }

    /**
     * 功能描述: 房间状态
     */
    public void showRoomState() {
      log.info(roomNum+state.getStateDescription());
    }
}

4>接下来测试类可以看出设计模式让代码简洁了很多:假设我们要预订一间空闲的房间

public class Test {

    public static void main(String[] args) {

        //状态模式适用于有多种状态,并且每种状态都有几种操作可以选择
        //FreeState,BookState,CheckinState其实都相当于一个一级条件的判断,里面的每个方法其实相当于一个二级判断
        //一般会有两个状态作比较,一个是当前状态(可以从数据库查询)
        //一个是要更改的状态



        //不使用设计模式--多重if条件判断
        String currentState = "free";//当前状态
        String wantState = "Book";//想要更改的状态
        if(currentState.equals("free")) {//空闲状态
            if(wantState.equals("free")) {
                System.out.println("已经是空闲状态");
            }else if(wantState.equals("Book")) {
                currentState = "Book";
            }else if (wantState.equals("checkin")) {
                currentState = "checkin";
            }else {
                System.out.println("空闲状态无法更改为退房状态");
            }
        }else if(currentState.equals("Book")) {//预定状态

        }else {//入住状态

        }





        //使用设计模式---代码精简很多
        Room room = new Room();
        room.setRoomNum("9521");

        room.setState(new FreeState());
        room.bookRoom();
    }

}

代码说明一切!!!

ps:这里强调两点

1>实际撸代码中,都是从数据库查询当前状态,但是我们数据库中状态可能是1,2,3,4,这样的,而我们怎么把它转换为状态的具体实现类呢?这就需要在包含状态的实体类中做判断,然后new相应的实体状态类,调用方法(其实我觉得不应该是这样,这样还是会有if判断,但是暂时没有想到好的办法让状态对应上状态的具体实现类)

2>具体的状态实现类需要实现接口的所有方法,有的可能压根就不需要判断,这时可以考虑写一个抽象状态类,然后抽象实体类继承,抽象状态类可以给默认实现,这样具体的实现类就只需要重写需要的方法即可

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值