查看本人文章索引请通过http://www.cnblogs.com/seesea125/archive/2012/04/17/2453256.html
一、简单工厂和工厂方法定义:
简单工厂模式是由一个工厂类根据参数来决定创立出哪一种产品类的实例。
工厂方法模式通过调用不同的方法返回需要的类,而不是去实例化具体的类。 对实例创建进行了包装。 工厂方法是一组方法, 他们针对不同条件返回不同的类实例,这些类一般有共同的父类。
工厂方法模式实施一种按需分配的策略, 即传入参数进行选择, 工厂方法根据参数进行选择,返回具体的实例。
二、实例讲解:实现加减乘除
程序需求:
处理两个数的+,-,*,/等运算
1. 是面向过程的实现方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
string strResult = "" ; switch (Operate) { case "+" : strResult = Convert.toString(Convert.ToDouble(NumA) + Convert.ToDouble(NumB)); break ; case "-" : strResult = Convert.toString(Convert.ToDouble(NumA) - Convert.ToDouble(NumB)); break ; case "*" : strResult = Convert.toString(Convert.ToDouble(NumA) * Convert.ToDouble(NumB)); break ; case "/" : if (NumB != 0) { strResult = Convert.toString(Convert.ToDouble(NumA) + Convert.ToDouble(NumB)); } else { strResult = "除数不能为0" ; } break ; } |
当增加需求时,例如:增加开方运算,这时我们需要更改上面switch的代码。如果再增加需求,还要更改switch代码。这样的代码很难维护。
健壮的设计应该是易扩展,不修改原有代码(或尽量减少修改原有代码)。
应对变化的运算方式,简单工厂就是一个很简单,好用的模式,下面是简单工厂的实现
2. 用简单工厂实现:
ULM图:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public class Operation { public double NumA { get ; set ; } public double NumB { get ; set ; } public abstract double GetResult(); } public class OperationAdd : Operation { public override double GetResult() { return NumA + NumB; } } public class OperationSub : Operation { public override double GetResult() { return NumA - NumB; } } |
工厂类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class Factory { public Operation Create( string ope) { Operation operation= null ; switch (ope) { case "+" : operation= new OperationAdd(); break ; case "-" : operation= new OperationSub(); break ; } return operation; } } |
客户端调用:
1
2
3
4
5
6
7
8
9
|
Operation oper; oper=Factory.Create(“+”); oper.NumA=1; oper.NumB=2; double result=opern.GetResult(); |
这时在客户端代码就没有switch代码,现在的switch代码也没有运算逻辑。运算逻辑在GetResult()方法中。
当再有新需求时,我就可以增加子类(继承自Operation),在子类的GetResult方法中设置运算规则。现在只需在switch中增加一个case返回增加子类实例的代码。
简单工厂是一个不完美的模式,因为它还是修改了switch代码。
3 用工厂方法实现:
应对上面的需求也可以使用工厂方法模式,工厂方法使一个类的实例化延迟到其子类。
UML图:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public class IFactory { public Operation Create(); } public class AddOperation : IFactory { public override Operation Create() { return new OperationAdd(); } } public class SubOperation : IFactory { public override Operation Create() { return new OperationSub(); } } |
工厂方法应对增加的需求时,增加继承自Operation子类(),和返回相应实例的工厂方法。
客户端:
1
2
3
4
5
6
7
8
9
10
11
|
Operation operation= null switch (ope) { case "+" : operation= new AddOperation().Create(); break ; case "-" : operation= new SubOperation().Create(); break ; } operation.GetResult(); |
在客户端代码中还是需要switch代码调用相应的工厂方法实例。但这是的switch代码和非面向对象代码的区别是:这个switch中不含有任何运算逻辑。只返回实例。
为了改动逻辑增加switch的改动,switch操作可以通过反射来实现。