定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

——DP

UML类图

模式说明

抽象业务基类

实际业务类的公共基类,也是工厂要创建的所有对象的父类,这部分同简单工厂。在这里是一个计算基类,定义了两个参数和一个抽象的计算方法:

    /// <summary>
/// 计算基类
/// </summary>
abstract class Operation
{
public double NumberA { get; set; }
public double NumberB { get; set; } public abstract double GetResult();
}

有了抽象的业务基类,那么要根据实现业务来实现具体的业务子类。这里是具体计算方法的各种实现:

    /// <summary>
/// 加法运算
/// </summary>
class OperationAdd:Operation
{
public override double GetResult()
{
return NumberA + NumberB;
}
}
/// <summary>
/// 减法运算
/// </summary>
class OperationSub : Operation
{
public override double GetResult()
{
return NumberA - NumberB;
}
}

工厂类

由于简单工厂,在工厂类中存在大量的if...else或switch...case判断语句,在添加新业务类的时候,还是需要修改工厂类(添加新的判断语句)才能实现,这就违背了一条重要的设计原则——开闭原则。所以工厂方法模式中,将这些判断逻辑抽象出来,抽象成一个创建业务类的接口(即定义中的“定义一个用于创建对象的接口”),然后由具体的工厂子类来创建各自的业务对象。

计算工厂类抽象出的统一接口:

    /// <summary>
/// 计算工厂类接口
/// </summary>
interface IOperationFactory
{
Operation CreateOperation();
}

具体的计算工厂类(创建各自的业务对象):

    /// <summary>
/// 加法运算工厂
/// </summary>
class OperationAddFactory:IOperationFactory
{
public Operation CreateOperation()
{
return new OperationAdd();
}
}
/// <summary>
/// 减法运算工厂
/// </summary>
class OperationSubFactory:IOperationFactory
{
public Operation CreateOperation()
{
return new OperationSub();
}
}

这样设计后,客户端只要根据需要,实例化一个具体的计算工厂,然后用工厂生成业务对象,就可以进行计算了:

            IOperationFactory factory = new OperationAddFactory();
Operation op = factory.CreateOperation(); op.NumberA = ;
op.NumberB = ;
double result = op.GetResult();

总结

工厂方法模式是对简单工厂模式中的工厂类,进行了面向对象的重构。使其在面对变化时,不需要修改工厂类里的判断逻辑,而是通过扩展(添加新的业务类和工厂类)来完成,这就使得工厂类的设计也完全符合开闭原则了。

参考

  1. 程杰老师  《大话设计模式》

设计模式——工厂方法(Factory Method)的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. 工厂方法 Factory Method

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

  7. 设计模式——工厂模式(Factory Method)

    工厂方法模式,定义一个用于创建对象的接口,让子类决定实例化哪个类.工厂方法使一个类的实例化延迟到其子类. UML图: 运算基类: package com.cnblog.clarck; /** * 数据 ...

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

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

  9. Java设计模式-工厂方法模式(Virtual Constructor/Polymorphic Factory)

    工厂方法模式(Virtual Constructor/Polymorphic Factory) 工厂方法模式是类的创建模式,又叫做虚拟构造子模式(Virtual Constructor)或者多态性工厂 ...

随机推荐

  1. 多版本Python共存时pip给指定版本的python安装package的方法

    在Linux安装了多版本Python时(例如python2.7和3.6),pip安装的包不一定是用户想要的位置,此时可以用 -t 选项来指定位置. 例如目标位置是/usr/local/lib/pyth ...

  2. Operating System-Kickoff:什么是操作系统&&操作系统的核心概念

    接下来会写一系列Operating System(操作系统)的文章,今天先开个头.本文主要内容: 什么是操作系统 操作系统的核心概念 程序=数据结构+算法 一.什么是操作系统 1.1 操作系统是对硬件 ...

  3. python中全局变量的使用

    python中在module定义的变量可以认为是全局变量, 而对于全局变量的赋值有个地方需要注意. test.py ------------------------------------------ ...

  4. MySQL on Azure高可用性设计 DRBD - Corosync - Pacemaker - CRM (二)

    在上一篇文章中描述了MySQL HA on Azured 设计思路,本篇文章中将描述具体的部署,每个组件的安装和配置. 整体的设计架构如下: 下面将是所有组件的安装配置过程,所有的虚拟机是CentOS ...

  5. 【转】 Pro Android学习笔记(四四):Dialog(1):触发Dialog

    目录(?)[-] 创建dialog fragment Activity显示对话框 Android提供alert.prompt.pick-list,单选.多选,progress.time-picker和 ...

  6. JVM体系结构之二:类加载器

    一.概述 定义:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型.类加载和连接的过程都是在运行期间完成的. 二. 类的加载 ...

  7. openstackM版本安装

    部署期间常见问题:http://www.cnblogs.com/bfmq/p/6001233.html,问题跟对架构的理解永远比部署重要!你玩技术是绝对是要基于理论的 一.基本情况:物理设备:4台惠普 ...

  8. modbus读输入状态与读线圈状态的区别?

    01 读线圈状态 描述 读从机离散量输出口的 ON/OFF 状态,不支持广播.附录B列出由不同控制器型号支持最大的参数清单. 查询 查询信息规定了要读的起始线圈和线圈量,线圈的起始地址为零,1-16个 ...

  9. js遍历for,forEach, for in,for of

    ECMAScript5(es5)有三种for循环 简单for for in forEach ECMAScript6(es6)新增 for of 简单for for是循环的基础语法,也是最常用的循环结构 ...

  10. iOS开发者福利之精品源码汇总!免费下载

    汇总一些看着不错的源码,有需要的朋友过来下载吧!{:4_102:} 1.用swift制作的色彩炫丽的进度条-KDCircularProgressKDCircularProgress是使用swift制作 ...