前言

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

为什么学习OOP

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


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

与软件维护类似的情况最先出现在刻板应刷中,那时的古人一旦设计完成系统,将祈求不再变更。因为一旦变更,其代价就会非常大,需要重新制版印刷,如果连续变更就会意味着连续的修改刻板,带来了人力和物料的大量浪费

 但是,聪明的中国人,将每一个字都做一个小的刻板,印刷系统将会变为如下的例子
通过某些小模块的替换,可以让印刷更加灵活多变,这种思想的转变也就是活字印刷的成功。

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

在软件设计的历史上,OOP的出现也引发了一场设计的革命,这也是我们不得不学习OOP思想的重要原因。

简单工厂模式

既然了解了OOP思想,那OOP的第一个使用方法莫过于简单工厂模式。
通常,在传统的面向过程设计中,使用Case结构来解决不同情况的出现
 

但是当多个函数中都需要进行判断时,Case结构将会写很多个,并且每一次维护代码均需要了解之前的设计,极易造成误修改。

为此,简单工厂模式出现,实现了程序设计的简化。

了解UML类图,可以发现程序在运行时动态选择执行的内容,通过类的继承,可以实现对原有方法的轻易拓展;改动的时候不影响主程序的原有设计,实现了针对接口而不是实现编程。

策略模式

策略模式的学习,我使用《大话设计模式》的例子,做一个深入的了解和熟悉。

该模式的目的是实现一个商场收银软件,通过文本框来输入单价和数量,从而计算输出的结果。

使用传统的方法快速设计,不超过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设计文章,并且借用商城打折的例子,设计了基于简单工厂的程序,通过对策略的分析,了解了简单工厂和策略模式的联合设计。最后使用开闭原则,将程序的改动仅仅停留在了控件的变更,实现了代码的可拓展和可维护。

后记

感谢大家这么长时间的关注,也谢谢各位的打赏和认可。接下来的一段时间,小黑将要忙自己的婚姻大事去啦,期间的一些学习内容将会在结婚后更新,希望大家多多支持~

撒一波狗粮~~~~~
 

【LabVIEW技巧】策略模式的更多相关文章

  1. 【LabVIEW技巧】工厂模式_简单工厂

    前言 上一个文章介绍了如何学习LabVIEW OOP,简要的提及了一些OOP学习中注意的事项,许多文章的读者反映写的太范,后文会逐步缩小范围,讨论在LabVIEW中各个模式的应用. 工厂模式概述 工厂 ...

  2. 大熊君说说JS与设计模式之------策略模式Strategy

    一,总体概要 1,笔者浅谈 策略模式,又叫算法簇模式,就是定义了不同的算法,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 策略模式和工厂模式有一定的类似,策略模式相对简单容易理解,并 ...

  3. LVOOP设计模式在路上(二)-- 策略模式

    前言 最近工作还挺忙的,连着好些周都是单休了,今天休息在家就来写写关于策略模式的理解和labivew的实现. 正文 1.什么是策略模式 定义是这样描述的:它定义了算法家族,分别封装起来,让它们之间可以 ...

  4. 设计模式 (一)——策略模式(Strategy,行为型)

    1.概述 使用设计模式可以提高代码的可复用性.可扩充性和可维护性.策略模式(Strategy Pattern)属于行为型模式,其做法是将类所需的行为或者算法一个个封装成单独的类,并将其作为类的数据成员 ...

  5. 【LabVIEW技巧】LabVIEW OOP怎么学

    前言 有很多人对LabVIEW OOP存在比较极端的看法,大致分为两类: 1. 绝对否定派认为LabVIEW OOP只不过是LabVIEW为了追求时髦,在面向过程的基础上用簇做了一些特性,实际上完全不 ...

  6. 《Mybatis 手撸专栏》第10章:使用策略模式,调用参数处理器

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 你这代码写的,咋这么轴呢! 说到轴,让我想起初中上学时老师说的话:"你那脑 ...

  7. javascript设计模式:策略模式

    前言 策略模式有效利用组合.委托.多态等技术和思想,可以有效避免多重条件选择语句. 策略模式对开放-封闭原则提供了很好的支持,将算法封装在strategy中,使得他们易于切换.理解.扩展. 策略模式中 ...

  8. StrategyPattern (策略模式)

    /** * 策略模式 * @author TMAC-J * 根据环境的不同选择不同的策略,把策略用接口抽象出来 */ public class StrategyPattern { interface ...

  9. JAVA 设计模式之策略模式

    定义:定义一组算法,将每个算法都封装起来,并且使他们之间可以互换. 类型:行为类模式 策略模式是对算法的封装,把一系列的算法分别封装到对应的类中,并且这些类实现相同的接口,相互之间可以替换.在前面说过 ...

随机推荐

  1. BZOJ4247 挂饰(动态规划)

    相当于一个有负体积的背包.显然如果确定了选哪些,应该先把体积小的挂上去.于是按体积从小到大排序,就是一个裸的背包了. #include<iostream> #include<cstd ...

  2. BZOJ4027 HEOI2015兔子与樱花(贪心)

    首先显然地如果某个点超过了最大负载,删掉它仍然是不合法的.删除某个点当前只会对其父亲产生影响,同一个节点的儿子显然应该按代价从小到大删.考虑如果删掉某个点之后他的父亲不能再删了,我们损失了父亲这个点, ...

  3. 【Luogu】P2901牛慢跑(K短路模板)

    题目链接 K短路居然用A*……奇妙. 先建反图从终点(1)跑一遍最短路,再A*,用堆存当前点到终点距离+从起点到当前点距离. 每次取出终点都可以视为发现了一个新的最短路. #include<cs ...

  4. hdu 3030 Increasing Speed Limits (离散化+树状数组+DP思想)

    Increasing Speed Limits Time Limit: 2000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java ...

  5. POJ1061:青蛙的约会——题解

    http://poj.org/problem?id=1061 Description 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定 ...

  6. BZOJ5249:[九省联考2018]IIIDX——题解

    https://www.luogu.org/problemnew/show/P4364#sub https://www.lydsy.com/JudgeOnline/problem.php?id=524 ...

  7. LG. 1003 铺地毯

    LG. 1003 铺地毯 题意分析 给出平面中地毯的左上角坐标和长宽,然后给出一点(x,y).求此点最上面是哪个地毯的编号,若没被覆盖则输出-1. 将所有地毯的信息存在一个结构体中,由于后埔地毯在上面 ...

  8. Vue_WebPack小白入门

    Vue语法笔记 Vue项目搭建过程 Vue问题总结 去掉vue 中的代码规范检测(Eslint验证) 解决跨域请求问题 Vue推荐资料

  9. 51nod 1273 旅行计划(思维题)

    一开始看到这题真的有点懵逼...一直在想着套算法,结果题解除了sort和dfs其他什么都没用到 显然每次到达的一定都是叶子,先从根节点dfs一遍,按深度对叶子降序排序,按这个顺序向根节点dfs,路径上 ...

  10. 清北学堂模拟赛d6t6 棋盘迷宫

    3.棋盘迷宫(boardgame.pas/c/cpp)(boardgame.in/out)时间限制:5s/空间限制:256M[题目描述]小 A 和小 Z 是非常要好的朋友, 而且他们都对迷宫游戏非常有 ...