GoF总结-18(状态模式)

213 阅读3分钟

本文已参与[新人创作礼]活动,一起开启掘金创作之路

1. 概念

对有状态的对象,把复杂的"判断逻辑"提取到不同的状态对象中,允许状态对象在其内部发生改变时改变其行为。 状态模式是一种对象行为型模式。

2. 优点

  1. 结构清晰,状态模式将于特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足"单一职责原则"。
  2. 将状态转换显示化,减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。
  3. 状态类职责明确,有利于程序的扩展。通过定义新的子类很容易地增加新的状态和转换。

3. 缺点

  1. 状态模式的使用必然会增加系统的类与对象的个数。
  2. 状态模式的结构与实现都较为复杂,如果使用不当会道之程序结构和代码的混乱。
  3. 状态模式对开闭原则的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改哪些负责状态转换的源码,否则无法切换到新增状态,而且修改某个状态类的行为也需要修改对应类的源码。

4. 结构与实现

状态模式把受环境改变的对象行为包装在不同的状态对象里,其意图是让一个对象在其内部状态改变的时候,其行为也随之改变。

4.1 结构

主要角色:

  1. 环境类角色:也称为上下文,它定义了客户端需要的接口,内部维护一个当前状态,并负责具体状态的切换。
  2. 抽象状态角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为,可以有一个或多个行为。
  3. 具体状态角色:实现抽象状态所对应的行为,并且在需要的情况下进行状态切换。 在这里插入图片描述

4.2 实现

//环境类
public class Context {
    private State state;

    public Context() {
        this.state = new Weiding();
    }

    public State getState() {
        return state;
    }

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

    public void handle() {
        state.handle(this);
    }
}
//抽象状态类
public abstract class State {
    public abstract void handle(Context context);
}
//具体状态 我也不知道我心情咋样
public class Weiding extends State {
    @Override
    public void handle(Context context) {
        System.out.println("早上刚起床,我也不知道我心情咋样");
        double tianqi = Math.random();
        System.out.println(tianqi);
        if (tianqi > 0.7) {
            System.out.println("推开窗,阳光明媚,心情好");
            context.setState(new Kaixin());
        } else if (tianqi > 0.4) {
            System.out.println("下雨了,心情不好了");
            context.setState(new Shangxin());
        } else {
            System.out.println("心情无变化");
        }
    }
}
//具体状态 开心
public class Kaixin extends State {
    @Override
    public void handle(Context context) {
        System.out.println("今天很开心");
        double tianqi = Math.random();
        System.out.println(tianqi);
        if (tianqi > 0.7) {
            System.out.println("没出门,心情不知道咋样");
            context.setState(new Weiding());
        } else if (tianqi > 0.4) {
            System.out.println("下雨了,心情不好了");
            context.setState(new Shangxin());
        } else {
            System.out.println("心情无变化");
        }
    }
}
//具体状态 伤心
public class Shangxin extends State {
    @Override
    public void handle(Context context) {
        System.out.println("今天很伤心");
        double tianqi = Math.random();
        System.out.println(tianqi);
        if (tianqi > 0.7) {
            System.out.println("推开窗,阳光明媚,心情好");
            context.setState(new Kaixin());
        } else if (tianqi > 0.4) {
            System.out.println("没出门,不知道心情咋样");
            context.setState(new Weiding());
        } else {
            System.out.println("心情无变化");
        }
    }
}

测试

public class StateTest {
    @Test
    public void test1() {
        Context context = new Context();
        for (int i = 0; i < 3; i++) {
            context.handle();
        }
    }
}

在这里插入图片描述