前言:
虽然做了个Demo但是实际应用的时候发现一开始对简单工厂与策略的理解有误差、开始想输入时间和基础数据就根据不同的算法算出来、后来发现不是、其实时间也是计算的数据、真正选择算法的是像固定用户和临时用户、或者说打折促销、根据这个。
深夜食堂
一个在深夜12点到凌晨7点开张的小食店、被大家称谓深夜食堂、菜单上只有一样菜、但是、无论你要点什么、只要老板会做、即使菜单上没有的菜也可以点、所以、客人还真不少呢。
日式滑动的木门被打开、进来的是一个浑身又绿色、有着硬壳的家伙、没错、他是富兰克林、老板,清酒、酒蒸蛤蜊。
老板一边做着、一边调侃道,怎么了?又被老板剥削了?富兰克林紧攥拳头、碰!敲桌子说道,哼!看着吧!他那臭煤窑早晚塌了!赔死他个黑心鬼!
清酒与酒蒸蛤蜊、老板端了上来、滋滋滋……嗯!果然酒蒸蛤蜊跟清酒一起、最美味了、呦呦呦、这不是我们伟大的IT人士、富兰克林嘛!肉白卡推门、探出头说道。
肉白卡……你怎么也大晚上的来吃料理?哎、这不是上下机刚做完嘛、出来吃夜宵、怎么龟龟涨工资了?都吃海鲜了?
PEI!别提了、不打算干了、那老板给软件输入钱跟没改一样、而且这次有了软件还不能钻空子了、这不赶到这点刚下班= =、你上下机怎么样了?
今天刚搞完、呐呐、还带着UML图呢、老板、章鱼烧三份、今天我心情好、富兰克林你上次那个不太对、我改了改,最后也用上了、策略模式的所有策略都是可以互相替换的、你一个输入2个数一个输入3个数那啥玩应啊。
去去去……的了便宜还卖乖、没我的Demo、你能做出来?UML图拿来
章鱼烧、请慢用、哇真香、嗯!皮酥肉嫩、加上柴鱼片和海苔丝、真是美味!
赶紧的!别废话!富兰克林叫到……
好好好、那咱先看抽象算法类与算法
这里我定义了两个算法、一个是上机临时用户的、一个是固定用户的、每个算法一个类、都继承与算法抽象类、都有一个算法方法。这个没问题吧
富兰克林很鄙视的看着满嘴章鱼丸的肉白卡……继续 - -
那说策略类
策略类声明了一个抽象算法、生命的抽象算法用的却是子类、他有两个方法、一个用于接收策略、另一个用于使用策略的方法、好处就不言而喻了、现在只有固定用户和临时用户、我可以再加个打折算法、直接在算法抽象类下面加个类就好啦、啥代码都不用改。
那工厂模式你咋仨方法了呀= =富兰克林问到
这个就要好好说下了、龟龟啊、你没发现我比你多些了一个有很多变量和方法的类吗?
又下角的那个?countData?
对!那是一个类似实体的类、里面是计算要用的参数、如每小时的钱、是固定用户还是临时用户、上机持续时间等、我工厂下的AddData方法就是把传进来的2个实体和一个参数传给countData、这样就解了耦合、假如我这个算法放到别的软件中、只要改下AddData方法、把参数都对应上、其他代码就不用改了、如果直接用给的参数名或者参数计算、那换个地方、传值的名字都要改。
IFCount这是工厂的核心、根据传进来是固定用户还是临时用户、选择算法、NEW算法类、返回一个算法类的实例对象。
CountMoney这个方法是我自己填的、他调用了AddData和 IFCount并且最后使用了工厂给出的算法对象、进行计算、简单后所就是外界只要知道这个类的这一个方法、输入值、方法就能直接返回Money结果。
综上所述、如果我加一个策略、只需要在抽象算法类下加一个子类、改下工厂的 IFCount、填一条小小的Case就好啦、咋样富兰克林?
真是太……太精彩了……富兰克林擦了擦脸上的章鱼烧碎屑……说道
富兰克林:这样吧、我辞了工作跟你干吧
好呀!我们公司最近做项目正好有个人女程序员因为抑郁、在宿舍那跳楼了、正好、你也是搞过的、应该没问题!这样吧、我给你这次的代码、你回去研究下。
''' <summary> ''' 简单工厂类 ''' </summary> ''' <remarks></remarks> Public Class CashFactory ''' <summary> ''' 传进算法所需要的值、请确定值不为空 ''' </summary> ''' <param name="bname">只能输入-固定用户-临时用户</param> ''' <param name="bComputerRecords"></param> ''' <param name="bBaseData"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function AddData(bname As String, bComputerRecords As Entity.EComputerRecords, bBaseData As Entity.EBaseData) As countData Dim countData As New countData '定义传递对象 '(复制代码的话请把传入值改了、并与此处一一对应上) '工厂判定 'countData.str = bname countData.str = "固定用户" '上机时间 countData.consumeTime = bComputerRecords.ConsumeTime 'countData.consumeTime = 35 '准备时间 countData.readyTime = bBaseData.ReadyTime 'countData.readyTime = 5 '固定用户半小时费用 countData.fixedMoney = bBaseData.FixedHalfHourMoney 'countData.fixedMoney = 1 '时间递增单位 countData.addTime = bBaseData.AddTime 'countData.addTime = 5 '最少上机时间 countData.leastTime = bBaseData.LeastTime 'countData.leastTime = 30 '上机最少金额 countData.LeastMoney = bBaseData.LeastMoney 'countData.LeastMoney = 1 Return countData End Function ''' <summary> ''' 选择算法、 ''' </summary> ''' <returns></returns> ''' <remarks></remarks> Function IFCount(coutData As countData) As CashContext Dim fCashContext As New CashContext '定义策略 Select Case (coutData.str) Case "固定用户" fCashContext.CashContext(New LongTermUser()) Case "临时用户" fCashContext.CashContext(New TemporaryUser()) Case Else MsgBox("未找到相应算法策略") End Select Return fCashContext End Function ''' <summary> ''' 方便调用(复制代码的话请把传入值改了) ''' </summary> ''' <param name="bname"></param> ''' <param name="bComputerRecords"></param> ''' <param name="bBaseData"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function CountMoney(bname As String, bComputerRecords As Entity.EComputerRecords, bBaseData As Entity.EBaseData) As Integer Dim countdata As New countData '储存数据 Dim fCashContext As New CashContext '储存策略 countdata = AddData(bname, bComputerRecords, bBaseData) '获取数据(复制代码的话请把传入值改了) fCashContext = IFCount(countdata) '获取策略 Return fCashContext.countMoney(countdata) '计算法返回结果 End Function End Class ''' <summary> ''' 策略模式类 ''' </summary> ''' <remarks></remarks> Public Class CashContext Private insideCashAlgorithm As CashAlgorithm '声明一个算法抽象类 ''' <summary> ''' 构造方法、接受外部传入的算法类(这里声明抽象算法类、使用他的子类、也就是策略) ''' </summary> ''' <param name="outSideCashAlgorithm"></param> ''' <remarks></remarks> Public Sub CashContext(outSideCashAlgorithm As CashAlgorithm) insideCashAlgorithm = outSideCashAlgorithm End Sub ''' <summary> ''' 使用接受算法的方法、计算出money返值 ''' </summary> ''' <returns></returns> ''' <remarks></remarks> Public Function countMoney(coutData As countData) As Integer Return insideCashAlgorithm.countMoney(coutData) End Function End Class ''' <summary> ''' 算法抽象列(CashAlgorithm现金算法) ''' </summary> ''' <remarks></remarks> Public MustInherit Class CashAlgorithm ''' <summary> ''' 算现金的抽象方法 ''' </summary> ''' <returns></returns> ''' <remarks></remarks> Public Overridable Function countMoney(coutData As countData) As Integer Dim money As Integer Return money End Function '必须被重写 'Public Overrides Sub Move(ByVal NewX As Integer, ByVal NewY As Integer) ' '... 'End Sub 'Public Property XPos() As Integer ' '... 'End Property End Class ''' <summary> ''' 算法1 固定用户 ''' </summary> ''' <remarks></remarks> Public Class LongTermUser '继承抽象类 Inherits CashAlgorithm ''' <summary> ''' 正常工资的算法 ''' </summary> ''' <returns></returns> ''' <remarks></remarks> Public Overrides Function countMoney(coutData As countData) As Integer Dim money As Integer '定义存放钱的变量 '--1--判定上机时间是否大于准备时间、小于则不收钱 If coutData.consumeTime < coutData.readyTime Then money = 0 Return money Exit Function Else coutData.consumeTime = coutData.consumeTime - coutData.readyTime End If '--2--减去没有到达递增时间的时间(只取整) coutData.consumeTime = Fix(coutData.consumeTime / coutData.addTime) * coutData.addTime '---3---是否大于最小上机时间 If coutData.consumeTime < coutData.leastTime Then coutData.consumeTime = coutData.leastTime End If '----4----算钱、有几个半小时、多出半小时的按一个半小时算 If coutData.consumeTime / 30 > Fix(coutData.consumeTime / 30) Then money = coutData.fixedMoney * (Fix(coutData.consumeTime / 30) + 1) Else money = coutData.fixedMoney * (coutData.consumeTime / 30) End If '---5-----是否大于上机最小金额 If money < coutData.LeastMoney Then money = coutData.LeastMoney End If Return money '返回计算结果 End Function End Class ''' <summary> ''' 算法2 临时用户 ''' </summary> ''' <remarks></remarks> Public Class TemporaryUser '继承抽象类 Inherits CashAlgorithm ''' <summary> ''' 节假日工资的算法 ''' </summary> ''' <returns></returns> ''' <remarks></remarks> Public Overrides Function countMoney(coutData As countData) As Integer Dim money As Integer '定义存放钱的变量 money = 2 '这里是正常工资的2倍 Return money '返回计算结果 End Function End Class ''' <summary> ''' 计算下机、简单工厂与策略模式传值用 ''' </summary> ''' <remarks></remarks> Public Class countData '工厂选择字段 Dim str_ As String '消费时间 Dim ConsumeTime_ As New Integer '准备时间 Dim ReadyTime_ As New Integer '固定用户半小时费用 Dim FixedMoney_ As New Integer '时间递增单位 Dim AddTime_ As New Integer '最少上机时间 Dim LeastTime_ As New Integer '上机最少金额 Dim LeastMoney_ As New Integer ''' <summary> ''' 传入工厂选择的字符串 ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public Property str() As String Get Return str_ End Get Set(ByVal value As String) str_ = value End Set End Property ''' <summary> ''' 消费时间 ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public Property consumeTime() As Integer Get Return ConsumeTime_ End Get Set(ByVal value As Integer) ConsumeTime_ = value End Set End Property ''' <summary> ''' 准备时间 ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public Property readyTime() As Integer Get Return ReadyTime_ End Get Set(ByVal value As Integer) ReadyTime_ = value End Set End Property ''' <summary> ''' 固定用户半小时费用 ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public Property fixedMoney() As Integer Get Return FixedMoney_ End Get Set(ByVal value As Integer) FixedMoney_ = value End Set End Property ''' <summary> ''' 时间递增单位 ''' </summary> ''' <remarks></remarks> Public Property addTime() As Integer Get Return AddTime_ End Get Set(ByVal value As Integer) AddTime_ = value End Set End Property ''' <summary> ''' 最少上机时间 ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public Property leastTime() As Integer Get Return LeastTime_ End Get Set(ByVal value As Integer) LeastTime_ = value End Set End Property ''' <summary> ''' 上机最少金额 ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public Property LeastMoney() As Integer Get Return LeastMoney_ End Get Set(ByVal value As Integer) LeastMoney_ = value End Set End Property End Class
现在临时用户的计算还没写、你可以试着写下、张嘴
啊……嗯……章鱼烧~
怎么样、还是烤章鱼丸好吃吧、海鲜就是好吃、我这个酒蒸蛤蜊也是海鲜啊!又鲜又美味
哎!……富兰克林、不对啊、你不也是海鲜嘛
切、那你和章鱼烧、酒蒸蛤蜊还都是生物呢、我可是有手有脚、有脑袋的高级生物好不!
哈哈哈…………店长和肉白卡一起笑了
章鱼烧
酒蒸蛤蜊
深夜凌晨6点、肉白卡和醉醺醺的富兰克林都回了家、每天深夜、12点到7点、深夜食堂、虽然菜单上只有一道菜、但是只要老板会做、及时菜单上没有、也可以点、大家都吃着自己喜欢的食物、深夜、都讲述着自己的故事。
总结:
这次送大家两道菜哈、最近越学设计模式、越感觉、做例子不等于实现了、能想通不代表能做通、只有不断的实践、实践、实践、才能越深入的了解和学习。
记得刚上小学三年级、那时候刚学英语、学完了ABC、英语老师说我们刚刚英语入门、上了初中、还是学ABC加音标、初中老师说我们英语刚刚入门、到了TGB、学英语……我了个去、这次连门都进不去了、由此看来设计模式我还没入门……蹲墙角画圈ING
_____________________大家在编程的同时也不要忘了、我们是吃货_____________________
—————————————chenchen—————————————
简单工厂+策略模式-下