初尝Factory Method 设计模式
假设您有一间生产PC 的工厂,绝大部分的组件都能自行生产或已经库存到位,但CPU 需要进口intel 的。这个时候您会怎么办?显然是不可能停下手上所有的生产工作去等待intel 给你一个答案,相反的,应该继续生产,并且要确定和intel 提供的cpu 之间的接口是怎样的。这样的沟通,使得它的CPU 到货之后,我们就能将自己的半成品很快的转换为成品,进行市场资金的运作了。
Factory Method 正好体现了这一“工厂智慧”。当我们有某个元件(类)暂时无法确定时,只需要先确定它的功能接口,即和该类签订一个契约。在抽象类中只依赖接口,而将具体实现推迟到子类构建的过程中。
意图
定义一个用户创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。
结构图
下面以一个文本编辑器为例,写一段代码来说明工厂方法。对于不同的文件格式,如txt,rtf,doc 文本编辑器都希望支持。在编写该编辑器时,我们首先要确定其中某一种格式所需要支持的功能接口,那么这一框架就不需要考虑具体的实现细节,而等到具体实现某一种格式的时候,再来具体实施。
代码
using System;
using System.Configuration;
using System.Reflection;
namespace FactoryMethod
{
public interface IDocument {
void Open();
void Close();
void Save();
}
public class TXTDocument : IDocument
{
public TXTDocument() {
Console.WriteLine("创建了一个TXT 文件哟!");
}
public void Open() {
Console.WriteLine("TXT 文件被打开了!");
}
public void Close() {
Console.WriteLine("TXT 文件已被关闭了!");
}
public void Save() {
Console.WriteLine("TXT 文件已被保存!");
}
}
public abstract class AbstractDocumentEditor {
private IDocument doc;
protected abstract IDocument CreateDocument();
public void NewDocument() {
doc = this.CreateDocument();
doc.Open();
}
public void SaveDocument() {
if (doc != null)
doc.Save();
}
public void CloseDocument() {
if (doc != null)
doc.Close();
}
}
public class TXTEditor : AbstractDocumentEditor {
protected override IDocument CreateDocument()
{
return new TXTDocument();
}
}
class Program
{
static void Main(string[] args)
{
//从配置文件中读取我们想要的编辑器
string editorName= ConfigurationManager.AppSettings["editorName"].ToString();
AbstractDocumentEditor editor = (AbstractDocumentEditor)Assembly.Load("DesignPattern").CreateInstance("FactoryMethod." + editorName);
//使用编辑器
editor.NewDocument();
editor.SaveDocument();
editor.CloseDocument();
}
}
}
总结
Factory Method模式是设计模式中应用最为广泛的模式,然而我们要明确的是:在面向对象的编程中,对象的创建工作非常简单,对象的创建时机却很重要。Factory Method要解决的就是对象的创建时机问题,它提供了一种扩展的策略,很好地符合了开放封闭原则。
Factory Method模式通过面向对象的手法,将所要创建的具体对象的创建工作延迟到了子类,从而提供了一种扩展的策略,较好的解决了这种紧耦合的关系。
在以下情况下,适用于工厂方法模式:
- 当一个类不知道它所必须创建的对象的类的时候。
- 当一个类希望由它的子类来指定它所创建的对象的时候。
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。


近期评论