简单工厂+策略模式-下

前言:

虽然做了个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—————————————

简单工厂+策略模式-下

时间: 2024-10-05 10:16:54

简单工厂+策略模式-下的相关文章

简单工厂+策略模式-上

http://www.biquge.cc/html/156/156282/22734698.html http://www.biquge.cc/html/156/156282/22734700.html http://www.biquge.cc/html/156/156282/22734702.html http://www.biquge.cc/html/156/156282/22734704.html http://www.biquge.cc/html/156/156282/22734706.

代码重构:用工厂+策略模式优化过多的if else代码块

最近在工作中优化了一段冗余的if else代码块,感觉对设计模式的理解和运用很有帮助,所以分享出来.鉴于原代码会涉及到公司的隐私,因此就不贴出来了.下面以更加通俗易懂的案例来解析. 假如写一个针对员工上班不遵守制度做相应惩罚的程序,比如,上班迟到:罚100:上班睡觉:罚1000:上班早退:警告:上班玩游戏:严重警告:上班谈恋爱:开除等,通常都会这样写: public class WorkPunish { public static void main(String[] agrs){ String

Java设计模式从精通到入门四 简单工厂方法模式

简单工厂方法模式 属于23中设计模式中创建型类型. 核心思想:工厂提供创建对象的接口,由子类决定实例化哪一个子类. 来源 ? 设计模式之禅中的例子,女娲造人,通过八卦炉来进行造人,没有烧熟的为白人,烧太熟的为黑人,刚好的为黄种人的例子进行程序展示 女娲作为client,八卦炉为工厂类,人类为具体实现类,有皮肤的区别. UML类图 图一 Factory: 工厂类的接口,根据类类型,提供只能创建Human子类,或者子孙类的方法. HumanFactory: 工厂类的具体实现,通过反射获取该对象. H

spring boot 工厂+策略模式实现APP版本控制

目前我们在用的技术方案是策略模式,在APP发包的时候,每次都是需要在当前版本迭代往上加,然而每次发包的内容并非覆盖所有功能的,有些功能是复用兼容旧版本. 因此是从class的name+版本好进行判断处理业务逻辑.比如8.0的版本是初版,那么8.0.1++往上叠加,若判断该版本是有新的功能迭代,那么就直接引用新版本的功能,若无,则向下兼容旧版本,比如我的版本出到了8.0.2,8.0.2是不需要加功能的,那么8.0.1已经出了一个版本迭代功能,比8.0.0的版本高,那么是优先拿8.0.1的功能的.

设计模式--简单工厂(Factory)模式

温故而知新,看了以前写的博文<Asp.net读取Excel文件 2>http://www.cnblogs.com/insus/archive/2011/05/05/2037808.html 觉得第一段代码示例,可以使用设计模式的简单工厂来实现. 也就是说,使用两个全新的类,替代两个Switch分支. Xls类: Xlsx类: 经这样分离之后,Switch代码,就可以写成下面这样子: 上面的高亮的方法是相同的,两个类的方法相同,我们可以抽取至父类作为父类的public的方法,但是Insus.NE

“模”法无边—策略模式+简单工厂实现下机收费

下机收费是一种算法,临时用户和学生下机下机就是两种算法,让我想到了使用策略模式,根据是否为临时用户和学生,选择具体的算法,这属于简单工厂,好的,简单工厂+策略模式实现下机收费 策略类-封装具体的策略   '封装具体的算法,需要引用一个算法 Public Class consumeContext     Dim strategyconsume As Consume       Sub New(ByRef strategy As Consume)         Me.strategyconsume

[设计模式] 策略模式(Strategy)

reference to : http://www.cnblogs.com/spring5/archive/2011/10/20/2485291.html 一.概要我们构建程序的时候,会遇到这样的状况,对象有某个行为,但是在不同的场景中,使用策略模式,可以把它们一个个封装起来,并且使它们可相互替换,而起使得算法可独立于使用它的客户而变化. 二.生活举例对于一个商店来讲,对不同的客户要报不同的价格,比如:(1)对普通客户或者是新客户报的是全价(2)对老客户(会员)报的价格,要给予一定的折扣(3)对

策略模式(Strategy )

为实现一个目的采用不同的方式都可实现,具体看要采取哪种方式. //接口 public interface Strategy {    public void algorithmInterface(); } public class  ConcreStrategyA implments Strategy {    public void  algorithmInterface() { System.out.println("策略A开始执行"); } } public class  Con

简单工厂、工厂方法、抽象工厂、策略模式、策略与工厂的区别

结合简单示例和UML图,讲解工厂模式简单原理. 一.引子 话说十年前,有一个爆发户,他家有三辆汽车(Benz(奔驰).Bmw(宝马).Audi(奥迪)),还雇了司机为他开车.不过,爆发户坐车时总是这样:上Benz车后跟司机说"开奔驰车!",坐上Bmw后他说"开宝马车!",坐上 Audi后他说"开奥迪车!".你一定说:这人有病!直接说开车不就行了?!而当把这个爆发户的行为放到我们程序语言中来,我们发现C语言一直是通过这种方式来坐车的!幸运的是这种有