每天一个设计模式之状态模式(State Pattern)

该博客介绍了如何使用状态模式来实现一个糖果机的控制逻辑。通过不同的状态类(如NoQuarterState、HasQuarterState等),实现了在不同状态下糖果机的行为变化,如投币、转动曲轴、退币和出糖等操作。代码示例展示了状态模式在实际问题中的应用,使得代码更加清晰和易于维护。
摘要由CSDN通过智能技术生成

状态模式适用于行为随状态改变而改变的场景,可以替换掉一个系统中依据内部状态而添加的条件、分支语句。

一、UML类图

在这里插入图片描述

二、状态转换图

在这里插入图片描述

对应的UML类图

在这里插入图片描述

三、代码示例

状态抽象类

public abstract class State {
    // 投币
    public abstract void insertQuarter();

    // 退币
    public abstract void ejectQuarter();

    // 转动出糖曲轴
    public abstract void turnCrank();

    // 出糖
    public abstract void dispense();

    // 退还硬币
    public void returnQuarter() {
        System.out.println("give back your quarter");
    }
}

状态具体类 - HasQuarterState

public class HasQuarterState extends State {
    CandyMachine candyMachine;

    public HasQuarterState(CandyMachine candyMachine) {
        this.candyMachine = candyMachine;
    }

    public void insertQuarter() {
        System.out.println("Do not drop quarter repeat");
        returnQuarter();
    }

    public void ejectQuarter() {
        returnQuarter();
        candyMachine.setState(candyMachine.noQuarterState);
    }

    public void turnCrank() {
        System.out.println("Turning crank, ready to pop out candy");
        candyMachine.setState(candyMachine.soldQuarterState);
    }

    public void dispense() {
        System.out.println("this operation is not supported");
    }
}

状态具体类 - NoQuarterState

public class NoQuarterState extends State {
    CandyMachine candyMachine;

    public NoQuarterState(CandyMachine candyMachine) {
        this.candyMachine = candyMachine;
    }

    public void insertQuarter() {
        System.out.println("You put a quarter in");
        candyMachine.setState(candyMachine.hasQuarterState);
    }

    public void ejectQuarter() {
        System.out.println("No quarters, cannot pop out quarter");
    }

    public void turnCrank() {
        System.out.println("Please put quarter");
    }

    public void dispense() {
        System.out.println("No quarters, cannot pop out candy");
    }
}

状态具体类 - SoldQuarterState

public class SoldQuarterState extends State {
    CandyMachine candyMachine;

    public SoldQuarterState(CandyMachine candyMachine) {
        this.candyMachine = candyMachine;
    }

    public void insertQuarter() {
        System.out.println("A quarter has already dropped in, waiting for candy");
        returnQuarter();
    }

    public void ejectQuarter() {
        System.out.println("About to pop out candy, so cannot eject quarter");
    }

    public void turnCrank() {
        System.out.println("Crank has been turned, please wait.");
    }

    public void dispense() {
        int candyCount = candyMachine.getCandyCount();
        if(candyCount > 0){
            System.out.println("pop out a candy");
            candyCount--;
            candyMachine.setCandyCount(candyCount);
            if(candyCount > 0){
                candyMachine.setState(candyMachine.noQuarterState);
                return;
            }
        }

        System.out.println("sorry, candy has been sold out");
        candyMachine.setState(candyMachine.soldOutQuarterState);
    }
}

状态具体类 - SoldOutQuarterState

public class SoldOutQuarterState extends State {
    CandyMachine candyMachine;

    public SoldOutQuarterState(CandyMachine candyMachine) {
        this.candyMachine = candyMachine;
    }

    public void insertQuarter() {
        System.out.println("candy has been sold out.");
        returnQuarter();
    }

    public void ejectQuarter() {
        System.out.println("No quarters, cannot pop out quarter");
    }

    public void turnCrank() {
        System.out.println("candy has been sold out.");
    }

    public void dispense() {
        System.out.println("candy has been sold out.");
    }
}

客户类

public class Client {
    public static void main(String[] args) {
        CandyMachine candyMachine = new CandyMachine(10);
        candyMachine.insertQuarter();
        candyMachine.turnCrank();
        candyMachine.dispense();
    }
}

// 运行结果
You put a quarter in
Turning crank, ready to pop out candy
pop out a candy

Process finished with exit code 0

四、参考

  1. https://www.runoob.com/design-pattern/state-pattern.html
  2. https://www.runoob.com/w3cnote/state-vs-strategy.html
  3. https://refactoring.guru/design-patterns/state
  4. https://www.geeksforgeeks.org/state-design-pattern/

设计模式系列博文导航

一、创建型 - 5种

原型模式(Prototype Pattern)
抽象工厂模式(Abstract Factory Pattern)
建造者模式(Builder Pattern)
工厂模式(Factory Pattern)
单例模式(Singleton Pattern)

助记语:原抽建工单

二、结构型 - 8种

享元模式(Flyweight Pattern)
代理模式(Proxy Pattern)
适配器模式(Adapter Pattern)
外观模式(Facade Pattern)

过滤器模式(Filter/Criteria Pattern)
桥接模式(Bridge Pattern)
组合模式(Composite Pattern)
装饰器模式(Decorator Pattern)

助记语:想呆室外,过桥组装

三、行为型 - 11种

责任链模式(Chain of Responsibility Pattern)
命令模式(Command Pattern)
解释器模式(Interpreter Pattern)
中介者模式(Mediator Pattern)
迭代器模式(Iterator Pattern)

观察者模式(Observer Pattern)
策略模式(Strategy Pattern)
状态模式(State Pattern)

备忘录模式(Memento Pattern)
模板方法模式(Template Pattern)
访问者模式(Visitor Pattern)

助记语:责令解中谍,观测状被模仿

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值