背景:有一个应用框架,它可以向用户显示多个文档。在这个框架中,两个主要的抽象是类Application和Document.这两个类都是抽象的。客户必须通过它们的子类来做与举替应用相关的实现。
分析:因为被实例化的特定Document子类是与特定应用相关的,所iApplication类不可能预测到那个Document子类将被实例化一一Application类仅直到一个新的文档何时应被创建,而不知道哪一种Document将被创建。这就产生了一个尴尬的局面框架必须实例化类,但是它只知道不能被实例化的抽象类。
延迟实例化一一工厂方法:
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
需求:使用框架开发一款Word应用程序。
1 namespace FactoryMethod 2 { 3 /// <summary> 4 /// 文档抽象类,定义了文档的一般操作接口 5 /// </summary> 6 public abstract class Document 7 { 8 public abstract void Open(); 9 public abstract void Close(); 10 public abstract void Save(); 11 public abstract void Revert(); 12 } 13 14 }
1 namespace FactoryMethod 2 { 3 /// <summary> 4 /// 文档生产工厂,定义了生产文档的接口 5 /// </summary> 6 public abstract class Application 7 { 8 public abstract Document CreateDocument(); 9 10 } 11 }
using System;namespace FactoryMethod {public class Word:Document{public override void Close(){Console.WriteLine("关闭了一个Word文档");}public override void Open(){Console.WriteLine("打开了一个Word文档");}public override void Revert(){Console.WriteLine("恢复了一个Word文档");}public override void Save(){Console.WriteLine("保存了一个Word文档");}} }
1 namespace FactoryMethod 2 { 3 public class WordApp : Application 4 { 5 public override Document CreateDocument() 6 { 7 return new Word(); 8 } 9 } 10 }
1 using System; 2 3 namespace FactoryMethod 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 Application app = new WordApp(); 10 Document doc = app.CreateDocument(); 11 doc.Open(); 12 doc.Revert(); 13 doc.Save(); 14 doc.Close(); 15 Console.ReadKey(); 16 } 17 } 18 }
运行结果:
新的需求:使用现有框架再开发一款Excel和PowerPoint应用程序。
分析:方法一:分别增加对应的工厂子类和产品子类即可。
方法二:参数化工厂,根据工厂接收的不同参数,返回不同的产品。(本人比较懒,这种方法要修改很现有多代码,放弃)
方法三:使用泛型。
这里我就采用泛型了,泛型的好处是不言而喻的,一次编写,永久使用,再多的产品使用这一个模板工厂就可以了。而且也不需要改变原有代码。
1 namespace FactoryMethod 2 { 3 public class App<T> : Application where T : Document,new() 4 { 5 public override Document CreateDocument() 6 { 7 return new T(); 8 } 9 } 10 }
1 using System; 2 3 namespace FactoryMethod 4 { 5 class Excel:Document 6 { 7 public override void Close() 8 { 9 Console.WriteLine("关闭了一个Excel文档"); 10 } 11 12 public override void Open() 13 { 14 Console.WriteLine("打开了一个Excel文档"); 15 } 16 17 public override void Revert() 18 { 19 Console.WriteLine("恢复了一个Excel文档"); 20 } 21 22 public override void Save() 23 { 24 Console.WriteLine("保存了一个Excel文档"); 25 } 26 } 27 }
1 using System; 2 namespace FactoryMethod 3 { 4 public class PPT:Document 5 { 6 public override void Close() 7 { 8 Console.WriteLine("关闭了一个PPT文档"); 9 } 10 11 public override void Open() 12 { 13 Console.WriteLine("打开了一个PPT文档"); 14 } 15 16 public override void Revert() 17 { 18 Console.WriteLine("恢复了一个PPT文档"); 19 } 20 21 public override void Save() 22 { 23 Console.WriteLine("保存了一个PPT文档"); 24 } 25 } 26 }
运行结果:
参考资料《Design Patterns》