22-策略(Strategy)模式Ruby实现

Posted 架构设计模式

tags:

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

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

关键字Gof 23 设计模式 策略模式 Ruby

Strategy based on Ruby

REN gang

Abstract:This paper gives a scene example to describe theuse of Strategy 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; Strategy Pattern Ruby

 

1. 标准定义

策略模式标准定义:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。

2. 分析和说明

策略(Strategy)模式属于对象的行为模式,通过分析Strategy模式可以发现:策略模式针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。策略模式把行为和环境分开。环境类负责维持和查询行为类,各种算法在具体的策略类中提供。由于算法和环境独立开来,算法的增减,修改都不会影响到环境和客户端。

在软件设计中,经常会遇到因为一开始考虑不够长远而导致后面遇到很大的麻烦。开发者只是想尽快地解决问题而没考虑到后期的维护或者根本没法预料到将来会有什么样的变化干脆置之不理。针对这个问题,Strategy模式提供了一个解决问题的方案:面向接口编程而不是实现,发现其中会改变的部分作为扩展点,然后把它封装起来。

Strategy结构如图1所示,其角色包括环境(Context)角色、抽象策略(Strategy)角色和具体策略(Concrete Strategy)角色。

1 策略模式结构

环境(Context)角色:拥有一个Strategy接口的引用。环境(Context)角色可以是接口、具体类或抽象类。该角色不可缺少。

抽象策略(Strategy)角色:这是一个抽象角色,此角色给出所有的具体策略类所需的统一接口,或者是定义所有支持的算法的公共接口。通常由一个接口或抽象类实现。

具体策略(Concrete Strategy)角色:包装了相关的算法或行为。具体策略(ConcreteStrategy)角色都是由具体类来实现。以Strategy接口实现某具体算法。

当客户调用Context时,它将客户的请求转发给它的StrategyContext将该算法所需的所有数据传递给Strategy,或者将自身作为参数传递给Strategy,使Strategy可以回调ContextConcreteStrategy实现具体算法。

3 应用场景举例

比如公司在多个行业中有项目,对于不同的行业,项目有不同的做法。行业项目就是环境(Context)角色。有一个抽象策略(Strategy)角色。而银行行业项目管理策略、能源行业项目管理策略、电信行业项目管理策略、政府项目管理策略全部都继承抽象策略并有各个行业的实现模式。

在这里可以把Project类理解为环境(Context)角色。Strategy抽象类是抽象策略(Strategy)角色。BankStrategy类、GovernmentStrategy类、TelecomStrategy类是具体策略(Concrete Strategy)角色。其实现类图如图2所示。BankStrategy类、GovernmentStrategy类和TelecomStrategy类继承Strategy抽象类,Project类关联Strategy抽象类。

2 策略模式类图

 

4Ruby的实现程序代码

Ruby程序实现主要包括Project类,Strategy抽象类,BankStrategy类、GovernmentStrategy类和TelecomStrategy类等5个类。其关系如图2所示。下面分别列出这5个类的程序代码,最后列出测试代码并显示输出结果。

程序代码清单

 

 

#!/behavioralpatterns/strategy

 

class Project          

      

       def  initialize(projectName)

       @projectName = projectName

         @strategy = nil

     end

 

       def  Project(projectName,strategy)

         @projectName = projectName

         @strategy = strategy

       end

      

       def  getProjectName

              @projectName

       end

      

       def  setProjectName(projectName)

              @projectName  = projectName

       end

 

       def  getStrategy

              @strategy

       end

 

       def  setStrategy(strategy)

              @strategy  = strategy

       end

      

       def  doCommonWork    

       end

      

       def  doStrategyWork()

              @strategy.doWork(self)

       end

end

 

class Strategy

      

       def  doWork(project)

       end

end

 

class BankStrategy < Strategy

      

       def  doWork(project)     

              puts  project.getProjectName()+"采用银行策略的工作。"        

       end

end

 

class GovernmentStrategy < Strategy

      

       def  doWork(project)     

              puts  project.getProjectName()+"采用政府策略的工作。"        

       end

end

 

class TelecomStrategy < Strategy

      

       def  doWork(project)     

              puts  project.getProjectName()+"采用电信策略的工作。"        

       end

end

 

 

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

 

puts "——————要求projectA采用银行策略——————"

projectA =  Project.new("projectA")

strategy1 = BankStrategy.new

projectA.setStrategy(strategy1)

projectA.doStrategyWork();

             

puts "——————要求projectB采用政府策略——————"

projectB =  Project.new("projectB")

strategy2 = GovernmentStrategy.new()

projectB.setStrategy(strategy2)

projectB.doStrategyWork()

             

puts "——————要求projectC采用电信策略——————"

projectC =  Project.new("projectC")

strategy3 = TelecomStrategy.new()

projectC.setStrategy(strategy3)

projectC.doStrategyWork()

 

BEGIN {

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

}

 

END {

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

}

 

 

策略模式测试类输出结果如下所示:

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

——————要求projectA采用银行策略——————

rojectA采用银行策略的工作。

——————要求projectB采用政府策略——————

rojectB采用政府策略的工作。

——————要求projectC采用电信策略——————

rojectC采用电信策略的工作。

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

 

 

参考文献

[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



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

策略模式(Strategy)

策略模式-Strategy(Java实现)

Java 实现策略(Strategy)模式

图解设计模式-Strategy模式

C++设计模式——策略模式(Strategy Pattern)

策略(Strategy)模式