在博客文章中,我们提到的简单工厂模式。然而,GoF摘要23设计模式,而不是她的影子,严厉格感,简单工厂模式是不是一种设计模式,合设计模式的开放—封闭原则,即软件实体如类、模块等应该能够扩展,可是不可改动。对于设计模式的设计原则,将在下一篇博文中介绍。这里我们先来看一个样例:

周所周知,超市收银系统都具有计费功能,那么要你做一个可以依据输入的商品单位价格和数量,以及计费方式进行计算的模块,你怎样做?计费方式也就是打不打折,有没有返利优惠等等。那么我们先用简单工厂模式去实现一下。

简单工厂实现

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace 商场收银软件
{public partial class Form1 : Form{public Form1(){InitializeComponent();}double total = 0.0d;private void textBox1_TextChanged(object sender, EventArgs e){}private void label5_Click(object sender, EventArgs e){}private void Form1_Load(object sender, EventArgs e){cbxType.Items.AddRange(new object[] { "正常收费", "满300返100", "打8折" });cbxType .SelectedIndex =0;}private void buttonOK_Click(object sender, EventArgs e){CashSuper csuper = CashFactory.createCashAccept(cbxType.SelectedItem.ToString());double totalPrices = 0d;totalPrices = csuper.acceptCash(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));total = total + totalPrices;lbxList.Items.Add("单位价格:" + txtPrice.Text + "数量:" + txtNum.Text +"计费方式:"+ cbxType.SelectedItem + "合计:" + totalPrices.ToString());lblResult.Text = total.ToString();}private void button2_Click(object sender, EventArgs e){txtNum.Text = "";txtPrice.Text = "";lbxList.Items.Clear();lblResult.Text = "0.00";}}//现金收费抽象类abstract class CashSuper{public abstract double acceptCash(double money);}//正常收费子类class CashNormal : CashSuper{public override double acceptCash(double money){return money;}}//打折收费子类class CashRebate : CashSuper{private double moneyRebate = 1d;public CashRebate(string moneyRebate){this.moneyRebate = double.Parse(moneyRebate);}public override double acceptCash(double money){return money * moneyRebate;}}//返利收费子类class CashReturn : CashSuper{private double moneyCondition = 0.0d;private double moneyReturn = 0.0d;public CashReturn(string moneyCondition, string moneyReturn){this.moneyCondition = double.Parse(moneyCondition);this.moneyReturn = double.Parse(moneyReturn);}public override double acceptCash(double money){double result = money;if (money >= moneyCondition)result = money - Math.Floor(money / moneyCondition) * moneyReturn;return result;}}//现金收费工厂类class CashFactory{public static CashSuper createCashAccept(string type){CashSuper cs = null;switch (type){case "正常收费":cs = new CashNormal();break;case "满300返100":CashReturn cr1 = new CashReturn("300", "100");cs = cr1;break;case "打8折":CashRebate cr2 = new CashRebate("0.8");cs = cr2;break;}return cs;}}
}

我们看到,这样的方案的特点就是将计费方式的实例化放到了工厂里。从而在须要加入新的计费方式的时候,仅仅需在工厂里加一下条件。完了再设计一个对应的类就可以。

可是这样做相同也破坏了开放—封闭原则,每一次的扩展都要大动干戈,实在是不好,不好。面对算法的时常变动。怎样应对?以下我们用还有一种方式试试:

策略模式实现

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace 商场收银软件
{public partial class Form1 : Form{public Form1(){InitializeComponent();}double total = 0.0d;private void textBox1_TextChanged(object sender, EventArgs e){}private void label5_Click(object sender, EventArgs e){}private void Form1_Load(object sender, EventArgs e){cbxType.Items.AddRange(new object[] { "正常收费", "满300返100", "打8折" });cbxType .SelectedIndex =0;}private void buttonOK_Click(object sender, EventArgs e){//简单工厂模式的client代码//CashSuper csuper = CashFactory.createCashAccept(cbxType.SelectedItem.ToString());//double totalPrices = 0d;//totalPrices = csuper.acceptCash(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));//total = total + totalPrices;//lbxList.Items.Add("单位价格:" + txtPrice.Text + "数量:" + txtNum.Text +"计费方式:"+ cbxType.SelectedItem + "合计:" + totalPrices.ToString());//lblResult.Text = total.ToString();//策略模式的client代码CashContext cc = null;switch (cbxType.SelectedItem.ToString()){case "正常收费":cc = new CashContext(new CashNormal());break;case "满300返100":cc = new CashContext(new CashReturn("300", "100"));break;case "打8折":cc = new CashContext(new CashRebate("0.8"));break;}double totalPrices = 0d;totalPrices = cc.GetResult(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));total = total + totalPrices;lbxList.Items.Add("单位价格:" + txtPrice.Text + "数量:" + txtNum.Text + "计费方式:" + cbxType.SelectedItem + "合计:" + totalPrices.ToString());lblResult.Text = total.ToString();}private void button2_Click(object sender, EventArgs e){txtNum.Text = "";txtPrice.Text = "";lbxList.Items.Clear();lblResult.Text = "0.00";}}//现金收费抽象类abstract class CashSuper{public abstract double acceptCash(double money);}//正常收费子类class CashNormal : CashSuper{public override double acceptCash(double money){return money;}}//打折收费子类class CashRebate : CashSuper{private double moneyRebate = 1d;public CashRebate(string moneyRebate){this.moneyRebate = double.Parse(moneyRebate);}public override double acceptCash(double money){return money * moneyRebate;}}//返利收费子类class CashReturn : CashSuper{private double moneyCondition = 0.0d;private double moneyReturn = 0.0d;public CashReturn(string moneyCondition, string moneyReturn){this.moneyCondition = double.Parse(moneyCondition);this.moneyReturn = double.Parse(moneyReturn);}public override double acceptCash(double money){double result = money;if (money >= moneyCondition)result = money - Math.Floor(money / moneyCondition) * moneyReturn;return result;}}//现金收费工厂类//class CashFactory//{//    public static CashSuper createCashAccept(string type)//    {//        CashSuper cs = null;//        switch (type)//        {//            case "正常收费"://                cs = new CashNormal();//                break;//            case "满300返100"://                CashReturn cr1 = new CashReturn("300", "100");//                cs = cr1;//                break;//            case "打8折"://                CashRebate cr2 = new CashRebate("0.8");//                cs = cr2;//                break;//        }//        return cs;//    }//}//CashContext类class CashContext{private CashSuper cs;public CashContext(CashSuper csuper){this.cs = csuper;}public double GetResult(double money){return cs.acceptCash(money);}}
}

对照两个方案,我们能够看到不同之处就是策略模式将工厂类撤了。取而代之的是CashContext类,然而又将实现哪一个算法的推断交给了client,这样client承担的责任又大了,不好。不好……

怎么办?要不将简单工厂和策略模式混搭?试试看。对于他们的结合。仅仅需将CashContext类改造一下就可以,例如以下:

 //改造后的CashContext类class CashContext{CashSuper cs = null ;public CashContext(string type){switch (type){case "正常收费":CashNormal cs0 = new CashNormal();cs = cs0;break;case "满300返100":CashReturn cr1 = new CashReturn("300", "100");cs = cr1;break;case "打8折":CashRebate cr2 = new CashRebate("0.8");cs = cr2;break;}}public double GetResult(double money){return cs.acceptCash(money);}}

这样一来,client的代码就要简单的多了,简单工厂模式须要让client和两个类CashSuper和CashFactory打交道,而策略模式与简单工厂结合后的使用方法,client就仅仅需和CashContext打交道就可完毕对应的功能,减少了耦合性。

我们再回过头去看策略模式的定义:

策略模式:定义了算法家族,分别封装起来,让它们之间能够相互替代,此模式让算法的变化,不会影响到使用此算法的客户。

版权声明:本文博主原创文章。博客,未经同意不得转载。

转载于:https://www.cnblogs.com/mfrbuaa/p/4912388.html

团“模子”政策模式乱舞相关推荐

  1. 拼团返利模式玩法VS最新拼团的商业模式

    拼团返利模式玩法VS最新拼团的商业模式 背景:因疫情影响,传统行业越来越难做,电商行业却得到了高速发展,传统电商模式玩法早已经过时,传统电商推广获客成本越来越高,所有的企业都在寻找新的突破口,全新拼团 ...

  2. 拼团不中返利模式开发(拼团商城返现系统源码设计)

    从火爆至今的拼多多到如雨后春笋般四处成立的零售批发商城,个体商家小程序.APP等系统,拼团和团购都作为一个商家让利推广的必要手段,传统的拼团和团购大多是商家为了薄利多销,以团购的名义向客户低价销售商品 ...

  3. 中国的三种特色团购创新模式

    团购真正被引爆是因为美国团购网站Groupon的迅速崛起,每天推出一个特定的优惠产品,并且必须在限定的时间内达到足够的人数.这种限量的超低折扣,在短时间内引起很多人的兴趣,使信息能够在短时间内在圈子中 ...

  4. 三种中国特色的团购创新模式

    团购真正被引爆是因为美国团购网站Groupon的迅速崛起,每天推出一个特定的优惠产品,并且必须在限定的时间内达到足够的人数.这种限量的超低折扣,在短时间内引起很多人的兴趣,使信息能够在短时间内在圈子中 ...

  5. 七人拼团系统开发模式,助力企业三个月新增超十万会员!

    现在市场上最不缺的就是好产品,产品在市场上目前已经趋于饱和.要想让自己的产品或企业快速打入市场,最好的办法是结合好的营销模式,让企业快速起步裂变提升销量.现在就有这么一款模式,助力企业在三个月内就新发 ...

  6. 网络团购商业模式如何运作才能成功

    "对于一些新兴的团购网站,由于自身特色与优势不明,未来发展面临的挑战会更多."清科研究中心分析师张亚男表示. 事实上,处于盲目快速增长中的网络团购市场,由于种种问题的不断出现,无论 ...

  7. 幸运拼团系统新模式 功能开发介绍

    幸运拼模式软件开发.幸运拼模式软件开发,幸运拼模式小程序拼团系统开发,幸运拼模式源码开发,幸运拼模式拼团商城系统开发. 一.拼团分类专区 拼团专区共设置多种价格专区供用户选择,包括(100元专区.30 ...

  8. 拼团小程序源码_小程序拼团+团购+分销模式,玩转小程序用户裂变

    我们应该都点过朋友扔过来的拼团.砍价链接,拼团.砍价的模式能达到迅速裂变的效果.现在很多大大小小的商家都已经注册了微信小程序,玩起了社交裂变,提高品牌的曝光度,也为门店销量带来了明显的效果.微信小程序 ...

  9. 我国地方大数据政策的扩散模式与转移特征研究

    我国地方大数据政策的扩散模式与转移特征研究 丁文姚, 张自力, 余国先, 韩毅 西南大学计算机与信息科学学院,重庆 400715 摘要:为揭示我国地方大数据政策的发展趋势与内容关联性,基于政策扩散与政 ...

  10. 团购模式的持久性--看书《九败一胜》

    11年前后团购大战的时候,我觉得团购是个昙花一现的模式,不会持久,后来大片团购网站倒下,证明了我这个看法. 但看了<九败一胜>这本书,觉得当年团购网站纷纷倒台,是团购行业的泡沫破灭,并不是 ...

最新文章

  1. saiku 3.8 二次开发代码整理步骤(20160727更新)
  2. 数据库-优化-数据库系统配置优化-配置文件优化
  3. Linux Software RAID的rebuild速度。
  4. 测试:fiddler使用
  5. linux 如何连接无线网卡,CentOS 7如何连接无线网络
  6. 查看jvm的full gc的频率
  7. 4.0之后的hibernate获取sessionFactory
  8. Sklearn——交叉验证(Cross Validation)
  9. 【推荐】互联网或技术多平台,一文多发小工具!
  10. Java8 - Stream API快速入门
  11. 手把手教你学dsp_大咖问答第13期:如何掌握DSP设计?顾卫钢博士在线为你解答...
  12. win7下ApmServ启动失败问题
  13. npm run dev命令报错解决方式
  14. 通信(服务器客户端的群聊与网络画板)
  15. C#环形缓冲区(队列)完全实现(转)
  16. hBuilder天蓝主题插件
  17. 我与Python的偶遇(第二篇)
  18. jVectorMap中添加九段线和台湾省
  19. 线性代数java包,Jama的常用方法
  20. 各种幻灯片切换效果。soChange

热门文章

  1. uefi能重置系统吗_无惧UEFI, Win10也能玩转一键自动还原
  2. 【OUTLINE】使用Oracle Outline技术暂时锁定SQL的执行计划
  3. Windows Server 2008 多元密码策略之ADSIEDIT篇
  4. Java------String DAte 转化
  5. 2月25日 局域不变特征的目标跟踪,SURF算子,KLT算子
  6. Invisible Perturbations: Physical Adversarial Examples Exploiting the Rolling Shutter Effect 论文解读
  7. 数据-第14课-栈的定义及实现
  8. 【bug】记一个有趣的“bug”
  9. 如何快速的复习学习过的Python
  10. linux-Centos 7下bond与vlan技术的结合[推荐]