21-状态(State)模式Ruby实现

Posted 架构设计模式

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了21-状态(State)模式Ruby实现相关的知识,希望对你有一定的参考价值。

摘要:本文用一个实例场景描述Gof 23设计模式中的状态(State)模式,并用Ruby程序代码给予实现,同时也给出实现代码的UML模型。

关键字Gof 23 设计模式 状态模式 Ruby

State Pattern based on Ruby

REN gang

Abstract:This paper gives a scene example to describe theuse of State Pattern of Gof 23 Design Pattern, and achieves the example by Ruby,at the same time, gives the UML model of realization of the example.

Key word: Gof 23; DesignPattern; State Pattern Ruby

 

1. 标准定义

状态(State)模式标准定义:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

2. 分析和说明

状态(State)模式属于对象行为型模式。状态模式允许一个对象在其内部状态改变的时候改变行为。这个对象看上去象是改变了它的类一样。可理解为在不同的上下文中,相同的动作导致的结果不同。状态模式把所研究的对象的行为包装在不同的状态对象里,每一个状态对象都属于一个抽象状态类的一个子类。状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变。状态模式需要对每一个系统可能取得的状态创立一个状态类的子类。当系统的状态变化时,系统便改变所选的子类。

使用State模式可以将不同状态下的行为分隔开来,这样做的好处是很容易增加新的状态并实现状态转换而不影响已存在的状态和上下文环境。同时还避免了操作中庞大的条件分支语句,使代码更容易维护。

状态(State)模式结构如图1,其角色包括抽象状态(State)角色、具体状态(Concrete State)角色和环境(Context)角色。

 

1 状态模式结构

    抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定的状态所对应的行为。

    具体状态(Concrete State)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。

    环境(Context)角色:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。

3 应用场景举例

比如公司的项目有这么几个状态,项目立项、项目开发、项目试运行、项目验收、项目维护、项目结项等状态。当项目启动的时候,工作是要进行项目立项工作。当项目立项完成后,接下来的工作是项目开发。项目开发完成后,项目的工作变成了项目试运行。当项目试运行完成了,进入了项目验收。当项目验收后,进行项目维护,维护工作结束后,最后是项目结项。整个项目就全部完成了。所以,项目在不同的状态有不同的工作内容。通过设置项目的状态,我们可以知道应该对不同状态的项目采取什么样的工作了。

在这里可以把State抽象类理解为抽象状态(State)角色。ProjectBuilderState类、ProjectDevelopmentState类、ProjectMaintenanceState类、ProjectRunState类和ProjectEndState类是具体状态(Concrete State)角色。Project类是环境(Context)角色。其结构类图如图2所示。ProjectBuilderState类、ProjectDevelopmentState类、ProjectMaintenanceState类、ProjectRunState类和ProjectEndState类继承State抽象类。Project类关联State抽象类,即State类是Project类的一个属性。

2 状态模式类图

 

4Ruby的实现程序代码

Ruby程序实现主要包括Project类,State抽象类,ProjectBuilderState类、ProjectDevelopmentState类、ProjectMaintenanceState类、ProjectRunState类和ProjectEndState类等7个类。其关系如图2所示。下面分别列出这7个类的程序代码,最后列出测试代码并显示输出结果。

程序代码清单

 

 

#!/behavioralpatterns/state

 

class Project

             

       def  initialize(name)

       @projectName  = name

         @currentState = nil

     end

      

       def  ProjectG(projectName)          

              @projectName  = projectName

       end

      

       def  getProjectName

              @projectName

       end

 

       def  setProjectName(projectName)

              @projectName  = projectName;

       end

      

       def  setCurrentState(state)

              @currentState  = state

       end

      

       def  doCurrentWork

              @currentState.doWork(self)

       end

end

 

class State

      

       def  doWork(project)

       end

end

 

class ProjectBuilderState < State

 

       def  doWork(project)     

              puts  project.getProjectName()+"正在进行立项工作"

       end

end

 

class ProjectDevelopmentState < State

 

       def  doWork(project)     

              puts  project.getProjectName()+"正在进行开发工作"

       end

end

 

class ProjectEndState < State

 

       def  doWork(project)     

              puts  project.getProjectName()+"正在进行结项工作"

       end

end

 

class ProjectMaintenanceState < State

 

       def  doWork(project)            

              puts  project.getProjectName()+"正在进行维护工作"

       end

end

 

class ProjectRunState < State

 

       def  doWork(project)     

              puts  project.getProjectName()+"正在进行试运行工作"

       end

end

 

 

# ————————main主程序应用————————

 

bullder = ProjectBuilderState.new

development = ProjectDevelopmentState.new

run =   ProjectRunState.new

maintenance = ProjectMaintenanceState.new

endState =  ProjectEndState.new

             

projectA =  Project.new("projectA")

             

puts   "——————设置项目为立项状态——————"

projectA.setCurrentState(bullder)

projectA.doCurrentWork

             

puts "——————设置项目为开发状态——————"

projectA.setCurrentState(development)

projectA.doCurrentWork

             

puts   "——————设置项目为试运行状态——————"

projectA.setCurrentState(run)

projectA.doCurrentWork

             

puts   "——————设置项目为维护状态——————"

projectA.setCurrentState(maintenance)

projectA.doCurrentWork

             

puts   "——————设置项目为结项状态——————"

projectA.setCurrentState(endState)

projectA.doCurrentWork

 

BEGIN {

    puts "———这是state的输出开始———"

}

 

END {

    puts "———这是state的输出结束———"

}

 

 

状态模式测试类输出结果如下所示:

———这是state的输出开始———

——————设置项目为立项状态——————

rojectA正在进行立项工作

——————设置项目为开发状态——————

rojectA正在进行开发工作

——————设置项目为试运行状态——————

rojectA正在进行试运行工作

——————设置项目为维护状态——————

rojectA正在进行维护工作

——————设置项目为结项状态——————

rojectA正在进行结项工作

———这是state的输出结束———

 

 

参考文献

[1] E.Gamma, R.Helm, R.Johnson, andVlissides. Design Patterns Elements of Reusable Object Oriented Software. Addison-Wesley,1995

[2] E.Gamma, R.Helm, R.Johnson, andVlissides.著,李英军等译,设计模式:可复用面向对象软件的基础,北京:机械工业出版社.20009

[3] (日)高桥征义,(日)后藤裕藏 著,何文斯 译,Ruby基础教程(第4版),北京:人民邮电出版社.2014.09

[4] 许勇 等编著,Ruby on Rails 程序设计 深入剖析与范例应用,北京:清华大学出版社.2013.07

[5] (美)梅茨 著,张雪平,彭晓东译,面向对象设计实践指南:Ruby语言描述,北京:人民邮电出版社.2014.01

[6] Ruby官方网站:www.ruby-lang.org

[7] Ruby教程 http://www.runoob.com/ruby/ruby-tutorial.html



以上是关于21-状态(State)模式Ruby实现的主要内容,如果未能解决你的问题,请参考以下文章

Java单体应用 - 架构模式 - 03.设计模式-21.状态模式

设计模式十四—— 状态模式/策略模式

状态模式State

Java 实现状态(State)模式

状态模式(State Pattern)

状态模式(State)