注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

LabATSS

关注自动测试软件

 
 
 

日志

 
 

LabVIEW面向对象设计模式学习之三:策略模式  

2011-11-07 15:40:05|  分类: LabVIEW |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Strategy Pattern(策略模式)——对象行为型模式

意图:定义一系列的算法,把它们一个个封装起来,并使它们可相互替换。本模式使得算法可独立与使用它的客户而变化(GOF)。

意图:改变一个类的方法行为而无需编辑该方法的实现,从而达到在运行时(run-time)动态的改变方法的行为,并且可以通过一个插件框架在未来扩展该方法的行为。(LVOOP)

意图:定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的的客户.(HeadFirst)

别名:政策(Policy)

Motivation(动机)

 如果你编写的类是根据一个配置参数的不同来相应的选择一个或多个的行为,又或者是在对象初始化的时候依赖一个初始化选项。以上的情境你可以通过使用继承实现一个公共通用的父类和一组针对每种情况的行为的子类,但是一些方法共享同一个行为却分布在各个类中,并且未来不是所有的子类都需要实现一些在父类中定义的方法接口。因此在类中可以使用包含(Contain)一组类,该组类每一个都定义一组行为来对应类中的方法

Implementation(实现)

这个设计模式依赖组合(composition)来封装需要变化的部分类,该类需要定义成为一个Composition,并且该类中包含了不同的方法/数据并将具体变化放置到一组扩充类Compositors之中。在LabView中,一个通用的父类Composition被用做接口来抽象所有的需要具体实现的Compositors。(在其他的语言中,往往用抽象类或一个接口实现父类,而具体的Compositors使用扩展或继承来实现),通过增加新的具体的Compositors来继承并且并不需要修改该组合的逻辑继承组合。

 现在用一个厨师烧菜的例程来说明这个概念:一个Chef.lvclass(厨师类)需要完成制作晚餐的任务因此拥有几个使用的方法来完成任务。每个方法如何实现的细节(每个方法的算法)将依赖于厨师对具体的烹饪器具的选用,相比于为每种烹饪器具定义一个类(如ToasterChef.lvclass,OvenChef.lvclass等),更好的是建立一个独立的Appliance.lvclass,而具体的烹饪器具将继承于它。在运行时Chef.lvclass(厨师类)首先需要被传入一个具体的Appliance.lvclass作为其厨师类的内部私有数据的一部分。厨师类持有这个烹饪器具对象,当其被要求进行烹饪方法时(如Broil.vi),它将调用在烹饪器具中的同一名称的方法,而具体的烹饪器具类将使用它自己的算法。以后,厨师在切换不同的烹饪器具时就可以以不同的方式来处理方法Briol.vi。在本例中Chef.lvclass(厨师类)也被称作为Context,应用程序实例化一个厨师对象被称作客户,Appliance.lvclass是一个策略,而它的子类都是具体策略。

LabVIEW面向对象设计模式学习之三:策略模式 - labats - LabATSS

 Consequences(结果)

策略模式容许你定义一系列可以在运行时被上下文替换的算法。这样替代在方法中的使用的条件结构(Case Structures),条件结构的作用也是依赖于条件来决定呈现哪种行为,你可以使用动态分配(dynamic dispatch)来决定哪个具体策略来使用,策略模式不像场景的简单的子类化来复写其方法,另外策略可以使你动态的变化算法而不需要销毁和重新创建上下文情景环境。

 每个算法簇——如在上面的例子里Appliance.lvclass和它的子类——还可以在多个上下文情景中被复用。以后你可以创建一个Sous-Chef.lvclass,该类型厨师也将以同一种操作方式使用这些烹饪器具,该方式就像我们的Chef.lvclass. 有了策略模式后,为了复用这些算法你仅需要增加一个Appliance.lvclass类的实例到Sous-Chef.lvclass类的私有数据中即可。

 实现策略模式常常会增加在场景中的对象数量,你可以使用上下文场景管理器来管理所有的状态信息来达到减弱该效应,这样将取代把状态放入到具体的算法策略类中并从而在若干对象中实例化。

 在一些案例中,客户将决定上下文情景使用哪一种策略算法,这就需要客户能够识别策略算法的有效性和进行评估,如果有可能,在上下文情景中提供一种行为切换界面(behavior-switching interface)从而达到从客户端将该类职责移除的效果。

Editorial Comments (编者意见)

【David Staab】

虽然在LabVIEW编程语言中并不存在抽象类,但在上面的例子中Appliance.lvclass作用类似抽象类,在计算机领域概念里它的角色实际上是类型定义,对于任何的具象烹饪器具(Oven,Microwave,Toaster),厨师类在编译时并不需要知道具体哪个烹饪器具被使用。子类可以被要求复写一个方法(通过选取在属性对话框中项目设置“Require desendant classes to override this dynamic dispatch VI”选项)。如果方法(method)只是需要选择性复写,那么该方法可以只在Appliance.lvclass类中只实现默认操作或空操作。

 LabVIEW面向对象设计模式学习之三:策略模式 - labats - LabATSS

 

上述例子也定义了一个构造器方法来避免使得Chef.lvclass的方法试图调用一个空的烹饪器具对象,当一个对象被实体化的时候构造器方法是必须需要执行的,但是在LabVIEW编程语言中没有此类定义,所以在此背景下本例使用了一个数据成员——一个布尔型的变量“Constucted”——这样每个需要调用烹饪器具的方法首先检查该变量,以确保烹饪器具对象的构造器方法已被先行调用。这个构造器方法在被调用的时候会设置“Constucted”该数据变量,并且相应地进行其他需要的规定操作过程。

 Strategy and Delegation (策略和委托)

很明白的可以看出:当你面对一个策略模式的时候,你会想到这是一个委托的例子,事实上,你的感觉是正确的,在面向对象编程技术中委托是作为一个技术型术语,一些设计模式实现了委托技术来增加应用程序的重用性和扩展性,策略也是属于这些策略中的之一:通过委托可变的算法到类中并用一个抽象类在上层占位接口,你可以实现运行时再决定哪个具象来替代抽象类。

原外文及配套程序下载链接

  评论这张
 
阅读(477)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017