前言

  上一篇我们介绍了单例模式,今天给大家讲一个比较简单的模式——工厂模式(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. Sublime Text 3 实现C语言代码的编译和运行

    Sublime Text 3 是一款优秀的代码编辑软件.界面简洁,轻巧快速,很受大家的欢迎. 最近开始用他来编辑数据结构的C语言代码,这就需要在新建编译系统.具体方法如下: 首先: 接下来是关键的一步 ...

  2. 洛谷P1140 相似基因

    题目:https://www.luogu.org/problemnew/show/P1140 分析: 本题一看就知道是一道动归,其实和字串距离非常的像,只不过多了题目规定的匹配相似度罢了. 匹配的相似 ...

  3. 百度OCR文字识别API使用心得===com.baidu.ocr.sdk.exception.SDKError[283604]

    异常com.baidu.ocr.sdk.exception.SDKError[283604]App identifier unmatch.错误的packname或bundleId.logId::303 ...

  4. <<Modern CMake>> 翻译 1. CMake 介绍

    <<Modern CMake>> 翻译 1. CMake 介绍 人们喜欢讨厌构建系统. 仅仅观看 CppCon17 上的演讲,就可以看到开发人员因为构建系统而闹笑话的例子. 这 ...

  5. eval 与 exec, compile区别

    exec 不是表达式: python 2. x, 中的一个语句和 python 3. x. 中的一个函数它编译并立即计算一个字符串中包含的语句或者语句集. 例如: exec('print(5)') # ...

  6. Spring WebClient vs. RestTemplate

    1. 简介 本教程中,我们将对比 Spring 的两种 Web 客户端实现 -- RestTemplate 和 Spring 5 中全新的 Reactive 替代方案 WebClient. 2. 阻塞 ...

  7. 【经验分享】ASP.NET 的 Page_Load 执行了2次,真的!

    发现问题 这是来自一位网友的提问: 本着求真务实的态度,我打开了 AppBoxPro 项目,本地调试果然发现 Page_Load 进入了两次! 其实在没测试之前,我就有了大概的方向,因为AppBoxP ...

  8. Spark Streaming消费Kafka Direct保存offset到Redis,实现数据零丢失和exactly once

    一.概述 上次写这篇文章文章的时候,Spark还是1.x,kafka还是0.8x版本,转眼间spark到了2.x,kafka也到了2.x,存储offset的方式也发生了改变,笔者根据上篇文章和网上文章 ...

  9. asp.net ashx处理程序中switch case的替代方案总结

    目录 1.用委托字典代替switch...case; 2.利用反射替代switch...case: 3.比较两种方案 4.其他方案 4.说明 5.参考 在开发 asp.net 项目中,通常使用一般处理 ...

  10. SpringMvc新建实例配置

    一.创建项目: 1.建立新的动态web项目: 2.为项目命名为:SpringMVC_01 3.添加tomcat运行时环境\依赖库  如果是MyEclipse的话创建web项目时就不需要此步骤 右键项目 ...