文档章节

【11】行为型-状态模式

小楼听雨中
 小楼听雨中
发布于 2014/06/27 07:06
字数 970
阅读 19
收藏 0

1、上下文及定义

     去除if-else的一种设计模式,允许一个对象在其内部状态发生变化时改变自己的行为,该对象看起来好像改变了它的类型。具体的State改变了Context的行为。

1、状态:对象实例的属性的值

2、行为:对象的功能,大多可以对应到方法上。

状态模式的功能就是分离状态的行为,通过维护状态的变化,来调用不同状态对应的不同功能。

也就是状态决定行为,对于同一个对象,在不同的运行时刻,行为是不一样的,就像是类被修改了一样。


2、常用场景

例如审核状态的变化,再往前变化,就是工作流


3、解决方法

(1)传统方法实现

(2)枚举方法实现


与策略模式的相同点:

(1)都将行为封装到不同子类

(2)都使用组合代理上下文操作


与策略模式不同点:

(1)状态模式是平行性的,不可替代的;策略模式是平等性的,可以替代的。

(2)状态模式隐藏了状态接口及子类,客户端只操作Context,状态接口及子类对其不可见;策略模式中,客户端可以再运行时选择不同算法,策略接口及具体实现对其可见。


4、抽象模型

5、代码实例

(1)抽象图实例

抽象类

public interface State {
    void push(PaintBoard paintBoard);

    void pull(PaintBoard paintBoard);

    String name();
}

具体实现

public class RedState implements State {
    @Override
    public void push(PaintBoard paintBoard) {
        paintBoard.setState(new GreenState());
    }

    @Override
    public void pull(PaintBoard paintBoard) {
        paintBoard.setState(new BlueState());
    }

    @Override
    public String name() {
        return "RED";
    }
}

public class GreenState implements State {
    @Override
    public void push(PaintBoard paintBoard) {
        paintBoard.setState(new BlueState());
    }

    @Override
    public void pull(PaintBoard paintBoard) {
        paintBoard.setState(new RedState());
    }

    @Override
    public String name() {
        return "GREEN";
    }
}

public class BlueState implements State {
    @Override
    public void push(PaintBoard paintBoard) {
        paintBoard.setState(new RedState());
    }

    @Override
    public void pull(PaintBoard paintBoard) {
        paintBoard.setState(new GreenState());
    }

    @Override
    public String name() {
        return "BLUE";
    }
}

客户端

public class PaintBoard {
    private State state = new RedState();
    //other methods and fields…

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

    public String getCurrentColor() {
        return state.name();
    }

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

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

测试

public class PaintBoardTestDrive {
    public static void main(String[] args) {
        PaintBoardTestDrive test = new PaintBoardTestDrive();
        PaintBoard paintBoard = new PaintBoard();

        System.out.println("Push Test:");
        System.out.println("Paint board current color:" + paintBoard.getCurrentColor());
        test.pushTest(paintBoard);

        System.out.println("\nPull Test:");
        System.out.println("Paint board current color:" + paintBoard.getCurrentColor());
        test.pullTest(paintBoard);
    }

    public void pushTest(PaintBoard paintBoard) {
        for (int i = 0; i < 3; i++) {
            System.out.printf("%s ---push---> ", paintBoard.getCurrentColor());
            paintBoard.push();
            System.out.println(paintBoard.getCurrentColor());
        }
    }

    public void pullTest(PaintBoard paintBoard) {
        for (int i = 0; i < 3; i++) {
            System.out.printf("%s ---pull---> ", paintBoard.getCurrentColor());
            paintBoard.pull();
            System.out.println(paintBoard.getCurrentColor());
        }
    }
}

(2)枚举方法实现

枚举方法

public enum Color implements State {
    RED {
        @Override
        public void push(PaintBoard paintBoard) {
            paintBoard.setState(GREEN);
        }

        @Override
        public void pull(PaintBoard paintBoard) {
            paintBoard.setState(BLUE);
        }
    },
    GREEN {
        @Override
        public void push(PaintBoard paintBoard) {
            paintBoard.setState(BLUE);
        }

        @Override
        public void pull(PaintBoard paintBoard) {
            paintBoard.setState(RED);
        }
    },
    BLUE {
        @Override
        public void push(PaintBoard paintBoard) {
            paintBoard.setState(RED);
        }

        @Override
        public void pull(PaintBoard paintBoard) {
            paintBoard.setState(GREEN);
        }
    };

    @Override
    public void push(PaintBoard paintBoard) {
        throw new UnsupportedOperationException("Invalid push!");
    }

    @Override
    public void pull(PaintBoard paintBoard) {
        throw new UnsupportedOperationException("Invalid pull!");
    }
}

public interface State {
    void push(PaintBoard paintBoard);

    void pull(PaintBoard paintBoard);

    String name();
}

客户端

public class PaintBoard {
    private State state = Color.RED;

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

    public String getCurrentColor() {
        return state.name();
    }

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

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

测试

public class PaintBoardTestDrive {
    public static void main(String[] args) {
        PaintBoard paintBoard = new PaintBoard();
        System.out.println("Push Test:");
        System.out.println("Paint board current color:" + paintBoard.getCurrentColor());
        for (int i = 0; i < 3; i++) {
            pushTest(paintBoard);
        }

        System.out.println("\nPull Test:");
        System.out.println("Paint board current color:" + paintBoard.getCurrentColor());
        for (int i = 0; i < 3; i++) {
            pullTest(paintBoard);
        }
    }

    private static void pushTest(PaintBoard paintBoard) {
        System.out.printf("%s ---push---> ", paintBoard.getCurrentColor());
        paintBoard.push();
        System.out.println(paintBoard.getCurrentColor());
    }

    private static void pullTest(PaintBoard paintBoard) {
        System.out.printf("%s ---pull---> ", paintBoard.getCurrentColor());
        paintBoard.pull();
        System.out.println(paintBoard.getCurrentColor());
    }
}

(3)bad code

public class PaintBoard {
    private Color state = Color.RED;

    public String getCurrentColor() {
        return state.name();
    }

    public void push() {
        switch (state) {
            case RED:
                state = Color.GREEN;
                break;
            case BLUE:
                state = Color.RED;
                break;
            case GREEN:
                state = Color.BLUE;
                break;
            default:
                throw new RuntimeException("Invalid state when pushing");
        }
    }

    public void pull() {
        switch (state) {
            case RED:
                state = Color.BLUE;
                break;
            case BLUE:
                state = Color.GREEN;
                break;
            case GREEN:
                state = Color.RED;
                break;
            default:
                throw new RuntimeException("Invalid state when pulling");
        }
    }
}

public enum Color {
    RED,
    GREEN,
    BLUE
}

测试

public class PaintBoardTestDrive {
    public static void main(String[] args) {
        PaintBoard paintBoard = new PaintBoard();
        System.out.println("Push Test:");
        System.out.println("Paint board current color:" + paintBoard.getCurrentColor());
        for (int i = 0; i < 3; i++) {
            push(paintBoard);
        }

        System.out.println("\nPull Test:");
        System.out.println("Paint board current color:" + paintBoard.getCurrentColor());
        for (int i = 0; i < 3; i++) {
            pull(paintBoard);
        }
    }

    private static void push(PaintBoard paintBoard) {
        System.out.printf("%s ---push---> ", paintBoard.getCurrentColor());
        paintBoard.push();
        System.out.println(paintBoard.getCurrentColor());
    }

    private static void pull(PaintBoard paintBoard) {
        System.out.printf("%s ---pull---> ", paintBoard.getCurrentColor());
        paintBoard.pull();
        System.out.println(paintBoard.getCurrentColor());
    }
}


© 著作权归作者所有

小楼听雨中
粉丝 61
博文 201
码字总数 129524
作品 0
海淀
程序员
私信 提问
小菜学设计模式——设计模式总结之行为型(2)

1、设计模式总结 设计模式总共23个,但是常用的不到10个,下面就把这23个设计模式进行整理归类,具体如下: 1)创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型...

learn_more
2015/07/10
144
0
PHP之设计模型分类(一)

经典的《设计模式》一书归纳出23种设计模式,本文按《易学设计模式》一书归纳分类如下: 1.创建型模式 前面讲过,社会化的分工越来越细,自然在软件设计方面也是如此,因此对象的创建和对象...

peasant
2016/04/29
87
0
设计模式之11个行为型模式

行为型模式概述 行为型模式(Behavioral Pattern)是对在不同的对象之间划分责任和算法的抽象化。 行为型模式不仅仅关注类和对象的结构,而且重点关注它们之间的相互作用。 通过行为型模式,可...

randy_shandong
2017/01/12
0
0
设计模式-创建-singleton(单例)模式

单例模式是一种创建型的模式,适用于 全局只有一个对象的类, 结构图 只有一个静态 实例变量 和一个静态 函数 外部通过Instance() 静态函数来获取 唯一实例 存在的问题: 线程安全性 可用dou...

梦想游戏人
2016/04/28
57
0
一句话总结23种设计模式则

1. 前言 断断续续写了一段时间的设计模式,终于把经典的23种设计模式全写完了。下面对这些设计模式总结一下。 2. 设计原则 设计原则的介绍 : 设计模式的六大原则 即使我们之前没有专门看过这...

四月葡萄
2018/01/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

代理模式之JDK动态代理 — “JDK Dynamic Proxy“

动态代理的原理是什么? 所谓的动态代理,他是一个代理机制,代理机制可以看作是对调用目标的一个包装,这样我们对目标代码的调用不是直接发生的,而是通过代理完成,通过代理可以有效的让调...

code-ortaerc
今天
5
0
学习记录(day05-标签操作、属性绑定、语句控制、数据绑定、事件绑定、案例用户登录)

[TOC] 1.1.1标签操作v-text&v-html v-text:会把data中绑定的数据值原样输出。 v-html:会把data中值输出,且会自动解析html代码 <!--可以将指定的内容显示到标签体中--><标签 v-text=""></......

庭前云落
今天
8
0
VMware vSphere的两种RDM磁盘

在VMware vSphere vCenter中创建虚拟机时,可以添加一种叫RDM的磁盘。 RDM - Raw Device Mapping,原始设备映射,那么,RDM磁盘是不是就可以称作为“原始设备映射磁盘”呢?这也是一种可以热...

大别阿郎
今天
12
0
【AngularJS学习笔记】02 小杂烩及学习总结

本文转载于:专业的前端网站☞【AngularJS学习笔记】02 小杂烩及学习总结 表格示例 <div ng-app="myApp" ng-controller="customersCtrl"> <table> <tr ng-repeat="x in names | orderBy ......

前端老手
昨天
16
0
Linux 内核的五大创新

在科技行业,创新这个词几乎和革命一样到处泛滥,所以很难将那些夸张的东西与真正令人振奋的东西区分开来。Linux内核被称为创新,但它又被称为现代计算中最大的奇迹,一个微观世界中的庞然大...

阮鹏
昨天
20
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部