[学习笔记]设计模式[a]-{状态模式}

设计模式

相信大家对状态机都有了解,状态机可以实现很多逻辑处理。在程序设计中也有对应的状态模式,虽然相比状态机简单很多,但是也是一种很有应用场景的设计模式。

状态模式

首先是状态模式的定义
状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
这句话怎么理解呢,首先是”允许对象在内部状态改变时改变它的行为”,正如状态机中的状态转移一样,如果状态机的状态改变了,它的下一步所能进行的“行为”也会对应产生变化。
第二句”对象看起来好像修改了它的类”,这个意味着,在外部看起来,我们的系统中只有一个类,但是事实上并不是这样。下面用一个简单的例子对状态模式进行介绍。
我们需要实现一个简单的显示器,用于显示门的开关:
1.当门打开的时候,显示打开状态,并提供关闭的方法。
2.当门关闭的时候,显示关闭状态,并提供打开的方法。
在没有学习状态模式的时候,我们可能这样实现代码:

public class Door {

    private static int OPEN = 0;
    private static int CLOSE = 1;
    private int state;

    public void openDoor() {
        if (state == OPEN) {
            return;
        }
        if (state == CLOSE) {
            state = OPEN;
        }
    }

    public void closeDoor() {
        if (state == OPEN) {
            state = CLOSE;
        }
        if (state == CLOSE) {
            return;
        }
    }

    public void showDoor() {
        if (state == OPEN) {
            System.out.println("Door is Open!");
        }
        if (state == CLOSE) {
            System.out.println("Door is Close!");
        }
    }
}

相当简单的逻辑,如果门关着,那么我关门的操作就会被忽略,开门的操作才会改变门的状态。
但是问题来了,如果现在门上加了锁,我们该如何修正这段代码从而实现需求呢?我们需要加一个上锁的状态,当门处于上锁的状态的时我们的开门操作需要先开锁,还要判断钥匙是不是匹配。。关门状态时也要加上可以上锁的操作。。。。
这简直就相当于重写了这段代码!
那么我们来看一下 如果使用状态模式对上面的需求该如何实现:
首先,每个状态是不同的类,同时继承一个基本接口:

abstract interface State {

    public abstract void openDoor();

    public abstract void closeDoor();

    public abstract void lockDoor();

}

然后把每个状态单独实现为一个类:
开门状态

class DoorOpen implements State {

    private Door door;

    public DoorOpen(Door door) {
        this.door = door;
    }

    public void openDoor() {
        return;
    }

    public void closeDoor() {
        door.setState(door.getDoorClose());
        System.out.println("Door is close");
    }

    public void lockDoor() {
        return;
    }
}

关门状态

class DoorClose implements State {

    private Door door;

    public DoorClose(Door door) {
        this.door = door;
    }

    public void openDoor() {
        door.setState(door.getDoorOpen());
        System.out.println("Door is open");
    }

    public void closeDoor() {
        return;
    }

    public void lockDoor() {
        door.setState(door.getDoorLock());
    }
}

锁门状态

class DoorLock implements State {

    private Door door;

    public DoorLock(Door door) {
        this.door = door;
    }

    public void openDoor() {
        check();//检查钥匙是否匹配
        door.setState(door.getDoorOpen());
        System.out.println("Door is open");
    }

    public void closeDoor() {
        return;
    }

    public void lockDoor() {
        return;
    }
}

我们最后的门这个类就十分简单了:

public class Door {

    private State DoorOpen;
    private State DoorClose;
    private State DoorLock;

    private State state = DoorOpen;

    public Door() {
        DoorOpen = new DoorOpen(this);
        DoorClose = new DoorOpen(this);
        DoorLock = new DoorOpen(this);
    }

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

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

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

    public State getDoorOpen() {
        return DoorOpen;
    }

    public State getDoorClose() {
        return DoorClose;
    }

    public State getDoorLock() {
        return DoorLock;
    }

    public void setState(State state) {
        this.state = state;
    }
}

如果以后要增加新的状态,我们只需要新增一个状态类并在门中增加这个状态即可,不需要对原来的代码进行修改。
最后是状态模式的类图:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值