设计模式之状态模式

替换繁琐if else和多状态转换

  • 概念
  • 使用场景
  • 类图
  • 代码实例

概念

一个对象中存在多种状态,并且不同的状态下对象有不同的行为操作,传统的实现方式就是if else 分支条件就是不同的状态,分支内容就是对应状态下的操作。 如果对象仅仅有一两个状态,不复杂还行。当状态很多且状态转换很复杂时就需要考虑使用状态模式

状态模式:抽象出一个状态接口,if else分支中的条件对应不同的状态子类,将相应状态下操作逻辑放在对应的状态类中(迁移到下个状态 其下个状态是确定的),状态类之间互不影响。 符合开闭原则,当需要增加一个状态时,只需要增加一个类,并实现相应的逻辑。

使用场景

状态模式适用于某一个对象的行为取决于该对象的状态,并且该对象的状态会在运行时转换,又或者有很多的if else判断,而这些判断只是因为状态不同而不断的切换行为。

类图

在这里插入图片描述

Work:相当于Context上下文类,里面包含了抽象状态类(工作状态)

WorkState:抽象工作状态

ForenoonState:上午工作状态 具体的工作状态类,实现接口的方法,该方法就是相当于传统使用if else实现的分支里的内容,并且在其方法内容做状态的转换
HavingLunchState:用餐状态
LunchRestState:午休状态
AfternoonState:下午工作状态
Client:客户端测试,只依赖于Work类进行相应的操作

代码实例

背景:
一个人随着时间改变工作状态也会随之改变,上午工作状态饱满,中午工作状态不行饿了要吃饭,午休时间要睡会觉,下午工作状态饱满,再则进入晚间工作状态,如果没有干完活就需要加班了,到了22点就进入睡眠。
以上场景很常见都是每个人亲身经历过的,根据上面分析出 随着一天当中时间推移,工作者会进入不同的状态,下面我会用传统方式和状态模式实现,可以体会到状态模式的好处。上面可以分出以下几种状态 上午工作状态、中午工作状态、午休工作状态、下午工作状态、晚间工作状态、睡眠状态、下班休闲状态

WorkByTradition 使用传统 if else实现的方式

/**
 * @author duanyimiao
 * @create 2018-10-09 10:38 AM
 * @description 工作类 使用if else实现
 **/
public class WorkByTradition {
    //工作时的钟点
    private Integer hour;
    //工作是否完成
    private Boolean isFinished;

    public static void main(String[] args) {

    }

    /**
     * 重构这本书说到,Long Method很长的一个方法肯定不符合单一职责原则,很多if else语句维护性极差,例如公司有个政策说所有员工在18点之后都要回家不加班,这个时候就需要进行改动,一不小心就会改错了。这些工作对象状态随时间改变而改变,进而产生不同的行为操作,接下来会使用状态模式进行重构。
     */
    public void writeProgram() {
        if (hour < 12) {
            System.out.println("上午开始工作,精神状态倍佳" + hour);
        } else if (hour < 13) {
            System.out.println("肚子咕咕叫,进入用餐时间" + hour);
        } else if (hour < 14) {
            System.out.println("午休十分钟,精神一下午");
        } else if (hour < 18) {
            System.out.println("下午精神饱满,继续努力");
        } else if (hour < 21) {
            if (isFinished) {
                //今天的工作完成了
                System.out.println("go home for having a rest");
            } else {
                System.out.println("加班中");
            }
        } else if (hour < 22) {
            System.out.println("太累了,睡着了 sleep");
        }
    }

    public Integer getHour() {
        return hour;
    }

    public void setHour(Integer hour) {
        this.hour = hour;
    }

    public Boolean getFinished() {
        return isFinished;
    }

    public void setFinished(Boolean finished) {
        isFinished = finished;
    }
}

WorkState 抽象工作状态

/**
 * @author duanyimiao
 * @create 2018-10-09 3:25 PM
 * @description 抽象工作状态
 **/
public interface WorkState {
    /**
     * 在某状态下的行为操作
     * @param work
     */
    void writeProgram(Work work);
}

ForenoonState 上午工作状态


/**
 * @author duanyimiao
 * @create 2018-10-09 3:30 PM
 * @description 上午状态
 **/
public class ForenoonState implements WorkState {
    /**
     * 在上午状态下写代码
     *
     * @param work Work上下文
     */
    @Override
    public void writeProgram(Work work) {
        if (work.getHour() < 12) {
            System.out.println("上午开始工作,精神状态倍佳" + work.getHour());
        } else {
            work.setWorkState(Work.HAVINGLUNCH_STATE);
            work.writeProgram();
        }
    }
}

HavingLunchState 午餐状态

/**
 * @author duanyimiao
 * @create 2018-10-09 3:30 PM
 * @description 午餐状态
 **/
public class HavingLunchState implements WorkState {
    /**
     * @param work Work上下文
     */
    @Override
    public void writeProgram(Work work) {
        if (work.getHour() < 13) {
            System.out.println("肚子咕咕叫,进入用餐时间" + work.getHour());
        } else {
            work.setWorkState(Work.LUNCHREST_STATE);
            work.writeProgram();
        }
    }
}

LunchRestState 午休状态

/**
 * @author duanyimiao
 * @create 2018-10-09 3:30 PM
 * @description 午休状态
 **/
public class LunchRestState implements WorkState {
    /**
     * @param work  Work上下文
     */
    @Override
    public void writeProgram(Work work) {
        if(work.getHour() < 14) {
            System.out.println("午休十分钟,精神一下午");
        }else{
            work.setWorkState(Work.AFTERNOON_STATE);
            work.writeProgram();
        }
    }
}

AfternoonState 下午工作状态

/**
 * @author duanyimiao
 * @create 2018-10-09 3:30 PM
 * @description 下午工作状态
 **/
public class AfternoonState implements WorkState {
    /**
     * @param work Work上下文
     */
    @Override
    public void writeProgram(Work work) {
        if (work.getHour() < 18) {
            System.out.println("下午精神饱满,继续努力");
        } else {
            work.setWorkState(Work.EVENING_STATE);
            work.writeProgram();
        }
    }
}

EveningState 晚间工作状态

/**
 * @author duanyimiao
 * @create 2018-10-09 3:30 PM
 * @description 晚间工作状态
 **/
public class EveningState implements WorkState {
    /**
     * @param work Work上下文
     */
    @Override
    public void writeProgram(Work work) {
        if (work.getFinished()) {
            work.setWorkState(Work.REST_STATE);
            work.writeProgram();
        }else {
            if(work.getHour() < 21) {
                System.out.println("加班中");
            }else {
                work.setWorkState(Work.SLEEP_STATE);
                work.writeProgram();
            }
        }

    }
}

RestState 下班休息状态

/**
 * @author duanyimiao
 * @create 2018-10-09 3:30 PM
 * @description 下班休息状态
 **/
public class RestState implements WorkState {
    /**
     * @param work  Work上下文
     */
    @Override
    public void writeProgram(Work work) {
        System.out.println("go home for having a rest");
    }
}

SleepState 睡觉状态

/**
 * @author duanyimiao
 * @create 2018-10-09 3:30 PM
 * @description 睡觉状态
 **/
public class SleepState implements WorkState {
    /**
     * @param work Work上下文
     */
    @Override
    public void writeProgram(Work work) {
            System.out.println("太累了,睡着了 sleep");
    }
}

Work 工作类

/**
 * @author duanyimiao
 * @create 2018-10-09 3:25 PM
 * @description 工作类(Context上下文类)
 **/
public class Work {
    public static final WorkState FORENOON_STATE = new ForenoonState();
    public static final WorkState HAVINGLUNCH_STATE = new HavingLunchState();
    public static final WorkState LUNCHREST_STATE = new LunchRestState();
    public static final WorkState AFTERNOON_STATE = new AfternoonState();
    public static final WorkState EVENING_STATE = new EveningState();
    public static final WorkState REST_STATE = new RestState();
    public static final WorkState SLEEP_STATE = new SleepState();


    //工作时的钟点
    private Integer hour;
    //工作是否完成
    private Boolean isFinished = false;
    //工作状态
    private WorkState workState;

    public Work() {
        workState = FORENOON_STATE;
    }

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

    public Integer getHour() {
        return hour;
    }

    public void setHour(Integer hour) {
        this.hour = hour;
    }

    public Boolean getFinished() {
        return isFinished;
    }

    public void setFinished(Boolean finished) {
        isFinished = finished;
    }

    public WorkState getWorkState() {
        return workState;
    }

    public void setWorkState(WorkState workState) {
        this.workState = workState;
    }
}

Client 客户端测试类

/**
 * @author duanyimiao
 * @create 2018-10-09 3:26 PM
 * @description
 **/
public class Client {
    public static void main(String[] args) {
        //WorkByTradition work = new WorkByTradition();
        Work work = new Work();
        work.setHour(10);
        work.writeProgram();

        work.setHour(13);
        work.writeProgram();

        work.setHour(15);
        work.writeProgram();

        work.setHour(22);
        work.setFinished(true);
        work.writeProgram();
    }
}

输出结果

上午开始工作,精神状态倍佳10
午休十分钟,精神一下午
下午精神饱满,继续努力
go home for having a rest
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值