
| 浅析设计模式之工厂方法 | ||
| 摘自: csdn.net 被阅读次数: 439 | ||
由 yangyi 于 2007-10-17 19:31:36 提供 | ||
闲谈工厂方法 设计模式系列中如果还不谈谈工厂方法设计模式就太对不起GoF了,为什么如此说?实际上工厂方法模式是好些模式的基石,它们或多或少的使用了工厂方法模式或以工厂方法为模型。 工厂方法模式是一种类创建型模式,它为创建一个对象提供了一个稳定的接口,而将对象创建的真正工作推迟到其子类,工厂方法允许将类的初始化工作延迟到子类,让子类决定实例化哪个具体的类。实际上很多时候对象的创建工作往往会发生变化,直接的去用new实例化对象会导致紧耦合,当需求发生变化的时候依赖项也会跟着发生变化。按照我们解决这类问题的一般原则:首先寻找变化点――对象创建,然后封装变化――用子类来封装,父类给客户程序提供稳定的接口,不稳定的地方给封装了,客户可见的只有稳定的父类接口,这也是我们面向对象开发人员一直所追求的目标。 工厂方法举例 既然是谈工厂方法模式,我们就来用工厂举例吧。 在举例之前先用一个类图来大致了解一下GoF的工厂方法模式的结构。 问题描述大概是:可口可乐公司的可乐瓶上粘贴广告条的工序,当一个可乐瓶到来的时候控制程序调用贴广告的类提供产生一个广告条的接口,假设流水线上来的可乐瓶有大有小(现实中肯定是不可能的了),那么这个接口就应该提供这样的实现:根据不同的可乐瓶产生不同的广告纸,这个广告纸的产生就是一个需求经常变化的环节(根据公司市场促销的变化广告纸需要变化等等)。 不用模式的实现: //广告纸 Get广告纸(int型别码){switch(型别码){caseA : returnnewA广告纸();break;caseB : returnnewB广告纸();break;//……..}} 当然,如果需求不再变化这种实现没有什么不妥,而且性能高效。但是不存在需求不变的程序,产生广告纸需求变化我们就得不断的修改这个switch,这个提供出去的接口也经常面临着变化,不再稳定(违反了开闭原则)。 为了向客户提供稳定的接口我们将产生广告纸的实现延迟到子类实现: publicclassCreator{publicvirtual广告纸 Get广告纸(int型别码){returnnew默认广告纸();}}publicclassConcreteCreator : Creator{publicoverride广告纸 Get广告纸(int型别码){switch(型别码){caseA : returnnewA广告纸();break;caseB : returnnewB广告纸();break;//……..//如果没有满足的型别码则调用父类的实现返回一个默认广告纸default: base.Get广告纸(型别码);}}} 其中,,默认广告纸、A广告纸、B广告纸都是广告纸的子类。 看到上面的例子我们并没有抑制变化的发生(这是不可能的),但是我们封装了变化而提供了不变的接口。
DotNet中的工厂方法
但是使用反射就失去了编译器的强类型检查,如果传入一个错误的字符串这个问题只有等到运行时刻才能发现,能不用就不用了。.net 2.0中我们有了泛型,在这里我们可以用泛型来解决这个问题了。 另一个实现如下:
上面所说的两种演进虽然已经失去了工厂方法模式原来的型构,但依然得到我们想要的:封装变化,为客户程序提供稳定的接口,不将需求的变化扩散到客户程序。所以说模式是灵活的,模式要这么多模式要表达的是她们的思想并不是模式的实现形式。 1
【发表评论 0条】 |