背景:有一个应用框架,它可以向用户显示多个文档。在这个框架中,两个主要的抽象是类Application和Document.这两个类都是抽象的。客户必须通过它们的子类来做与举替应用相关的实现。

分析:因为被实例化的特定Document子类是与特定应用相关的,所iApplication类不可能预测到那个Document子类将被实例化一一Application类仅直到一个新的文档何时应被创建,而不知道哪一种Document将被创建。这就产生了一个尴尬的局面框架必须实例化类,但是它只知道不能被实例化的抽象类。
延迟实例化一一工厂方法:

工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

需求:使用框架开发一款Word应用程序。

 namespace FactoryMethod
{
/// <summary>
/// 文档抽象类,定义了文档的一般操作接口
/// </summary>
public abstract class Document
{
public abstract void Open();
public abstract void Close();
public abstract void Save();
public abstract void Revert();
} }
 namespace FactoryMethod
{
/// <summary>
/// 文档生产工厂,定义了生产文档的接口
/// </summary>
public abstract class Application
{
public abstract Document CreateDocument(); }
}
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文档");
}
}
}
 namespace FactoryMethod
{
public class WordApp : Application
{
public override Document CreateDocument()
{
return new Word();
}
}
}
 using System;

 namespace FactoryMethod
{
class Program
{
static void Main(string[] args)
{
Application app = new WordApp();
Document doc = app.CreateDocument();
doc.Open();
doc.Revert();
doc.Save();
doc.Close();
Console.ReadKey();
}
}
}

运行结果:

新的需求:使用现有框架再开发一款Excel和PowerPoint应用程序。

分析:方法一:分别增加对应的工厂子类和产品子类即可。

方法二:参数化工厂,根据工厂接收的不同参数,返回不同的产品。(本人比较懒,这种方法要修改很现有多代码,放弃)

方法三:使用泛型。

这里我就采用泛型了,泛型的好处是不言而喻的,一次编写,永久使用,再多的产品使用这一个模板工厂就可以了。而且也不需要改变原有代码。

 namespace FactoryMethod
{
public class App<T> : Application where T : Document,new()
{
public override Document CreateDocument()
{
return new T();
}
}
}
 using System;

 namespace FactoryMethod
{
class Excel:Document
{
public override void Close()
{
Console.WriteLine("关闭了一个Excel文档");
} public override void Open()
{
Console.WriteLine("打开了一个Excel文档");
} public override void Revert()
{
Console.WriteLine("恢复了一个Excel文档");
} public override void Save()
{
Console.WriteLine("保存了一个Excel文档");
}
}
}
 using System;
namespace FactoryMethod
{
public class PPT:Document
{
public override void Close()
{
Console.WriteLine("关闭了一个PPT文档");
} public override void Open()
{
Console.WriteLine("打开了一个PPT文档");
} public override void Revert()
{
Console.WriteLine("恢复了一个PPT文档");
} public override void Save()
{
Console.WriteLine("保存了一个PPT文档");
}
}
}

运行结果:

参考资料《Design Patterns》

工厂方法 Factory Method的更多相关文章

  1. Spring 通过工厂方法(Factory Method)来配置bean

    Spring 通过工厂方法(Factory Method)来配置bean 在Spring的世界中, 我们通常会利用bean config file 或者 annotation注解方式来配置bean. ...

  2. 抽象工厂(Abstract Factory),工厂方法(Factory Method),单例模式(Singleton Pattern)

    在谈工厂之前,先阐述一个观点:那就是在实际程序设计中,为了设计灵活的多态代码,代码中尽量不使用new去实例化一个对象,那么不使用new去实例化对象,剩下可用的方法就可以选择使用工厂方法,原型复制等去实 ...

  3. [设计模式-创建型]工厂方法(Factory Method)

    概括 名称 Factory Method 结构 动机 定义一个用于创建对象的接口,让子类决定实例化哪一个类.Factory Method 使一个类的实例化延迟到其子类. 适用性 当一个类不知道它所必 ...

  4. 设计模式——工厂方法(Factory Method)

    定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. ——DP UML类图 模式说明 抽象业务基类 实际业务类的公共基类,也是工厂要创建的所有对象的父类,这部分 ...

  5. Headfirst设计模式的C++实现——工厂方法(Factory Method)

    引用原书的一句话:所有的工厂模式都用来封装对象的创建,工厂方法模式通过让子类决定该创建的对象是什么来达到封装的目的. Pizza类及其派生类与上一例相同 PizzaStore.h #ifndef _P ...

  6. 设计模式二: 工厂方法(Factory Method)

    简介 工厂方法模式是创建型模式的一种, 核心结构有四个角色: 抽象工厂,具体工厂,抽象产品,具体产品; 实现层面上,该模式定义一个创建产品的接口,将实际创建工作推迟到具体工厂类实现, 一个产品对应一个 ...

  7. 设计模式学习心得<工厂方法 Factory Method>

    概述 意图 业务代码中常常有构造对象的过程,它拥有大量的参数.并且有很多地方需要这对象. 简化对象构造过程. 主要解决 一个类在不同场景的频繁地创建,让不同对象的创建更有语义化,提高代码复用性. 何时 ...

  8. 简单工厂,Factory Method(工厂方法)和Abstract Factory(抽象工厂)模式

    对于简单工厂来说,它的工厂只能是这个样子的 public class SimplyFactory {  /** * 静态工厂方法 */ public static Prouct factory(Str ...

  9. 工厂方法模式(Method Factory),理解多态应用的好例子.

    工厂方法模式又称为多态性工厂,个人认为多态性工厂更能准确的表达这个模式的用处.与简单工厂(静态工厂)相比较,这里的多态性是指抽象出一个工厂基类,将因为一个产品有N种不同的是现这种变化封装起来,将具体的 ...

随机推荐

  1. Beta(0/7)

    组长重选议题 Beta阶段计划改进完善的功能 Beta阶段计划新增的功能 需要改进的团队分工 需要改进的工具流程 Beta冲刺的时间计划安排 组长重选议题 没人想当,所以没有换. Beta阶段计划改进 ...

  2. python 进程间通信(上)

    一  使用queue来实现进程间的内存共享 #_*_coding:utf-8_*_ from multiprocessing import Process,Queue import os,time d ...

  3. Think twice, code once.

    .Think twice, code once. .WJMZBMR神犇的话 我还记得很久以前有人跟我说的话,自己选择的路,跪着也要走完.朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感 ...

  4. GitHub的实现是否是基于此语言的支持网络编程性呢?

    我觉好像是的,我之前很奇怪为什么那样就可以引用了,后来发现GitHub中的java  JavaScript  phton等语言都支持网络编程.

  5. day13_H5_CSS_1

    一.标签.HTML是可以被浏览器解析的一套规则 1.a标签:他是主动闭合标签,表现形式<a href="http://www.baidu.com">baidu<a ...

  6. GMA Round 1 新年的复数

    传送门 新年的复数 已知$\left\{\begin{matrix}A>B>0\\ AB=1\\ (A+B)(A-B)=2\sqrt{3}\end{matrix}\right.$ 求$(A ...

  7. __x__(27)0907第四天__ float 浮动

     float 浮动 块元素脱离文档流,水平排列. 浮动元素 会尽量往左上(left),或者右上(right)浮动,直到遇到 块元素 或者 其他浮动元素. 可选值: none;   默认值,不脱离文档流 ...

  8. Hangover POJ - 1003

    How far can you make a stack of cards overhang a table? If you have one card, you can create a maxim ...

  9. Java正则表达式过滤并消除非法字符

    package sd; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * * @author 大汉 * */ ...

  10. wpf mvvm 实例

    1.程序结构如图所示: 2.Model实现 在Model文件夹下新建业务类StudentModel,代码如下: public class StudentModel : INotifyPropertyC ...