夸克之书

  • 首页
  • 科普
  • 笔记
  • C#
  • 物联网
  • 算法
  • Linux
  • 树莓派
夸克之内,别有洞天
  1. 首页
  2. C#
  3. 正文

23种常见的设计模式(2):工厂方法模式

2019-12-30 645点热度 0人点赞 0条评论

在进入正题之前,我们先一起来重温一下简单工厂模式。

什么是简单工厂模式?通俗一点来说就是就是专门定义一个类或者或一个方法根据不同参数来返回继承了同一个抽象类的具体实现类。是不是很像一个类工厂,所以就叫简单工厂模式了。

23种常见的设计模式(2):工厂方法模式插图
简单工厂模式(来源:百度百科)

对于简单工厂模式,举个简单的例子。我们开了一家工厂,现在在生产三种产品,分别是ProductA、ProductB和ProductC。

现在我们先来定义我们的抽象工厂类:

/// <summary>
/// 工厂类
/// </summary>
public abstract class IFactory
{
    public abstract void Show();
}

现在我们来创建三种产品的对应的产品类:

public class ProductA : IFactory
{
    public override void Show()
    {
        Console.WriteLine("我是产品A");
    }
}

public class ProductB : IFactory
{
    public override void Show()
    {
        Console.WriteLine("我是产品B");
    }
}

public class ProductC : IFactory
{
    public override void Show()
    {
        Console.WriteLine("我是产品C");
    }
}

好了,工厂有了,产品也有了。我们再来招聘一个产品经理吧,通过产品经理来控制产品的生产。

/// <summary>
/// 工厂创建类,负责输出产品
/// </summary>
public class FactoryCreater
{
    public static IFactory Creator(ProduceName name)
    {
        switch (name)
        {
            case ProduceName.A:
                return new ProductA();
            case ProduceName.B:
                return new ProductB();
            case ProduceName.C:
                return new ProductC();
            default:
                throw new Exception("啊!我不生产这个产品。");
        }
    }
}

BOOS指挥代码(调用代码):

IFactory factory;
factory = FactoryCreater.Creator(ProduceName.A);
factory.Show();
factory = FactoryCreater.Creator(ProduceName.B);
factory.Show();
factory = FactoryCreater.Creator(ProduceName.C);
factory.Show();

运行一下,我们通过输入不同的参数指挥产品经理来生产不同的产品。

23种常见的设计模式(2):工厂方法模式插图1
简单工厂模式运行截图

通过上面的例子,很容易就能看出来简单工厂模式的优缺点。

优点:

· 将创建实例的工作与使用实例的工作分开,使用者不必关心类对象如何创建,实现了解耦;
· 把初始化实例时的工作放到工厂里进行,使代码更容易维护。 更符合面向对象的原则 & 面向接口编程,而不是面向实现编程。

缺点:

· 工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂挂掉了,整个系统都会受到影响;
· 违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑。

而工厂方法模式就是为了解决工厂模式的两个缺点的。通过工厂方法,即不违反开闭原则,又能让整个系统易于扩展,不至于产品经理挂掉了,整个工厂也就不运作了。

那么什么是工厂方法模式呢?工厂方法模式,又称工厂模式、多态工厂模式和虚拟构造器模式,通过定义工厂父类定义创建对象的公共接口,而子类则负责生成具体的对象。与简单工厂模式最明显的区别就是工厂方法模式是在子类中生成具体的对象,而不是由工厂来创建子类对象。解决了工厂一旦需要生产新产品就需要修改工厂类的方法逻辑的缺点。

看上面这一段,肯定是晕乎乎的,这都是什么跟什么啊?不过别急,我们再进一步举个例子,一起看看工厂方法模式是怎么运作的。

还是我们刚才那个工厂,不过最近一段时间,生意爆好。一个产品经理已经忙不过来,于是我们决定再开几个工坊,让不同的工坊生产不同的产品,也让我们的产品经理歇一歇。

为了约束我们工坊,我们来创建一个抽象工坊类。

/// <summary>
/// 抽象工厂类
/// 用于创建具体的工厂
/// </summary>
public abstract class IWorkshop
{
    public abstract IFactory Create();
}

然后分别创建每个产品对应的生产工坊,通过工坊来创建对应的产品生产类。

/// <summary>
/// 生产A产品的工坊A
/// </summary>
public class WorkshopA : IWorkshop
{
    public override IFactory Create()
    {
        return new ProductA();
    }
}

/// <summary>
/// 生产B产品的工坊B
/// </summary>
public class WorkshopB : IWorkshop
{
    public override IFactory Create()
    {
        return new ProductB();
    }
}

/// <summary>
/// 生产C产品的工坊C
/// </summary>
public class WorkshopC : IWorkshop
{
    public override IFactory Create()
    {
        return new ProductC();
    }
}

从上面的代码可以看出来,我们产品经理已经升职加薪啦,从原来的产品经理变成厂长啦。既然如此,我们也只有通过指挥厂长来生产我们想要的产品了。

//工厂方法模式
factory = new WorkshopA().Create();
factory.Show();
factory = new WorkshopB().Create();
factory.Show();
factory = new WorkshopC().Create();
factory.Show();

看看我们生产的产品:

23种常见的设计模式(2):工厂方法模式插图2
工厂方法模式运行截图

可以看出相对于简单工厂模式,工厂方法模式缺少了必要的逻辑判断,把该调用哪个工厂生产的逻辑交给开发人员处理。但同时也解决了简单工厂模式不利于扩展和违反开闭原则的缺点。

但问题又来了?不可能我们一个工坊就只生产一个产品呀?下篇待续....

本篇代码下载:点此下载

本作品采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可
标签: 暂无
最后更新:2020-12-13

Afirefish

夸克之内,别有洞天

打赏 点赞
< 上一篇
下一篇 >

文章评论

您需要 登录 之后才可以评论

Afirefish

夸克之内,别有洞天

搜索文章
分类目录
  • C# (28)
  • Linux (3)
  • 树莓派 (13)
  • 物联网 (19)
  • 科普 (4)
  • 笔记 (30)
  • 默认 (44)
最新 热点 随机
最新 热点 随机
树莓派PWM风扇控制 PVE重启后LVM Thin数据丢失,错误:Volume group "****" has insufficient free space (128 extents): 4048 required. OpenWrt配置SmartDNS OpenWrt x86安装Frpc Intel网卡开机显示Initializing Intel(R) Boot Agent GE v1.5.50 IdentityServer4证书创建 免费本地解析域名(locallocal.cn),支持HTTPS 使用淘宝npm以及安装cnpm
你见过哪些有趣的代码?修改PostgreSQL数据库默认用户postgres密码在VS Code开发Arduino项目Error response from daemon: cannot stop container: ******: Cannot kill container *******:.....单机Docker搭建FastDFSC# Json序列化时将长整型(long)属性序列化为Json字符串使用淘宝npm以及安装cnpm免费本地解析域名(locallocal.cn),支持HTTPS
OpenWrt x86安装Frpc IIS应用程序池两种运行模式:集成模式和经典模式。 记一次成功的Update(Oracle误Delete或Update数据还原) 你见过哪些有趣的代码? 在ASP.NET Core中使用Session 23种常见的设计模式(8):中介者模式 23种常见的设计模式(6):代理(委托)模式 近期学习计划整理
最近评论
发布于 2 周前(02月21日) 好的谢谢,那我只能通过kill杀死推流指令进程来实现了。
发布于 2 周前(02月21日) 要用这个项目的话,你得自己拉代码来改了。做这玩意儿主要是考虑全天候的,没考虑过关[笑哭]
发布于 2 周前(02月21日) 就是想问有没有能通过代码控制的关闭推流的指令,而不需要手动控制。我想设置一个按钮来控制开始推流和结束...
发布于 2 周前(02月20日) 唔,没懂你意思,直接拔电源不就行了。不拔电源关闭推流服务也行撒。
发布于 2 周前(02月20日) 你好,我想问一下,如果不想推流了,该用什么方法停止树莓派推流呢?
书签
  • 打赏
  • 毒鸡汤(有点意思)
  • 米店
  • 金鱼直播间
放松一下
https://www.quarkbook.com/wp-content/uploads/2020/09/Yanni-Nightingale.flac
用户您好!请先登录!
登录 注册

COPYRIGHT © 2020 夸克之书. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

蜀ICP备15036129号-9

登录
注册|忘记密码?