《大话设计模式》学习笔记——第1章——简单工厂模式
2015-06-22 17:29
363 查看
最近开始学习《大话设计模式》这本书,以每章一篇博客的形式把学习心得记录下来。代码部分使用的均为C#,开发工具是VS2013,我的代码可以在[我的GitHub](https://github.com/12301013-SunHaobo/DesignPatterns下载到
在工厂模式里,我们向工厂类传入不同的参数,他就会返回不同的具体实现。
以书中的计算器程序为例,最简单的写法当然是所有代码放一起,不使用任何设计模式,读两个数字和一个运算符,在switch语句里根据不同的运算符对两个数字进行不同的操作,最后输出结果。
作为一个小黑框程序这样写就够了,但如果考虑一下程序的可复用性呢?比如如果要写一个有界面的计算器呢?在读这本书以前,我的做法肯定是把控制台的代码粘过去,然后把获取数字和运算符的方法从控制台读取修改成从界面获取,最后的输出改成调用界面控件显示,这样就完成了。
但有一种明显更好的做法,就是把数据的获取和计算过程分离,把计算的过程封装成一个函数,接受两个数字和一个运算符作为参数并返回计算结果,然后对这个函数进行调用。那么这个函数就是可复用的。小黑框能用,界面程序也能用,甚至网页应用、手机应用也能直接拿去用。
现在我们的计算器完成了,但如果要增加计算器的功能呢?比如要增加一个开平方的运算,怎么办。其实很简单啊,只要在计算函数的switch里增加一个分支就行了。这样做的后果就是,要增加一个功能,就必须**修改原有的代码**,而最好的情况是我们希望在给程序增加功能的时候,只需要增加实现新功能的代码,而不需要修改原有的部分。
该怎么做呢?工厂模式闪亮登场。
先来一个抽象类,成员变量有两个,数字A和数字B
public class Operation
{
private double _numberB = 0;
private double _numberA = 0;
public double NumberA
{
get { return _numberA; }
set { _numberA = value; }
}
public double NumberB
{
get { return _numberB; }
set { _numberB = value; }
}
public virtual double GetResult()
{
return 0;
}
}
加法运算类的具体实现,继承了运算抽象类,重写GetResult方法:
class OperationAdd:Operation
{
public override double GetResult()
{
return NumberA + NumberB;
}
}
其他三种基本运算的实现类跟加法类似,不再赘述。
关键的工厂类:
public class OperationFactory
{
public static Operation createOperation(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;
default:
throw new Exception("不支持的运算");
}
return oper;
}
}
主函数的代码:
static void Main(string[] args)
{
Console.WriteLine("计算A+-*/B");
Console.Write("输入数字A:");
string strNumberA = Console.ReadLine();
Console.Write("输入运算符:");
string strOperate = Console.ReadLine();
Console.Write("输入数字B:");
string strNumberB = Console.ReadLine();
Operation oper = OperationFactory.createOperation(strOperate);
oper.NumberA = Convert.ToDouble(strNumberA);
oper.NumberB = Convert.ToDouble(strNumberB);
Console.WriteLine(oper.GetResult());
Console.ReadLine();
}
哈哈,工厂模式的计算器完成了。对这个计算器增加新运算时,就只要新增一个继承自抽象类的心运算类,并在其中重新GetResult方法就好了。
可是,还是要修改工厂类啊?
是这样的,但是不用修改已经实现好的其他运算类。
第1章——简单工程模式
工厂是什么?就是批量生产东西的地方。在工厂模式里,我们向工厂类传入不同的参数,他就会返回不同的具体实现。
以书中的计算器程序为例,最简单的写法当然是所有代码放一起,不使用任何设计模式,读两个数字和一个运算符,在switch语句里根据不同的运算符对两个数字进行不同的操作,最后输出结果。
作为一个小黑框程序这样写就够了,但如果考虑一下程序的可复用性呢?比如如果要写一个有界面的计算器呢?在读这本书以前,我的做法肯定是把控制台的代码粘过去,然后把获取数字和运算符的方法从控制台读取修改成从界面获取,最后的输出改成调用界面控件显示,这样就完成了。
但有一种明显更好的做法,就是把数据的获取和计算过程分离,把计算的过程封装成一个函数,接受两个数字和一个运算符作为参数并返回计算结果,然后对这个函数进行调用。那么这个函数就是可复用的。小黑框能用,界面程序也能用,甚至网页应用、手机应用也能直接拿去用。
现在我们的计算器完成了,但如果要增加计算器的功能呢?比如要增加一个开平方的运算,怎么办。其实很简单啊,只要在计算函数的switch里增加一个分支就行了。这样做的后果就是,要增加一个功能,就必须**修改原有的代码**,而最好的情况是我们希望在给程序增加功能的时候,只需要增加实现新功能的代码,而不需要修改原有的部分。
该怎么做呢?工厂模式闪亮登场。
先来一个抽象类,成员变量有两个,数字A和数字B
public class Operation
{
private double _numberB = 0;
private double _numberA = 0;
public double NumberA
{
get { return _numberA; }
set { _numberA = value; }
}
public double NumberB
{
get { return _numberB; }
set { _numberB = value; }
}
public virtual double GetResult()
{
return 0;
}
}
加法运算类的具体实现,继承了运算抽象类,重写GetResult方法:
class OperationAdd:Operation
{
public override double GetResult()
{
return NumberA + NumberB;
}
}
其他三种基本运算的实现类跟加法类似,不再赘述。
关键的工厂类:
public class OperationFactory
{
public static Operation createOperation(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;
default:
throw new Exception("不支持的运算");
}
return oper;
}
}
主函数的代码:
static void Main(string[] args)
{
Console.WriteLine("计算A+-*/B");
Console.Write("输入数字A:");
string strNumberA = Console.ReadLine();
Console.Write("输入运算符:");
string strOperate = Console.ReadLine();
Console.Write("输入数字B:");
string strNumberB = Console.ReadLine();
Operation oper = OperationFactory.createOperation(strOperate);
oper.NumberA = Convert.ToDouble(strNumberA);
oper.NumberB = Convert.ToDouble(strNumberB);
Console.WriteLine(oper.GetResult());
Console.ReadLine();
}
哈哈,工厂模式的计算器完成了。对这个计算器增加新运算时,就只要新增一个继承自抽象类的心运算类,并在其中重新GetResult方法就好了。
可是,还是要修改工厂类啊?
是这样的,但是不用修改已经实现好的其他运算类。
相关文章推荐
- 25.根据公式计算值
- 换主页轮播的主题图片(1)---轻开电子商务系统(企业入门级B2C网站)
- linux常用命令
- [采矿]POJ List & 题解
- 黑马程序员--Java学习日记之面向对象(多态和匿名内部类)
- 第三篇 学习OpenCV之图像变换(1)
- android(EditText)属性详解
- C语言回顾(七、多重指针,argc,argv,动态内存分配,void指针,const)——iOS开发基础
- 第三篇 学习OpenCV之图像变换(1)
- mysql 触发器学习
- 【转】TCP协议的无消息边界问题
- phalcon在ubuntu上的安装问题
- C实现 LeetCode->Linked List Cycle 双指针大法)(单链表是否有环)
- python unicode转str方法
- 基于稀疏表示的人脸识别 (SRC,LASRC,RASL,MRR)
- 电平转换方法
- 黑马程序员--网络编程
- 如何判断一个数是不是完全平方数
- angularjs实战项目01-构建开发环境
- 塔勒布《反脆弱》-读后感