两种语言实现设计模式(C++和Java)(十六:状态模式)

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

状态模式是一种对象行为型模式,其主要优点如下。

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

状态模式的主要缺点如下。

  1. 状态模式的使用必然会增加系统的类与对象的个数。
  2. 状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。

UML:

示例:

以仓库里的无人仓储物流机器人(AGV)为例,设计AGV的工作模式时,为AGV定义3种状态:空闲状态(接收任务),工作状态(接收新任务后放入任务队列等待执行),故障状态(不接收任何任务),代码实现如下:

 1 #include <iostream>
 2
 3 using namespace std;
 4
 5 //命令类,传递到状态中执行
 6 class Order{
 7 private:
 8     bool accepted;
 9 public:
10     string orderId;
11     Order(string _id){
12         orderId = _id;
13         accepted = false;
14     }
15     void accept(){
16         accepted = true;
17     }
18 };
19
20 //状态抽象类
21 class State{
22 protected:
23     string name;
24 public:
25     State(string _name){
26         name = _name;
27     }
28     virtual void handleNewOrder(Order *order) = 0;
29     string getName(){
30         return name;
31     }
32 };
33
34 //具体状态类
35 class StateRunning:public State{
36 public:
37     using State::State;
38     virtual void handleNewOrder(Order* order){
39         cout << name << "忙碌中,将任务添加到任务序列" << order->orderId << endl;
40         order->accept();
41     }
42 };
43
44 class StateWaiting:public State{
45 public:
46     using State::State;
47     virtual void handleNewOrder(Order* order){
48         cout << name <<"立即执行任务" << order->orderId << endl;
49         order->accept();
50     }
51 };
52
53 class StateFault:public State{
54 public:
55     using State::State;
56     virtual void handleNewOrder(Order* order){
57         cout << name <<"故障,不接收任务" << endl;
58     }
59 };
60
61 //环境类,AGV
62 class Agv{
63 private:
64     State *state;
65 public:
66     void receiveNewOrder(Order* order){
67         state->handleNewOrder(order);
68     }
69
70     void setState(State* state){
71         this->state = state;
72     }
73
74     string getState(){
75         return state->getName();
76     }
77 };
78
79 int main()
80 {
81     Agv agv;
82     State *pStateRunning = new StateRunning("running");
83     State *pStateWaiting = new StateWaiting("waiting");
84     State *pStateFault = new StateFault("fault");
85     agv.setState(pStateRunning);
86     agv.receiveNewOrder(new Order("1"));
87     agv.setState(pStateWaiting);
88     agv.receiveNewOrder(new Order("2"));
89     agv.setState(pStateFault);
90     agv.receiveNewOrder(new Order("3"));
91     return 0;
92 }

Java实现如下:

  1 public class Order {
  2
  3     private String name;
  4
  5     private boolean accepted;
  6
  7     public Order(String name){
  8         this.name = name;
  9         accepted = false;
 10     }
 11
 12     public void accept(){
 13         this.accepted = true;
 14     }
 15
 16     public String getName(){
 17         return this.name;
 18     }
 19 }
 20
 21 public abstract class State {
 22
 23     protected String name;
 24
 25     public State(String name){
 26         this.name = name;
 27     }
 28
 29     public String getName(){
 30         return name;
 31     }
 32
 33     public void handleNewOrder(Order order){}
 34 }
 35
 36 public class StateRunning extends State {
 37
 38     public StateRunning(String name){
 39         super(name);
 40     }
 41
 42     @Override
 43     public void handleNewOrder(Order order) {
 44         System.out.println(name + "忙碌中,将任务添加到任务序列" + order.getName());
 45         order.accept();
 46     }
 47 }
 48
 49 public class StateWaiting extends State {
 50
 51     public StateWaiting(String name){
 52         super(name);
 53     }
 54
 55     @Override
 56     public void handleNewOrder(Order order) {
 57         System.out.println(name + "立即执行任务" + order.getName());
 58         order.accept();
 59     }
 60 }
 61
 62 public class StateFault extends State {
 63
 64     public StateFault(String name){
 65         super(name);
 66     }
 67
 68     @Override
 69     public void handleNewOrder(Order order) {
 70         System.out.println(name + "故障,不接收任务");
 71     }
 72 }
 73
 74 public class Agv {
 75
 76     private State state;
 77
 78     public String getState() {
 79         return state.getName();
 80     }
 81
 82     public void setState(State state) {
 83         this.state = state;
 84     }
 85
 86     public void receiveNewOrder(Order order){
 87         state.handleNewOrder(order);
 88     }
 89 }
 90
 91 public class Main {
 92     public static void main(String[] args) {
 93         Agv agv = new Agv();
 94         State stateRunning = new StateRunning("running");
 95         State stateWaiting = new StateWaiting("waiting");
 96         State stateFault = new StateFault("fault");
 97         agv.setState(stateRunning);
 98         agv.receiveNewOrder(new Order("1"));
 99         agv.setState(stateWaiting);
100         agv.receiveNewOrder(new Order("2"));
101         agv.setState(stateFault);
102         agv.receiveNewOrder(new Order("3"));
103     }
104 }

输出:

running忙碌中,将任务添加到任务序列1
waiting立即执行任务2
fault故障,不接收任务

原文地址:https://www.cnblogs.com/Asp1rant/p/11332748.html

时间: 2024-10-01 00:29:05

两种语言实现设计模式(C++和Java)(十六:状态模式)的相关文章

javascript设计模式学习之十六——状态模式

状态模式的关键是区分事务内部和外部的状态,事务内部状态改变往往会带来事务的行为改变. 状态模式中有意思的一点是,一般我们谈到封装,都是优先封装对象的行为,而非对象的状态.但在状态模式中刚好相反,状态模式的关键是把事务的每种状态都封装为单独的类,跟此种状态有关的行为都封装在这个类的内部.与此同时,我们还可以把状态的切换规则实现分布在状态类中,这样就有效消除了原本存在的大量条件分支语句.

两种语言实现设计模式(C++和Java)(五:代理模式)

参考:https://blog.csdn.net/lh844386434/article/details/18045671 代理模式指为其他对象提供一种代理以控制对这个对象的访问.这样实现了业务和核心功能分离. Subject: 抽象角色.声明真实对象和代理对象的共同接口.Proxy: 代理角色.代理对象与真实对象实现相同的接口,所以它能够在任何时刻都能够代理真实对象.代理角色内部包含有对真实对象的引用,所以她可以操作真实对象,同时也可以附加其他的操作,相当于对真实对象进行封装.RealSubj

两种语言实现设计模式(C++和Java)(十四:责任链模式)

责任链模式实现为请求创建了一个接收者对象的链.当请求的直接执行者无法实现请求时,会将请求传递给链的上一级进行处理.这种传递往往可以通过让接收者包含另一个接收者的引用的方式实现. 责任链模式是一种对象行为型模式,其主要优点如下. 降低了对象之间的耦合度.该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息. 增强了系统的可扩展性.可以根据需要增加新的请求处理类,满足开闭原则. 增强了给对象指派职责的灵活性.当工作流程发生变化,可以动态地改变链内的

详谈线性表的有关操作(Java、C两种语言)

    之前在学习线性表一章的时候,有些地方都是比较含糊的带过,只是把一些比较难理解的地方花了好长时间才明白....然后写出代码,存在博客上面.从今天开始,将重新把数据结构这本书走一遍,用C和Java两种语言,尽量把每个部分都可以用代码实现一遍,使印象更加深刻,也算是重新学习一下C语言啦~~.而且现在新学期开始学Oracle啦,也会把一些学习过程中的代码以及重点难点记录下来,希望大家会关注哦~~    线性表的概念都在之前的文章有提到,今天来说一下有关线性表的具体操作(数组实现),分为以下几个部

1003. 我要通过!(20)(两种语言的运行时间差异)

"答案正确"是自动判题系统给出的最令人欢喜的回复.本题属于PAT的"答案正确"大派送 -- 只要读入的字符串满足下列条件,系统就输出"答案正确",否则输出"答案错误". 得到"答案正确"的条件是: 1. 字符串中必须仅有P, A, T这三种字符,不可以包含其它字符: 2. 任意形如 xPATx 的字符串都可以获得"答案正确",其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串:

Spring定时器配置的两种实现方式OpenSymphony Quartz和java Timer详解

原创整理不易,转载请注明出处:Spring定时器配置的两种实现方式OpenSymphony Quartz和java Timer详解 代码下载地址:http://www.zuidaima.com/share/1772648445103104.htm 有两种流行Spring定时器配置:Java的Timer类和OpenSymphony的Quartz. 1.Java Timer定时 首先继承java.util.TimerTask类实现run方法 import java.util.TimerTask; p

使用OC和Swift两种语言写一个发射烟花的小项目

OC与Swift两种实现方式基本上区别不大,主要是在一些对象或方法的调用方式不同 OC代码样式: self.view.backgroundColor = [UIColor blackColor]; //加载颗粒状的火花图片 CAEmitterLayer *emitterLa = [CAEmitterLayer layer]; emitterLa.emitterPosition = CGPointMake(self.view.bounds.size.width/2, self.view.bound

Java设计模式菜鸟系列(十六)原型模式建模与实现

转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/39997337 原型模式(Prototype):该模式的思想就是将一个对象作为原型,对其进行复制.克隆,产生一个和原对象类似的新对象.而这里的复制有两种:浅复制.深复制. 浅复制:将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的. 深复制:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的.简单来说,就是深复制进行了完全彻底的复制,而浅复

设计模式十之状态模式1

状态模式,允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类. 这个模式将状态封装成为独立的类,并将动作委托到代表当前状态的对象,我们知道行为会随着内部状态而改变.糖果机提供了一个很好地例子:当糖果机是在NoQuarterState或HasQuarterState两种不同的状态时,你投入25分钱,就会得到不同的行为(机器接受25分钱和机器拒绝25分钱). 如果说你使用的对象能够完全改变它的行为,那么会觉得,这个对象实际上是从别的类实例化而来的.然而,实际上,我们是在使用组合通过简单