java设计模式-状态模式

状态模式介绍:

当一个对象在内在状态改变时,允许改变起行为,这个对象看起来像是改变了其类。
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。

简例
工作状态-分类板

package com.example.designmode.statepattern;

import lombok.Data;

/**
 * <h3>design-mode</h3>
 * <p>工作状态-分类板</p>
 *
 * @author : ZhangYuJie
 * @date : 2022-04-24 14:56
 **/
@Data
public class Work {
    private int hour;

    private Boolean finish=false;

    public void writeProgram() {
        if (hour < 12) {
            System.err.println("当前时间:上午" + hour + "点");
        } else if (hour < 13) {
            System.err.println("当前时间:中午" + hour + "点");
        } else if (hour < 17) {
            System.err.println("当前时间:下午" + hour + "点");
        } else {
            if (finish) {
                System.err.println("当前时间:下班回家" + hour + "点");
            } else {
                if (hour < 21) {
                    System.err.println("当前时间:加班哦,疲累之极" + hour + "点");
                } else {
                    System.err.println("当前时间:不行了,睡着了" + hour + "点");
                }
            }
        }
    }
}

客户端程序:

public static void main(String[] args) {
        Work emergencyProjects = new Work();
        emergencyProjects.hour = 9;
        emergencyProjects.writeProgram();
        emergencyProjects.hour = 10;
        emergencyProjects.writeProgram();
        emergencyProjects.hour = 12;
        emergencyProjects.writeProgram();
        emergencyProjects.hour = 13;
        emergencyProjects.writeProgram();
        emergencyProjects.hour = 14;
        emergencyProjects.writeProgram();
        emergencyProjects.hour = 17;
        emergencyProjects.writeProgram();

        //emergencyProjects.WorkFinished = true;
        emergencyProjects.finish = false;

        emergencyProjects.writeProgram();
        emergencyProjects.hour = 19;
        emergencyProjects.writeProgram();
        emergencyProjects.hour = 22;
        emergencyProjects.writeProgram();
    }

以上代码有个很大的问题:
‘Work’类的’writeProgram’方法很长,而且有很多判断的分支,这也就意味着它的责任过大了。无论是任何状态,都需要通过它来改变,这实际上是很糟糕的。
面对对象设计其实就是希望做到代码的责任分解这个类违背了’单一职责原则’。而且由于’WriteProgram’的方法里面有这么多判断,使得任何需求的改动或增加,都需要更改这个方法。又违背了’开放-封闭原则’。这类有个解决方案,就是’状态模式’。

状态模式的好处是将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于摸个ConcreteState中,所以通过定义新的字类可以很容易地增加新的状态与转换。这样做的目的就是为了消除庞大的条件分支语句。状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖。
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以使用状态模式了。

工作状态-状态模式板

package com.example.designmode.statepattern;

/**
 * <h3>design-mode</h3>
 * <p>抽象状态</p>
 *
 * @author : ZhangYuJie
 * @date : 2022-04-24 15:14
 **/

public abstract  class State {
    public abstract void writeProgram(Work w);
}


上午工作状态

package com.example.designmode.statepattern;

/**
 * <h3>design-mode</h3>
 * <p>上午工作状态</p>
 *
 * @author : ZhangYuJie
 * @date : 2022-04-24 15:14
 **/

public class ForenoonState extends State {
    @Override
    public void writeProgram(Work w) {

        if (w.getHour() < 12)
        {
            System.err.println("当前时间:上午"+w.getHour()+"点");
        } else
        {
            w.setState(new NoonState());
            w.writeProgram();
        }
    }
}

中午工作状态

package com.example.designmode.statepattern;

/**
 * <h3>design-mode</h3>
 * <p>中午工作状态</p>
 *
 * @author : ZhangYuJie
 * @date : 2022-04-24 15:17
 **/

public class NoonState extends State {
    @Override
    public void writeProgram(Work w) {
        if (w.getHour() < 13)
        {
            System.err.println("当前时间: 下午"+w.getHour()+"点");
        } else
        {
            w.setState(new EveningState());
            w.writeProgram();
        }
    }
}

下午工作状态

package com.example.designmode.statepattern;

/**
 * <h3>design-mode</h3>
 * <p></p>
 *
 * @author : ZhangYuJie
 * @date : 2022-04-24 15:36
 **/

public class AfterNoonState extends State {
    @Override
    public void writeProgram(Work w) {

        if (w.getHour() < 13) {
            System.err.println("当前时间:下午" + w.getHour() + "点");
        } else {
            w.setState(new EveningState());
            w.writeProgram();
        }
    }
}

晚间工作状态

package com.example.designmode.statepattern;

/**
 * <h3>design-mode</h3>
 * <p>晚间工作状态</p>
 *
 * @author : ZhangYuJie
 * @date : 2022-04-24 15:18
 **/

public class EveningState extends State {
    @Override
    public void writeProgram(Work w) {
        if (w.getFinish())
        {
            w.setState(new RestState());
            w.writeProgram();
        } else
        {
            if (w.getHour() < 21)
            {
                System.err.println("当前时间:加班哦,疲累"+w.getHour()+"点");
            } else
            {
                w.setState(new SleepingState());
                w.writeProgram();
            }

        }
    }
}

睡眠状态

package com.example.designmode.statepattern;

/**
 * <h3>design-mode</h3>
 * <p>睡眠状态</p>
 *
 * @author : ZhangYuJie
 * @date : 2022-04-24 15:20
 **/

public class SleepingState extends State {
    @Override
    public void writeProgram(Work w) {
        if (w.getHour() < 13) {
            System.err.println("当前时间: 不行了,睡着了。" + w.getHour() + "点");
        }
    }
}

下班休息状态

package com.example.designmode.statepattern;

/**
 * <h3>design-mode</h3>
 * <p>下班休息状态</p>
 *
 * @author : ZhangYuJie
 * @date : 2022-04-24 15:21
 **/

public class RestState extends State {
    @Override
    public void writeProgram(Work w) {
        System.err.println("当前时间: 下班回家了。"+w.getHour()+"点");
    }
}

工作类改造

package com.example.designmode.statepattern;

import lombok.Data;

/**
 * <h3>design-mode</h3>
 * <p>工作状态-改造版</p>
 *
 * @author : ZhangYuJie
 * @date : 2022-04-24 14:56
 **/
@Data
public class Work {
    private int hour;

    private Boolean finish = false;

    private State state;

    public Work() {
        state = new ForenoonState();
    }


    public void writeProgram() {
        this.state.writeProgram(this);
    }

}

客户端代码,没有任何改动。但我们的程序却更加灵活易变了。

public static void main(String[] args) {

        Work emergencyProjects = new Work();
        emergencyProjects.hour = 9;
        emergencyProjects.writeProgram();
        emergencyProjects.hour = 10;
        emergencyProjects.writeProgram();
        emergencyProjects.hour = 12;
        emergencyProjects.writeProgram();
        emergencyProjects.hour = 13;
        emergencyProjects.writeProgram();
        emergencyProjects.hour = 14;
        emergencyProjects.writeProgram();
        emergencyProjects.hour = 17;
        emergencyProjects.writeProgram();

        //emergencyProjects.WorkFinished = true;
        emergencyProjects.finish = true;

        emergencyProjects.writeProgram();
        emergencyProjects.hour = 19;
        emergencyProjects.writeProgram();
        emergencyProjects.hour = 22;
        emergencyProjects.writeProgram();
    }

状态模式总结

状态模式的主要优点在于封装了转换规则,并枚举可能的状态,它将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为,还可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数;其缺点在于使用状态模式会增加系统类和对象的个数,且状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱,对于可以切换状态的状态模式不满足“开闭原则”的要求

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
内容简介: 设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 本课程内容定位学习设计原则,学习设计模式的基础。在实际开发过程中,并不是一定要求所有代码都遵循设计原则,我们要考虑人力、时间、成本、质量,不是刻意追求完美,要在适当的场景遵循设计原则,体现的是一种平衡取舍,帮助我们设计出更加优雅的代码结构。本章将详细介绍开闭原则(OCP)、依赖倒置原则(DIP)、单一职责原则(SRP)、接口隔离原则(ISP)、迪米特法则(LoD)、里氏替换原则(LSP)、合成复用原则(CARP)的具体内容。 为什么需要学习这门课程? 你在日常的开发中,会不会也遇到过同样的问题。系统出现问题,不知道问题究竟出在什么位置;当遇到产品需求,总是对代码缝缝补补,不能很快的去解决。而且平时工作中,总喜欢把代码堆在一起,出现问题时,不知道如何下手,工作效率很低,而且自己的能力也得不到提升。而这些都源于一个问题,那就是软件设计没做好。这门课能帮助你很好的认识设计模式,让你的能力得到提升。课程大纲: 为了让大家快速系统了解设计模式知识全貌,我为您总结了思维导图,帮您梳理学习重点,建议收藏!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值