工厂方法 Factory Method

背景:有一个应用框架,它可以向用户显示多个文档。在这个框架中,两个主要的抽象是类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》

posted @ 2019-01-03 23:15  _清风明月  阅读(292)  评论(0编辑  收藏  举报