首页 > 代码库 > 【LabVIEW技巧】策略模式

【LabVIEW技巧】策略模式

前言

在之前的文章中,我们提到了如何学习OOP以及对应的简单工厂模式,由于时间比较长,我们先回顾一下之前讲到的一些内容,然后继续了解策略模式。

为什么学习OOP

在测控系统的软件开发过程中,我们LabVIEW工程师一直认为程序完成功能就可以了,但是随着程序的越来越复杂,我们发现很多情况下成型系统到后期无法添加功能或很难添加功能。

是什么阻碍了我们软件系统的开发?为什么在需求沟通不明确的前期,我们无法开发软件;在需求明确的后期,又无法对软件进行灵活修改。

如果大家仔细分析中国的四大发明,就会发现活字印刷非常类似于我们的软件OOP思想。在我们传统的刻板印刷中,我们一旦设计完成系统,再对其变更时,代价就会非常大,需要重新制版印刷,如果连续变更就会意味着连续的修改刻板。古人一定对书籍的变更非常痛恨吧~
技术分享
 但是,当古人转换思想,将每一个字都做一个小的刻板,印刷系统将会变为如下的例子
技术分享
通过某些小模块的替换,可以让印刷更加灵活变更。这种思想的转变正式活字印刷成为四大发明的根本。

在软件设计的过程中,也出现了类似的“活字印刷”术--面向对象思想。通过单一职责原则,OOP设计可以将系统分割为功能单一的很多小模块,通过小模块的拼接,组织不同的程序。一旦任何一处的模块发生了变化,我们只需修改固定的一些模块,即可让我的系统发生变化。

可见,在软件设计的历史上,OOP的出现也引发了一场设计的革命。

简单工厂模式

既然了解了OOP思想,那OOP的第一个使用方法莫过于简单工厂模式了。
通常,我们在传统的面向过程设计中,使用Case结构来解决不同情况的出现
技术分享
 
但是当我们在多个函数中都需要进行判断时,我们的Case结构将会写很多个,并且每一次维护代码均需要了解之前的设计,一步小心还会改错代码。
技术分享
为此,简单工厂模式出现,进行了公共行为的抽象,并且通过简单工厂对输出的内容进行选择
技术分享
通过选择,可以让程序在运行时动态选择执行的内容,通过类的继承,可以实现对原有方法的轻易拓展。而且改动的时候不影响主程序的原有设计,实现了针对接口而是实现编程。
技术分享

 策略模式

策略模式的学习,我使用《大话设计模式》的例子,一边学习一边熟悉。

该模式的目的是实现一个商场收银软件,通过文本框来输入单价和数量,从而计算输出的结果。
技术分享
使用传统的方法快速设计完成了代码,不超过10分钟就完成了功能 技术分享
 当我们完成代码后,新的需求改动来了,商场需要增加打折系统,可以对输出的总价进行不同程度的打折,于是,我们增加打折功选项。为了保证商家可以自由控制打折力度,所以我们需要支持不打折和打不同折。
技术分享
当商场需要增加满减活动(如满200减30)时,我们又需要改动程序,增加一个子VI,并且修改程序的连线。

简单工厂实现

为了避免对主程序修改并优化逻辑设计,我们尝试使用OOP思想对该程序进行改进。

 分析程序需求,我们发现用金额计算的算法是这段程序中最容易变化的部分,所以对这段算法进行抽象,抽象后的类图如下。
技术分享

算法抽象 

在程序中,我们将变化的部分抽象为AbstractCash,其具有AcceptCash的方法,可以输入当前的金额,并且返回计算后的结果。
技术分享
 对于采取的商城策略一共有3种类型的处理方式,我们继承抽象并实现这一方法。

对于CashNormal,我们不做任何处理。
技术分享
 对于CashRebate,可以配置打折比例,并且在运算中对其进行相应的处理
技术分享
技术分享
 
CashReturn不同于其他算法,需要增加moneyCondition与moneyReturn两个参数来计算是否执行返现
技术分享

工厂设计 

至此,我们完成了算法的设置,接下来设计工厂类。此处由于工厂类只有一个方法,也没有属性,所以使用一个子VI来代替类
不打折时,我们使用不打折的类作为输出
技术分享
 打八折时,我们使用CashRebate作为输出
技术分享
 设计满减活动时,我们只需要使用CashReturn类即可
技术分享

 主程序设计

完成设计后,主程序只需要调用抽象的方法即可编写程序
技术分享
当某一类的方法拓展时,我们只需要在工厂分支中增加一个Case即可,如打7折。除此之外对不碰任何的其他程序,实现了程序的快速拓展,而又不影响原有的代码。
技术分享
 如拓展一个满减活动时,我们同样只改动简单工厂的方法
技术分享
如拓展一个新的打折活动,如打折和满减同时作用,我们只需要在类图上新增一个继承类,并修改简单工厂即可。
技术分享
经过试验,整个程序既具有了完善的功能,也实现了特殊变化点的快速拓展。
技术分享

 策略模式实现

简单工厂的程序已经使用到了策略模式的思想,通过抽象运算策略,来实现相同顶层方法的复用,这里在此基础上,引出策略模式的设计类图。
技术分享
在策略模式中,我们定义了一个抽象的策略,AbstractCash和3个具体的策略,分别是CashNormal、CashRebate、CashReturn。这里的策略与上文简单工厂中的策略是一样的,不同仅仅在策略模式选择的地方稍有差别。

为了封装策略的变化,使用CashContext聚合AbstractCash,利用GetResult的多态,实现不同策略的替换
技术分享
在接口设计时,结合简单工厂模式,可以将程序改进为工厂+策略模式
技术分享
使用策略模式封装后,我们发现,相比于简单工厂模式的例子,
1.我们在顶层程序完全封装了算法,只需要与给出的预定API交互即可
2.底层的算法变更不会影响主程序的设计,实现了策略的封装和拓展技术分享

 继续优化代码

策略模式中,我们仍需要每次修改枚举的时候重新编写Case结构,优化工厂的解析策略,可以实现自动初始化特定的类,修改如下
技术分享
 通过正则表达式,对枚举的规则进行解析,可以实现自动选择正确的执行策略,从而后续的代码修改将只针对于界面上数值的变化。

总结

本文回顾了之前的OOP设计文章,并且借用商城打折的例子,设计了基于简单工厂的程序,通过对策略的分析,了解了简单工厂和策略模式的联合设计。最后使用开闭原则,将程序的改动仅仅停留在了控件的变更,实现了代码的可拓展和可维护。

后记

接下来的一段时间,小黑将要忙自己的婚姻大事去了,期间的一些内容将会在结婚后更新,希望大家多多支持~

撒一波狗粮撤退啦~
技术分享
 


null


【LabVIEW技巧】策略模式