前言

  上一篇我们介绍了单例模式,今天给大家讲一个比较简单的模式——工厂模式(Factory Method,工厂模式又是什么呢?顾名思义,工厂——生产制造东西的地方。那么应用在程序当中该如何使用、并且又起到什么效果呢?以至于为什么用工厂模式呢?

  之前我们说的OCP原则(开放封闭原则),对扩展开放,对修改封闭这一原则。在工厂模式中有极好的体现,对对象及类进行极好的封装。使其减少代码之间的耦合性。更具有扩展性。

工厂模式介绍

一、来由

  在我们编程过程当中,总会面临一些类的创建以及对象的创建,但是由于需求而不断变动(增加或者修改),导致对象的变化。这时怎么处理这个问题呢?

工厂模式提供的一种封装机制,隔离出了那些易变动的对象。这个时候需求的变动不再影响之前的对象的变动了。

二、意图

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

三、案例图

工厂模式中由以下部分组成:

(1)、抽象工厂(Creator): 复制定义工厂所需的基本规则,其他任何具体工厂都得继承此抽象工厂

(2)、具体工厂(Concrete_Creator):继承抽象工厂,实现其定义的方法,以此来创建具体的产品

(3)、抽象产品(Product):复制定义产品的基本方法及规则,所有具体产品都得基础此抽象产品类

(4)、具体产品(Concrete_Product):继承抽象产品,实现其定义抽象方法,由具体工厂创建,两者是一一对应的关系。

四、工厂模式代码实现

这里我们通过一个事例来介绍工厂模式的规则及用法。在工厂模式中,定义抽象工厂,然后其具体工厂继承实现其抽象方法调用继承了抽象产品类的具体产品来创建产品。

 

下面我们就手机产品的制造来看看下面的事例吧:

namespace ConsoleApp4
{
public class Factory_Method_Pattern
{
}
#region 产品 =========================
/// <summary>
/// 抽象手机产品类
/// </summary>
public abstract class Phone
{
public abstract string Create();
} /// <summary>
/// 具体华为手机产品类
/// </summary>
public class Huawei : Phone
{
/// <summary>
/// 实现抽象方法
/// </summary>
/// <returns></returns>
public override string Create()
{
return "华为一号现世";
}
} /// <summary>
/// 具体小米手机产品类
/// </summary>
public class Xiaomi : Phone
{
/// <summary>
/// 实现抽象方法
/// </summary>
/// <returns></returns>
public override string Create()
{
return "小米一号现世";
}
} #endregion #region 工厂=========================
/// <summary>
/// 抽象工厂类
/// </summary>
public abstract class Factory
{
/// <summary>
/// 抽象工厂类的方法,创建调用产品
/// </summary>
/// <returns></returns>
public abstract Phone CreatePhone();
} /// <summary>
/// 具体华为工厂类,继承抽象工厂类
/// </summary>
public class HuaweiFactory : Factory
{
/// <summary>
/// 实现继承方法
/// </summary>
/// <returns></returns>
public override Phone CreatePhone()
{
return new Huawei();
}
} /// <summary>
/// 具体小米工厂类,继承抽象工厂类
/// </summary>
public class XiaomiFactory : Factory
{
/// <summary>
/// 实现继承方法
/// </summary>
/// <returns></returns>
public override Phone CreatePhone()
{
return new Xiaomi();
}
}
#endregion
}
 class Program
{
static void Main(string[] args)
{
//初始化工厂
Factory huaweiFactory = new HuaweiFactory(); //生产具体的华为手机
var result=huaweiFactory.CreatePhone();
//华为手机现世
var answer = result.Create();
Console.WriteLine(answer); Factory xiaomiFactory = new XiaomiFactory();
result = xiaomiFactory.CreatePhone();
answer = result.Create();
Console.WriteLine(answer); Console.ReadLine();
}
}

  在上述事例中,同样是先把手机抽象出一个抽象类,手机当然也不是凭空出现的。所以需要再抽象一个工厂类。工厂类派生子类不同的手机厂商类。同样手机也派生了不一样的品牌。手机厂商类再对应手机品牌去生产相应的手机。这时我们需要增加一个手机手机品牌,我们不需要去修改工厂类及产品类。我们另外新增即可。完全不影响其原来的运行。比如我们需要新增魅族手机。

    #region 新增魅族手机 ================
/// <summary>
/// 新增魅族工厂类
/// </summary>
public class MeizuFactory : Factory
{
public override Phone CreatePhone()
{
return new Meizu();
}
} /// <summary>
/// 新增具体魅族手机产品类
/// </summary>
public class Meizu : Phone
{
public override string Create()
{
return "魅族一号现世";
}
}
#endregion

在客户端调用时增加以下调用就可以了

            Factory meizuFactory = new MeizuFactory();
result = meizuFactory.CreatePhone();
answer = result.Create();
Console.WriteLine(answer);

使用场景及优缺点

在此模式中,将所有要创建的具体对象的工作都延迟放在了子类中去实现,实现了一种扩展的策略。与OCP原则相对应。

工厂模式主要针对解决的是”单个对象”的问题。隔离类的对象的使用者与具体类型之间的耦合关系。去实现了一定程度的解耦。

(一)使用场景

1、当用户不需要知道产品的类名的时候或者不关心如何创建的时候。我们只需要知道创建它的具体工厂的时候。

2、将创建对象的任务委托给多个工厂中的一个,客户端使用的时候无需关心是哪一个创建产品。当需要动态指定。

(二)优点

1、在编程方法中,客户端调用不需要知道产品的具体工厂,也不需要关心如何创建的。

2、在增加需求的时候,增加产品的时候仅需要新增一个工厂类及产品类即可,不需要对原来的代码进行修改。可轻易的扩展。

(三)缺点

在增加产品的时候,额外的增加了工厂类及产品类。增加一个产品增加两个类。在一定程度上增加了系统的复杂度。同时也增强了类之间的依赖性。这也就是其中不好的问题

总结

  每一个设计模式都有对应的使用场合,切勿滥用。在我们学习设计模式的同时,我们也需要以其原主要则作为基准学习。万万不能违背原则。在设计模式——工厂模式中,将创建对象的任务委托给其工厂子类、延迟执行。解决了系统难于扩展的问题,同时也减少了具体类与对象之间的耦合性。也实现了开放扩展封闭修改的原则。

  这个社会是存在不公平的,不要抱怨,因为没有用!人总是在反省中进步的!

  C#设计模式系列目录

欢迎大家扫描下方二维码,和我一起踏上设计模式的闯关之路吧!

  

二级小兵——工厂模式(Factory Method)的更多相关文章

  1. c++工厂模式(Factory method)

    下面以女娲造黑人,白人,黄种人的例子来介绍一下工厂模式. 1.工厂的接口,相当于造人工厂总部. class IHumanFactory { public: IHumanFactory(void) { ...

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

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

  3. 乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pattern)

    原文:乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pa ...

  4. 【设计模式】工厂方法模式 Factory Method Pattern

    在简单工厂模式中产品的创建统一在工厂类的静态工厂方法中创建,体现了面形对象的封装性,客户程序不需要知道产品产生的细节,也体现了面向对象的单一职责原则(SRP),这样在产品很少的情况下使用起来还是很方便 ...

  5. 工厂方法模式-Factory Method(Java实现)

    工厂方法模式-Factory Method 工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法让实例化的具体内容交给子类工厂来进行. 本文中的例子是这样的. 生产一个身份证, ...

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

    工厂方法模式(Factory Method Pattern) 介绍定义一个用于创建对象的接口,让子类决定将哪一个类实例化.Factory Method使一个类的实例化延迟到其子类. 示例有SqlMes ...

  7. 设计模式-03工厂方法模式(Factory Method Pattern)

    插曲.简单工厂模式(Simple Factory Pattern) 介绍工厂方法模式之前,先来做一个铺垫,了解一下简单工厂模式,它不属于 GoF 的 23 种经典设计模式,它的缺点是增加新产品时会违背 ...

  8. 六个创建模式之工厂方法模式(Factory Method Pattern)

    问题: 在使用简单工厂模式的时候,如果添加新的产品类,则必需修改工厂类,违反了开闭原则. 定义: 定义一个用于创建对象的接口,让子类决定具体实例化哪个产品类.此时工厂和产品都具有相同的继承结构,抽象产 ...

  9. 工厂模式(Factory Patter)

    1.工厂模式简介 工厂模式属于创建型模式,是专门用来创建对象的模式,抽象了实例化的过程.工厂模式分为 : 工厂方法模式.抽象工厂模式. 在学习工厂方法模式.抽象工厂之前,首先先要了解一下简单工厂模式, ...

随机推荐

  1. P2822组合数问题

    组合数问题(NOIP2016提高组Day2T1) Time Limit:1000MS  Memory Limit:512000K [题目描述] 组合数表示的是从n个物品中选出m个物品的方案数.举个例子 ...

  2. OnCommandStateChange 不响应

    原因是我把原先的OnCommandStateChange( long nCommand, BOOL bEnable )大BOOL改成了小bool,回调不认识了.

  3. [leetcode] #239 Sliding Window Maximum (Hard)

    原题链接 题意: 给定一个数组数字,有一个大小为k的滑动窗口,它从数组的最左边移动到最右边.你只能在窗口看到k个数字.每次滑动窗口向右移动一个位置. 记录每一次窗口内的最大值,返回记录的值. 思路: ...

  4. nginx配置目录访问&用户名密码控制

    背景 项目上需要一些共享目录让外地同事可以网页访问对应的文件,且受权限控制: 现有环境: centos nginx 你可以了解到以下内容: 配置nginx开启目录访问 并配置nginx用户名和密码进行 ...

  5. bat命令闪退问题

    今天执行一个bat命令,然而会出现问题:双击执行bat命令时,命令提示符界面会闪退. 然而该bat命令在他人电脑上可正常执行,而我会遇到这种问题. 以下是我尝试的方法: 首先尝试编辑bat命令,在ba ...

  6. Linux命令大全(简)

    rm--删除文件和目录   -i 删除一个已存在的文件前,提示用户进行确认.   -r 递归的删除目录. mkdir--创建目录 cp--复制文件和目录   -i 在覆盖一个已存在的目录前,提示用户进 ...

  7. storm学习路线指南

    关于对storm的介绍已经有很多了,我这里不做过多的介绍,我介绍一下我自己的学习路线,希望能帮助一些造轮子的同学走一些捷径,毕竟我也是站在前人总结整理的基础上学习了,如果有不足之处,还请大家不要喷我. ...

  8. 华三F100 系列防火墙 - 浮动路由联动NQA 实现双线路自动切换

    公司 有两条公网线路,一条移动作为日常主用线路,一条联通作为备用线路. 为了实现主备线路自动切换,配置了浮动路由 但浮动路由只能在 主用接口为down状态时才能浮出接管默认路由.如果故障为非物理链路故 ...

  9. jQuery中事件与动画

    jQuery中的事件与动画   一. jQuery中的事件 jQuery事件是对javaScript事件的封装. 1.基础事件 在javaScript中,常用的基础事件有鼠标事件.键盘事件.windo ...

  10. Heap Greedy

    1 239 Sliding Window Maximun 双端队列 public int[] maxSlidingWindow(int[] nums, int k) { if (nums == nul ...