设计模式之策略模式&简单工厂模式
学习设计模式已经有非常长一段时间了,事实上先前已经敲过一遍了。可是老认为没有学到什么,认识也不够深刻。如今趁着重构机房,再又一次来过,也不晚。
事实上在敲了机房之后,看看模式,事实上,曾经非常难理解。非常难看懂的代码一眼就能够看懂了,趁着有点感觉了。早点收获吧。
简单工厂模式:
简单地说简单工厂模式:非常easy变化的地方,就能够用到简单工厂模式。
实例:
举个样例:我们在逛商场时。正好商场促销,各种优惠活动:有满300返100 ,有打8折的、抽奖等等吧。
促销来讲,各种优惠活动事实上就是变化。
再举个样例:我们在买早餐的时候。早餐店里琳琅满目,但不管是谁来这家商店买都系,营业员问你须要什么,他就知道给你拿什么东西。我们须要的东西就是变化。
浅谈:
简单工厂模式就是通过传入的数据返回几种可能类宏的一种类的实例。但这几种类通常会有一个共同特点就是:这几种类有一个共同的父类和共同的方法。但每一个方法被容不同。并且依据不同的数据进行优化。
深入:
上述是浅谈,实质:面对这些变化,面向对象的思想就是封装这些变化。封装变化之后,则可添加它的可扩展性,不会再改动曾经的类了。
简单工厂模式结构图:
实现商场促销:
父类:
- <span style="background-color: rgb(204, 204, 204);"><strong> abstract class CashSuper//父类。一个抽象还是,封装
- {
- public abstract double acceptCash(double money);
- }</strong></span>
各个子类:
- 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");
- break;
- case"打8折":
- CashRebate cr2 = new CashRebate("0.8");
- break;
- }
- return cs;
- }
- }
界面层:
- private void button1_Click(object sender, EventArgs e)
- {
- //简单工厂模式-------------------------------------------------------------------
- CashSuper csuper = CashFactory.createCashAccept(cbxType.SelectedItem.ToString());//简单工厂模式的写法,client认识两个类,CashSuper和CashFactory。再简单工厂模式中就已经实例出了各个子类对象
- 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());
- label4.Text = total.ToString();
- }
我们都知道,商店不是一直都有促销的。也不一定今年这这样的促销。明年还是这样的,事物都是在随着时间变化的。假设每次更改打折额度和返利额度,每次都要维护或扩展收费方式,都要修改工厂。一直代码徐又一次编译部署。这要就非常糟糕了,面对算法的市场变动。就须要策略模式了。
策略模式:
样例:
商店里促销每年须要更改打折额度和返利额度。
结构图:
闲谈:
事实上策略模式定义了算法家族。分别封装起来。让他们之间能够相互取代,此模式让算法的变化,不会影响到使用算法的客户。全部这些算法完毕的都是同样的工作,仅仅是实现不同,他能够用同样的方法调用全部的算法。降低了算法类和使用算法类之间的耦合。
深入:
简单工厂来生成算法对象,算法是随时都可能互相替换,这就是变化点。封装变化点。
实现商店促销:
前面的父类和个促销子类不须要改动:
策略模式代码:
- class CashContext//用一个CashContext来配置,维护一个对Strategy对象的引用。
- {
- 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);
- }
- }
界面代码:
- private void button1_Click(object sender, EventArgs e)
- {
- //策略模式和简单工厂模式结合----------------------------------------------------
- CashContext csuper = new CashContext(cbxType.SelectedItem.ToString());//client仅仅认识CashContext即可了,纯如详细的策略对象
- double totalprices = 0d;
- totalprices = csuper.GetResult(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));
- total = total + totalprices;
- lbxList.Items.Add("单位价格:" + txtPrice.Text + "数量:" + txtNum.Text + " " + cbxType.SelectedItem + "合计:" + totalprices.ToString());
- label4.Text = total.ToString();
- }
以上就是策略模式和简单工厂模式的结合了,简单工厂模式事实上说简单一点就是:一个类创造实例的过程。策略模式:策略随时有可能互相替换。
设计模式之策略模式&简单工厂模式的更多相关文章
- C++设计模式 ==> 策略模式与简单工厂模式结合
简介 策略模式相较之于简单工厂模式适用于生产方法经常变化且方法较为繁多的情况,因为生产方法时常变化就会需要频繁修改工厂类,违背了开闭原则,这时就可以用策略选择类由客户端根据需求动态切换策略.且策略模式 ...
- Java 设计模式系列(二)简单工厂模式和工厂方法模式
Java 设计模式系列(二)简单工厂模式和工厂方法模式 实现了创建者和调用者的分离.分为:简单工厂模式.工厂方法模式.抽象工厂模式 简单工厂模式.工厂方法模式都很简单,就不详细介绍了. 一.简单工厂 ...
- 设计模式(Java语言)- 简单工厂模式
简单工厂模式有称为静态工厂模式,属于设计模式中的创建型模式.简单工厂模式通过对外提供一个静态方法来统一为类创建实例.简单工厂模式的目的是实现类与类之间解耦,其次是客户端不需要知道这个对象是如何被穿创建 ...
- Java设计模式之(工厂模式)--简单工厂模式--工厂方法模式--抽象工厂模式
工厂模式: 工厂模式可以分为三类: 1)简单工厂模式(Simple Factory) 2)工厂方法模式(Factory Method) 3)抽象工厂模式(Abstract Factory) 简单工厂模 ...
- 学习设计模式第二十七 - GoF之外简单工厂模式
示例代码来自<深入浅出设计模式>和<大话设计模式> 概述 简单工厂模式又被称为静态工厂模式,属于类的创建型模式.其实质是由一个工厂类根据传入的参量,动态决定应该创建出哪一个产品 ...
- 设计模式(Java版)-创建型模式之简单工厂模式
前言:这段时间在学习设计模式,本人也是小菜一枚(所以写的如果有错误的地方请大大们给予指出).这个东西也是我一直想学习的,从点点滴滴做起,记录下自己每天的领悟! 一.工厂模式的动机 在软件系统中,经常面 ...
- [Python设计模式] 第1章 计算器——简单工厂模式
github地址:https://github.com/cheesezh/python_design_patterns 写在前面的话 """ 读书的时候上过<设计模 ...
- Javascript设计模式理论与实战:简单工厂模式
通常我们创建对象最常规的方法就是使用new关键字调用构造函数,这会导致对象之间的依赖性.工厂模式是一种有助于消除类之间依赖性的设计模式,它使用一个方法来决定要实例化哪一个类.本文详细介绍了简单工厂模式 ...
- Java设计模式(1)——创建型模式之简单工厂模式(Simple Factory)
设计模式系列参考: http://www.cnblogs.com/Coda/p/4279688.html 一.概述 工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高 ...
随机推荐
- Apache Rewrite规则详解
参考链接:http://slj.me/2009/04/apache-rewrite-regular/ 1.Rewrite规则简介 Rewirte主要的功能就是实现URL的跳转,它的正则表达式是基于Pe ...
- ZH奶酪:Python按行读取文件
1:readline() file = open("sample.txt") while 1: line = file.readline() if not line: break ...
- 通过wlst工具创建weblogic11g域单节点包括服务与被管服务
1:创建域(1)节点一执行 export MV_HOME=/home/wzh/Oracle/Middleware export WL_HOME=$MV_HOME/wlserver_10. export ...
- Jlink烧写出错 : Unable to halt arm core
环境:TQ2440开发板,J-link 通过J-link向TQ2440开发板的Nor Flash烧写程序,执行烧写时出错:Unable to halt arm core-详情如下图所示: 解决办法: ...
- PYQT操作JS并且截图事例
如何安装PYQT,可以查看我的上一篇文章:http://www.cnblogs.com/liqiu/p/3361948.html 然后运行下面的带有JS程序的Python脚本即可: #-*- codi ...
- gdb 小技巧
https://www.gitbook.com/book/wizardforcel/100-gdb-tips/details
- infobright系列二:数据迁移
安装之后把之前infobright的数据迁移到新安装的infobright上. 1:挺掉相关的服务 2:scp 把旧数据拷到新安装的infobright上 3:修改/etc/my-ib.cnf的数据目 ...
- vue key
有相同父元素的子元素必须有独特的 key.重复的 key 会造成渲染错误. <ul> <li v-for="item in items" :key="i ...
- Eclipse项目修改没有同步到编译的问题
有两个原因: 1:项目有错,不能正常编译:查看是否有Jar包冲突.JDK版本问题等: 2:编译输出目录配置错误: Maven项目会修改项目编译时的输出路径到target文件夹,但是我们用Myelips ...
- Java线程池的使用以及原理
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6543909.html 一:线程池简介 在使用多线程来提高处理器利用率的同时,由于线程的不断创建和销毁所造成的 ...