简单工厂模式 :
记得最开始学编程的时候用C#写过一个计算器,当时完全是用面向过程的思想来写的计算器,代码又臭又长,后来知道面向对象了,知道用一点面向对象的知识来写一个业务逻辑层与表示层分离的计算器了,代码如下:
public class Operation{
public static double GetResult(double numberA,double numberB,string operate){
double result = 0.0;
switch(Operate){
case "+":
result = numberA + numberB;
break;
case "-":
result = numberA - numberB;
break;
case "*":
result = numberA * numberB;
break;
case "/":
result = numberA / numberB;
break;
}
return result;
}
}
//客户端代码略
上面这段计算器的代码算是实现了业务逻辑与表示的分离,但是还存在许多的问题,如果要加入一个开根号的运算,那么要在GetResult方法中添加一些代码,这样是不合理的,因为如果程序员不小心改动了其它运算的代码,那就有可能会产生bug,增加一个运算不应该影响其他的运算。
而且上面的这段代码也只用上了面向对象的三大特性之一:封装。还可以进行一下改进!
public class Operation{
private double numberA = 0;
private double numberB = 0;
public double NumberA{
get{ return numberA;}
set{ numberA = value;}
}
public double NumberB{
get{ return numberB;}
set{ numberB = value;}
}
public virtual double GetResult(){
double result = 0;
return result;
}
}
//加减乘除类
class OperationAdd:Operation{
public override double GetResult(){
double result = 0;
result = numberA + numberB;
return result;
}
}
......其它类省略
//下面这个类就是工厂类,在工厂类中来决定到底实例化哪个对象
public 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;
}
}
//客户端省略。。。
下面来看看简单工厂模式计算器的类图
工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到类。
说完了简单工厂模式,下面再来说一下工厂方法模式,这两种设计模式有什么不同呢?来看看代码:
//先构建一个工厂接口
interface IFactory{
Operation CreateOperation();
}
//然后加减乘除各建一个具体的工厂去实现这个接口
class AddFactory:IFactory{
public Operation CreateOperation(){
return new OperationAdd();
}
}
class SubFactory:IFactory{
public Operation CreateOperation(){
return new OperationSub();
}
}
//乘除的工厂以及客户端代码省略
还有工厂方法模式计算器的类图
为什么会出现类似于简单工厂模式的工厂方法模式呢?简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了具体产品的依赖。但是如果说要加上一个运算呢?对于简单工厂模式来说,加上一个运算要修改工厂类中的方法,这样的话就违背了开放-封闭原则,开放封闭的原因就是说对于需要扩展的地方,那么是开放的,对于要修改原有代码的地方,是封闭的。简单工厂模式不但对扩展开放了,对修改也开放了,工厂方法模式就不一样,只需要加上一个运算类来实现工厂接口就好了,这样的话就遵循了开放-封闭原则。
抽象工厂模式:提供一个创建一系列相关或者相互依赖对象的接口,而无需制定它们具体的类。
看看上面工厂方法的定义,其实就一点小小的区别,那就是从一个变成了一系列,下面看看抽象工厂模式下计算器的类图:
工厂方法模式下的计算器就只有一个运算类,那么抽象工厂模式下的计算器就可以有一系列的抽象接口,比如上面类图中的,可以有算术型计算器运算类,还有科学型计算器运算类。
//因为要加上科学计算器,那么需要的是两个带抽象方法的类,要将具体的实现抽象出来,一个是科学计算器的运算类,一个是算术型计算器的运算类,还要修改三个类
//科学性计算器的运算类
public class ScentificOperation{
private double numberA = 0;
private double numberB = 0;
public double NumberA{
get{ return numberA;}
set{ numberA = value;}
}
public double NumberB{
get{ return numberB;}
set{ numberB = value;}
}
public virtual double GetResult(){
double result = 0;
return result;
}
}
//算术型计算器的抽象类
public class MathOperation{
private double numberA = 0;
private double numberB = 0;
public double NumberA{
get{ return numberA;}
set{ numberA = value;}
}
public double NumberB{
get{ return numberB;}
set{ numberB = value;}
}
public virtual double GetResult(){
double result = 0;
return result;
}
}
//接下来就可以分别用加减乘除这四个运算类来继承这两个类,此处略
//那么工厂接口以及具体的工厂类也会需要修改
//先构建一个有两个方法的工厂接口
interface IFactory{
Operation CreateScentificOperation();
Operation CreateMathOperation();
}
//然后加减乘除各建一个具体的工厂去实现这个接口
class AddFactory:IFactory{
public Operation CreateScentificOperation(){
return new ScentificOperationAdd();
}
public Operation CreateMathOperation(){
return new MathOperationAdd();
}
}
class SubFactory:IFactory{
public Operation CreateScentificOperation(){
return new ScentificOperationSub();
}
public Operation CreateMathOperation(){
return new MathOperationSub();
}
}
.........其他类省略
由上述抽象工厂的构建可以发现抽象工厂模式的一个缺点,那就是如果要对原有的功能进行扩展的话会很麻烦,要增加几个类,修改几个类。所以我们可以参照简单工厂模式来改进抽象工厂模式!具体的实现在这里就不细说了,自己慢慢体会!哈哈!