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

    首先声明,之前vue项目没有报错,做react项目这样配置就报错了. 一.问题描述 [HMR] Hot Module Replacement is disabled. 二.问题分析 不太理解控制台为什 ...

  2. win10,vs2017+mpi v10.0 安装与入门 (详细)

    一.安装visual studio 2017  下载 地址:https://visualstudio.microsoft.com/zh-hans/vs/ 安装 我们再选择自己想要安装的东西,确认好后点 ...

  3. Hibernate根据实体类自动创建表

    Hibernate支持自动建表,在开发阶段很方便,可以保证hbm与数据库表结构的自动同步. 如何使用呢?很简单,只要在hibernate.cfg.xml里加上如下代码 Xml代码<propert ...

  4. Chrome_断点调试(使用vue-resource进行数据交互)

    一.使用vue-resource插件进行数据交互式,返回的并不是直接的json数据,其实还封装了一层. 如下代码:直接使用 res.result.list 取不到数据. methods:{ cartv ...

  5. poj 1375

    一道解析几何么,,, 其实就是求直线与圆的切线. 看到方法有很多,比如根据角度之类的. 这里主要用到了初中的几何知识. 考虑这幅图. 首先可以根据相似三角形知道b的长度,同时圆心与点的方向也知道. 那 ...

  6. 超小Web手势库AlloyFinger原理(转载)

    目前AlloyFinger作为腾讯手机QQ web手势解决方案,在各大项目中都发挥着作用. 感兴趣的同学可以去Github看看: https://github.com/AlloyTeam/AlloyF ...

  7. Oracle 备份与恢复

    在进行生产服务器升级.或更换数据库服务器.搭建测试环境时,需要对生产数据库进行备份以及将来可能的还原. 1.expdp导出 expdp DMS version directory=DATA_PUMP_ ...

  8. servlet数据库验证登录

    servlet数据库验证登录 一.将数据库连接和验证封装为一个单独的类 import java.sql.*; public class SQLtest { // JDBC 驱动名及数据库 URL st ...

  9. ASP.NET JS调用WebService——简单例子

    一.创建好WebService 二.编辑页面与js 三. 运行页面并点击按钮,结果如下 简单调用吧!

  10. h5跳转

    <!doctype html> <html lang="en" style="width:100%; height:100%"> < ...