设计模式培训之三:抽象工厂
查看本人文章索引请通过http://www.cnblogs.com/seesea125/archive/2012/04/17/2453256.html
在工厂方法里讲到了加减乘除的例子,请查阅http://www.cnblogs.com/seesea125/archive/2012/05/02/2478981.html
一、抽象工厂的定义
提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类。
二、实现思路
实现思路:如果说简单工厂与工厂方法是对同一个问题的两种不同的解决方法的话,抽象工厂就是解决一系列这种问题的方法。因为其主要的作用就是生产一系列相互依赖的对象,而不用去关心它们具体的实现。
三、代码实现
为了方便查看工厂方法和抽象工厂的区别,因此还以工厂方法的例子为例,做进一步扩展。
在工厂方法里,工厂方法的核心代码如下:
public interface IFactory { Operation Create(); } public class AddOperation : IFactory { public Operation Create() { return new OperationAdd(); } } public class SubOperation : IFactory { public Operation Create() { return new OperationSub(); } } public abstract 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; } }
假设这个加减运算是中国人的运算方法,美国人加减运算不是这么算的,比如美国人的加法,是NumA + NumB+10,美国人的减法是NumA - NumB-10,呵呵,这只是假设,目的是方便我们看工厂方法和抽象工厂的区别,当然现实中不可能发生。
为了区分,我们把OperationAdd,OperationSub 分别改为ChinaOperationAdd,ChinaOperationSub,同时实现美国人的加法和减法AmericaOperationAdd,AmericaOperationSub,这两个方法也同样继承自Operation,代码如下:
public abstract class Operation { public double NumA { get; set; } public double NumB { get; set; } public abstract double GetResult(); } public class ChinaOperationAdd : Operation { public override double GetResult() { return NumA + NumB; } } public class ChinaOperationSub : Operation { public override double GetResult() { return NumA - NumB; } } public class AmericaOperationAdd : Operation { public override double GetResult() { return NumA + NumB+10; } } public class AmericaOperationSub : Operation { public override double GetResult() { return NumA - NumB-10; } }
接下来我们把AddOperation 和SubOperation 这两个继承自IFactory的类,给改造一下,定义一个新的类ChinaOperationFactroy,这个新类里返回两个操作,分别是AddOperation,SubOperation,代码如下:
public class ChinaOperationFactroy { public Operation AddOperation() { return new ChinaOperationAdd(); } public Operation SubOperation() { return new ChinaOperationSub(); } }
再建一个美国的工厂,也是返回美国的加法和减法的实例,代码如下:
public class AmericaOperationFactroy { public Operation AddOperation() { return new AmericaOperationAdd(); } public Operation SubOperation() { return new AmericaOperationSub(); } }
到现在为止,ChinaOperationFactroy,AmericaOperationFactroy的代码很相似,他们都是返回了AddOperation和SubOperation方法,因此把他们抽象出来,建议一个抽象工厂
public abstract class AbstractFactory { public static AbstractFactory GetInstance() { AbstractFactory instance = new AmericaOperationFactroy(); return instance; } public abstract Operation AddOperation(); public abstract Operation SubOperation(); }
然后让ChinaOperationFactroy和AmericaOperationFactroy继承这个工厂,改进后代码如下
public class ChinaOperationFactroy : AbstractFactory { public override Operation AddOperation() { return new ChinaOperationAdd(); } public override Operation SubOperation() { return new ChinaOperationSub(); } } public class AmericaOperationFactroy : AbstractFactory { public override Operation AddOperation() { return new AmericaOperationAdd(); } public override Operation SubOperation() { return new AmericaOperationSub(); } }
此时抽象工厂已经完成了,客户端调用
AbstractFactory af = AbstractFactory.GetInstance(); Operation oper = af.AddOperation(); oper.NumA = 3; oper.NumB = 2; double result = oper.GetResult(); Response.Write(result);
这个时候如果我们想调用中国的加法和减法,只需要把抽象地方改下,改动一个标红的地方即可,改动后,加法和减法运算都变成中国的了
public abstract class AbstractFactory { public static AbstractFactory GetInstance() { AbstractFactory instance = new ChinaOperationFactroy(); return instance; } public abstract Operation AddOperation(); public abstract Operation SubOperation(); }
这种改动可以通过反射来搞定它,这样就只需要修改配置文件就可以了,反射在工厂方法里已经介绍,就不再多写了。
四、工厂与抽象工厂的对比
由代码也可以看出,抽象工厂解决的是创 建一系列有共同风格的产品(鲁菜还是粤菜),而工厂方法模式解决的创建有共同特征的一系列产品(红烧肉、清蒸鱼它们都是食物)。