大话设计模式(五 体会简单工厂模式的美妙)
(续上篇)
次日,小菜再来找大鸟,问道:“你昨天说计算器这样的小程序还可以用到面向对象三大特性?继承和多态怎么可能用得上,我实在不可理解。”
大鸟:“小菜很有钻研精神吗?好,今天我让你功力加深一级。你先要考虑一下,你昨天写的这个代码,能否做到很灵活的可修改和扩展呢?”
小菜:“我已经把业务和界面分离了呀,这不是很灵活了吗?”
大鸟:“那我问你,现在如果我希望增加一个开根(sqrt)运算,你如何改?”
小菜:“那只需要改Operation类就行了,在switch中加一个分支就行了。”
大鸟:“问题是你要加一个平方根运算,却需要把加减乘除的运算都得来参与编译,如果你一不小心,把加法运算改成了减法,这不是大大的糟糕。打个比方,如果现在公司要求你为公司的薪资管理系统做维护,原来只有技术人员(月薪),市场销售人员(底薪+提成),经理(年薪+股份)三种运算算法,现在要增加兼职工作人员的(时薪)算法,但按照你昨天的程序写法,公司就必须要把包含有的原三种算法的运算类给你,让你修改,你如果心中小算盘一打,‘TMD,公司给我的工资这么低,我真是郁闷,这会有机会了’,于是你除了增加了兼职算法以外,在技术人员(月薪)算法中写了一句
if (员工是小菜)
{salary = salary * 1.1;
}
那就意味着,你的月薪每月都会增加10%(小心被抓去坐牢),本来是让你加一个功能,却使得原有的运行良好的功能代码产生了变化,这个风险太大了。你明白了吗?”
小菜:“哦,你的意思是,我应该把加减乘除等运算分离,修改其中一个不影响另外的几个,增加运算算法也不影响其它代码,是这样吗?”
大鸟:“自己想去吧,如何用继承和多态,你应该有感觉了。”
小菜:“OK,我马上去写。”
/// <summary>/// 运算类/// </summary>class Operation{private double _numberA = 0;private double _numberB = 0;/// <summary>/// 数字A/// </summary>public double NumberA{get{ return _numberA; }set{ _numberA = value;}}/// <summary>/// 数字B/// </summary>public double NumberB{get{ return _numberB; }set{ _numberB = value; }}/// <summary>/// 得到运算结果/// </summary>/// <returns></returns>public virtual double GetResult(){double result = 0; return result;}}
/// <summary>/// 加法类/// </summary>class OperationAdd : Operation{public override double GetResult(){double result = 0; result = NumberA + NumberB;return result;}}/// <summary>/// 减法类/// </summary>class OperationSub : Operation{public override double GetResult(){double result = 0;result = NumberA - NumberB;return result;}}/// <summary>/// 乘法类/// </summary>class OperationMul : Operation{public override double GetResult(){double result = 0;result = NumberA * NumberB;return result;}}/// <summary>/// 除法类/// </summary>class OperationDiv : Operation{public override double GetResult(){double result = 0;if (NumberB==0)throw new Exception("除数不能为0。");result = NumberA / NumberB;return result;}}
小菜:“大鸟哥,我按照你说的方法写出来了一部分,首先是一个运算类,它有两个Number属性,主要用于计算器的前后数,然后有一个虚方法GetResult(),用于得到结果,然后我把加减乘除都写成了运算类的子类,继承它后,重写了GetResult()方法,这样如果要修改任何一个算法,都不需要提供其它算法的代码了。但问题来了,我如何让计算器知道我是希望用哪一个算法呢?”
大鸟:“写得很不错吗,大大超出我的想象了,你现在的问题其实就是如何去实例化对象的问题,哈,今天心情不错,再教你一招‘简单工厂模式’,也就是说,到底要实例化谁,将来会不会增加实例化的对象(比如增加开根运算),这是很容易变化的地方,应该考虑用一个单独的类来做这个创造实例的过程,这就是工厂,来,我们看看这个类如何写。”
/// <summary>/// 运算类工厂/// </summary>class OperationFactory{public static Operation createOperate(string operate){Operation oper = null;switch (operate){case "+":{oper = new OperationAdd();break;}case "-":{oper = new OperationSub();break;}case "*":{oper = new OperationMul();break;}case "/":{oper = new OperationDiv();break;}}return oper;}}
大鸟:“哈,看到吧,这样子,你只需要输入运算符号,工厂就实例化出合适的对象,通过多态,返回父类的方式实现了计算器的结果。”
Operation oper;
oper = OperationFactory.createOperate("+");
oper.NumberA = 1;
oper.NumberB = 2;
double result = oper.GetResult();
大鸟: “哈,界面的实现就是这样的代码,不管你是控制台程序,Windows程序,Web程序,PDA或手机程序,都可以用这段代码来实现计算器的功能,当有一天我们需要更改加法运算,我们只需要改哪里?”
小菜:“改OperationAdd 就可以了。”
大鸟: “那么我们需要增加各种复杂运算,比如平方根,立方根,自然对数,正弦余弦等,如何做?”
小菜:“只要增加相应的运算子类就可以了呀。”
大鸟: “嗯?够了吗?”
小菜:“对了,还需要去修改运算类工厂,在switch中增加分支。”
大鸟: “哈,那才对,那如果要修改界面呢?”
小菜:“那就去改界面呀,关运算什么事呀。”
小菜:“ 回想那天我面试题写的代码,我终于明白我为什么写得不成功了,原来一个小小的计算器也可以写出这么精彩的代码,谢谢大鸟。”
(下为当时面试题时小菜所写代码,见《小菜编程成长记(一)》)
class Program
{static void Main(string[] args){Console.Write("请输入数字A:");string A = Console.ReadLine();Console.Write("请选择运算符号(+、-、*、/):");string B = Console.ReadLine();Console.Write("请输入数字B:");string C = Console.ReadLine();string D = "";if (B == "+")D = Convert.ToString(Convert.ToDouble(A) + Convert.ToDouble(C));if (B == "-")D = Convert.ToString(Convert.ToDouble(A) - Convert.ToDouble(C));if (B == "*")D = Convert.ToString(Convert.ToDouble(A) * Convert.ToDouble(C));if (O == "/")D = Convert.ToString(Convert.ToDouble(A) / Convert.ToDouble(C));Console.WriteLine("结果是:" + D);}
}
大鸟: “吼吼,记住哦,编程是一门技术,更加是一门艺术,不能只满足于写完代码运行结果正确就完事,时常考虑如何让代码更加简炼,更加容易维护,容易扩展和复用,只有这样才可以是真的提高。写出优雅的代码真的是一种很爽的事情。不过学无止境,其实这才是理解面向对象的开始呢。给你出个作业,做一个商场收银软件,营业员根据客户购买商品单价和数量,向客户收费。”
小菜:“就这个?没问题呀。”
(待续)
出处:http://www.cnblogs.com/cj723/archive/2006/09/23/512430.html
大话设计模式(五 体会简单工厂模式的美妙)相关推荐
- 大话设计模式Python实现-简单工厂模式
简单工厂模式(Simple Factory Pattern):是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类. 下面使用简单工厂模式实现一个简单的四则运算 1 #!/us ...
- 23种设计模式 -----Day01:简单工厂模式
目录 前言 1.设计模式(Design pattern)定义 2.为什么要使用设计模式(使用设计模式的意义) 3.设计原则 a.单一职责原则 b.开放封闭原则 c.里氏代换原则 d.迪米特法则 e.依 ...
- 【C#设计模式】4-0. 简单工厂模式【创建型】
[C#设计模式]总目录-共23种 [C#设计模式]简单工厂模式 前言 一.简单工厂模式定义 二.实例 三.进一步研究[违反开闭原则的解决方法] 四.简化简单工厂模式[将抽象产品类和工厂类合并] 五.简 ...
- 设计模式 笔记4 | 简单工厂模式 在源码中的应用 | Calendar 日历 | 源码浅析 | 使用总结 | 建造者模式
文章目录 一.Calendar 日历类 1.1 内部属性 1.2 设置时间属性值 1.3 获取时间属性 1.4 使用 Calander 计算时间 二.Calender 类中的设计模式 2.1 简单工厂 ...
- 从王者荣耀看设计模式(四.简单工厂模式)
从王者荣耀看设计模式(简单工厂模式) 一.简介 游戏开始前,玩家可从英雄池自由挑选将要出战的英雄 二.简单工厂模式 简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫 ...
- 【设计模式】之简单工厂模式详解与应用(一)
开心一刻 [老公:老婆老婆,我刚去买了15块钱水果. 老婆:然后呢? 老公:给了老板100块,那二货找了我95.你说他二不二? 老公:我当时撒腿就跑啊. 老婆:水果呢? 老公:-忘拿了- 开心不,笑了 ...
- 手撕设计模式之「简单工厂模式」(Java描述)
前言 利用简单工厂模式可以实现对象创建和业务逻辑处理的分离,但存在工厂类职责过重,增添新产品违背开闭原则等问题.它不属于GoF 23种设计模式之一,但是它可以作为学习工厂方法模式前的一个很好的引导. ...
- 设计模式----2(简单工厂模式的概念,简单工厂模式的实现,简单工厂模式的优缺点)
简单工厂模式 简单工厂模式的概念 简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式.通过专门定义一个类来负 责创建其他类的实例,被创建的实例通常都具有共同的父类. 具体分类 工厂(Creator ...
- 设计模式(1):简单工厂模式(Simple Factory Pattern)
1. 从一个简单的例子开始 在众多的设计原则中,有一条原则是这么说的:要针对接口编程,不要针对实现编程. 针对接口编程的话,可以使用不同的实现类来创建这个对象.比如需要一个List: List< ...
最新文章
- (int),Int32.Parse() 和 Convert.toInt32() 的区别
- msflexgrid允许大选择_工程中要用多大的电线电缆?一文教你怎么算
- [Jmeter系列]Jmeter源码编译步骤(转)
- 汇编 and or xor not test cmp 条件跳转指令 jcc
- 修改android framework学习
- linux视频教程之vsftp_B
- Spring核心知识点总结
- qcom camera smmu 学习(3)
- “.NET研究”理解.NET程序集的执行过程
- eclipse优化方案
- Linux修改文件编码格式的三种方式
- java库存_java实现超市库存管理系统
- 传说中的考研神校,考研人数究竟有多高?
- cs系统的服务器地址,《反恐精英CS》服务器地址
- 发生系统错误 67,找不到网络名
- 【迁移学习】STL(Stratified Transfer Learning)小结
- 2015三十本好书推荐及理由
- 彩色飘带字体怎么制作?AE教程教给你
- 【Android】蓝牙开发——经典蓝牙:配对与解除配对 实现配对或连接时不弹出配对框
- 2019年上半年 DDOS流量攻击分析以及解决方案
热门文章
- [Linux]搜索文件是否包含指定内容并返回文件名
- Apache ZooKeeper - 使用ZK实现分布式锁(非公平锁/公平锁/共享锁 )
- Spring Boot2.x-11 使用@ControllerAdvice和@ExceptionHandler实现自定义全局异常
- Spring Cloud【Finchley】-07Feign构造多参数GET/POST请求
- Halcon知识:如何画出灰度图像直方图
- 2020-12-28 Matlab自动化控制-Adrc自抗扰控制
- mysql 事物gljbie_图片转成base64格式上传至数据库
- JAVA期末简答题参考
- 织女的红线_JAVA
- 精选30道Java笔试题解答