Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >new也可以创建对象,为什么需要工厂模式?

new也可以创建对象,为什么需要工厂模式?

作者头像
用户6557940
发布于 2022-07-24 08:48:21
发布于 2022-07-24 08:48:21
96700
代码可运行
举报
文章被收录于专栏:Jungle笔记Jungle笔记
运行总次数:0
代码可运行

设计模式里,工厂模式是一类创建型的设计模式。为遵循软件设计和开发的开闭原则,先后衍生出了简单工厂模式,工厂方法模式和抽象工厂模式。作为一种创建型的设计模式,工厂模式是用来创建新对象的。那么问题就来了,以C++为例,C++的类明明构造函数也可以创建新的对象啊,为什么非得引入工厂模式呢

封装创建对象时的初始化工作

如果使用C语言,分配并初始化的工作包括:

  • malloc申请内存(但申请完了对象并没有初始化,只是有了一片内存空间),并强制类型转换
  • 初始化这块内存
  • Do other works

好像有点麻烦,分配内存、类型转换、初始化。如果是C++,new的动作包括分配内存和调用构造函数两个步骤,比较简化了。这是对一般的初始化过程比较简单的对象。那如果初始化过程比较复杂呢?什么叫比较复杂的初始化过程呢?就是说创建对象不仅是分配内存空间,还要做一些其他初始化工作,甚至是与外部变量或者资源相关的工作

下面的代码是NVDLA的compiler的源码中的一部分:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SDPScaleOpNode* NodeFactory::newSDPScaleOpNode
(
    ScaleNode* origCanNode,
    Graph* engGraph
)
{
    B b;
    DD dd;
    NvU16 numBatches = engGraph->profile()->multiBatchSize();
 
    b = dd = new SDPScaleOpNode(origCanNode, numBatches);
    dd->setName(std::string("sdp-scale-") + toString(s_sdp_scale_priv.size()));
    dd->setId(engGraph->nextNodeId());
    dd->setGraph(engGraph);
    engGraph->insertNode(b);
 
    s_sdp_scale_priv.insert(std::pair<B, DD>(b, dd));
    return dd;
}

我删去了部分代码以便于观察。该接口是要创建一个SDPScaleOpNode,但封装在NodeFactory的newSDPScaleOpNode()接口里。该接口里除了

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
new SDPScaleOpNode(origCanNode, numBatches);

以外,还有其他setter和insert工作。如果不用工厂模式封装,则每创建一个node,都要在创建node的地方写上其他setter和insert的代码,不便于阅读,而且造成代码冗余。

下面代码是tensorflow源码中的一个片段。可以看到,创建device的初始化过程更加复杂,甚至还可以处理一些异常

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::unique_ptr<Device> DeviceFactory::NewDevice(const string& type,
                                                 const SessionOptions& options,
                                                 const string& name_prefix) {
  auto device_factory = GetFactory(type);
  if (!device_factory) {
    return nullptr;
  }
  SessionOptions opt = options;
  (*opt.config.mutable_device_count())[type] = 1;
  std::vector<std::unique_ptr<Device>> devices;
  TF_CHECK_OK(device_factory->CreateDevices(opt, name_prefix, &devices));
  int expected_num_devices = 1;
  auto iter = options.config.device_count().find(type);
  if (iter != options.config.device_count().end()) {
    expected_num_devices = iter->second;
  }
  DCHECK_EQ(devices.size(), static_cast<size_t>(expected_num_devices));
  return std::move(devices[0]);
}

统一创建对象的接口命名

有了上面的例子,也就比较好理解“统一接口命名”了。

  • 如果是class Football,那么创建是要new Football;
  • 如果创建Basketball,则要new Basketball;
  • 如果是Volleyball,则new VolleyBall;
  • 如果是AbcdEfgHijkOpq1234567,则new AbcdEfgHijkOpq1234567(类的名字很长)。

如果有工厂模式做封装,那么就成了

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
createFootball();
createBasketball();
createVolleyball();
createAbcdEfgHijkOpq1234567();

接口命名很清晰,并且能够通过函数名大概知道它的作用。

对象是否真的需要“创建”?

每次new,都会去分配内存(不谈placement new)。但是有的场景下,我们真的需要每次都分配内存吗?要从线程池里获取一个线程,要从内存池里获取一片内存,要从某个资源池里获取一个资源,这些资源本身就有,不需要重新分配,除非池里的资源也用完了。所以工厂模式的另一个作用是,掌控某些资源分配的时机,当真正需要分配内存的时候,才去分配

结合多态,便于扩展

工厂模式结合多态,定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化,增加代码的灵活性。比如下列代码,通过一个统一的接口getSportProduct(),运行时可创建出不同的产品。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int test()
{
  AbstractFactory *fac = NULL;
  AbstractSportProduct *product = NULL;
 
  fac = new BasketballFactory();
  product = fac->getSportProduct();
 
  fac = new FootballFactory();
  product = fac->getSportProduct();
 
  fac = new VolleyballFactory();
  product = fac->getSportProduct();  
 
  // other work
 
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Jungle笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
​设计模式之单例、工厂、发布订阅者模式
近段时间兵长在开发一个小项目,需要用到设计模式的思想,但是兵长苦于没有接触过设计模式,于是走到胖sir座位旁边
阿兵云原生
2023/02/16
3430
java设计模式之-工厂模式
工厂模式是一种创建对象的设计模式,它通过将对象的实例化过程封装在一个工厂类中,从而实现对象的创建和使用的解耦。它属于创建型模式的一种,可以帮助我们更加灵活地创建对象。
用户11172247
2024/06/19
1140
PHP单例模式与工厂模式详解
一、单例模式又称为职责模式,它用来在程序中创建一个单一功能的访问点,通俗地说就是实例化出来的对象是唯一的。 所有的单例模式至少拥有以下三种公共元素:
用户2323866
2021/07/05
6980
学会工厂方法模式,搬起砖头更加给力!
在介绍简单工厂方法模式时Jungle总结出简单工厂模式存在最大的问题是违背了“开闭原则”,每当增加新的产品时,需要修改工厂类的逻辑。为了规避这种不足,同时很好的利用简单工厂模式的优点,本节Jungle将声情并茂地为您奉上工厂方法模式。
用户6557940
2022/07/24
1810
学会工厂方法模式,搬起砖头更加给力!
深入理解工厂模式:创建对象的艺术
工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的最佳方式。工厂模式抽象了对象的创建过程,使客户端代码与具体对象的创建过程分离,从而降低了代码的耦合性。在本文中,我们将深入研究工厂模式,包括其定义、结构、不同类型的工厂、应用场景以及如何使用示例代码来实现工厂模式。
coderidea
2023/11/25
2350
深入理解工厂模式:创建对象的艺术
简单工厂模式都不会,你真应该去工厂搬砖!
创建型模式关注对象的创建过程,在软件开发中应用非常广泛。创建型模式描述如何将对象的创建和使用分离,让用户在使用对象过程中无须关心对象的创建细节,从而降低系统耦合度,并且让系统易于修改和扩展。
用户6557940
2022/07/24
1930
简单工厂模式都不会,你真应该去工厂搬砖!
抽象工厂模式——工厂方法的大结局
回顾之前的设计模式,简单工厂模式所有逻辑都封装在工厂类中,工厂根据客户提供的产品名字创建对应产品的对象实例;工厂方法模式将产品的创建过程放到了具体工厂类中,每一个工厂可以创建一个具体产品,由此可能会创建许多工厂类。很多时候,一个工厂不只是生产一种产品,而是生产一类产品,比如一个体育用品工厂,可以生产篮球、足球、排球等多种产品。此时我们可以把这些相关的产品归纳为一个“产品族”,由同一个工厂来生产,这即是Jungle今天要学习的抽象工厂模式。
用户6557940
2022/07/24
5360
抽象工厂模式——工厂方法的大结局
JS 设计模式之工厂模式(创建型)
有一天我写了个员工信息录入系统,起初这个系统开发阶段用户只有我,想怎么玩怎么玩。 于是在创建我这个唯一的用户的时候,可以这么写:
Leophen
2021/06/10
6100
【C++】设计模式:工厂模式
工厂模式的实现方式有简单工厂模式、工厂方法模式、抽象工厂模式,每个实现方式都存在优和劣。
DevFrank
2024/07/24
2210
【前端设计模式】之工厂模式
工厂模式是一种创建对象的设计模式,它通过使用工厂类来封装对象的创建逻辑,隐藏了具体对象的实例化过程。工厂模式的主要特性包括:
can4hou6joeng4
2023/11/14
3310
深入理解工厂模式:创建可复用的对象实例
简单工厂模式通过一个工厂类来创建所有产品的实例。客户端只需要提供给工厂类一个参数,工厂类根据这个参数决定实例化哪个具体产品类的对象并返回给客户端。
洁洁
2024/01/26
2150
深入理解工厂模式:创建可复用的对象实例
创造对象的艺术——深入理解工厂模式
定义一个工厂类,根据传入的参数的不同返回不同的实例,被创建的实例具有共同的接口或者父类;因为简单工厂模式中创建实例的方法是静态方法,因此又称为静态工厂模式。
码匠er
2024/02/29
1550
创造对象的艺术——深入理解工厂模式
《优化工厂模式:降低对象创建开销的秘籍》
在现代软件开发中,设计模式扮演着至关重要的角色,而工厂模式无疑是其中的明星之一。它就像一座神奇的工厂,负责创建我们所需的对象。然而,如果不加以优化,这座工厂可能会在不经意间消耗大量的资源,尤其是在对象创建开销方面。今天,我们就来深入探讨如何实现高效的工厂模式,避免那些不必要的资源浪费。
程序员阿伟
2024/12/09
1370
为什么建议没事不要随便用工厂模式创建对象?
一般情况下,工厂模式分为三种更加细分的类型:简单工厂、工厂方法和抽象工厂。在这三种细分的工厂模式中,简单工厂、工厂方法原理比较简单,在实际的项目中也比较常用。而抽象工厂的原理稍微复杂点,在实际的项目中相对也不常用。所以,我们今天讲解的重点是前两种工厂模式。对于抽象工厂,稍微了解一下即可。
码农架构
2021/01/14
5890
工厂模式
工厂模式 目录 何为工厂模式 工厂方法与抽象工厂 如何在Java EE中通过@Producers与@Inject注解实现工厂模式 如何创建自定义注解以及通过@Qualifier消除具体实现之间的歧义 工厂模式有两种模式:工厂方法和抽象方法。它们的意图是一样的:提供一个接口,在不指定具体类的情况下创建相关或依赖的一系列对象。 一.何为工厂模式 工厂的目的在于创建对象。创建的逻辑被封装在工厂中,要么提供一个方法来返回新创建的对象(工厂方法模式),要么将对象的创建委托给子类(抽象工厂模式)。 客户端不必考虑接口或
Zephery
2018/03/12
8750
工厂模式
java 工厂模式变形的多种应用
 工厂模式在项目开发中是使用效率非常高的,意思就是说定义一个用于创建对象的接口,让子类去决定实例化哪一个类。
用户5166556
2019/04/16
8650
简单工厂模式、工厂模式、抽象工厂模式比较
设计模式已经经历了很长一段时间的发展,它们提供了软件开发过程中面临的一般问题的最佳解决方案。学习这些模式有助于经验不足的开发人员通过一种简单快捷的方式来学习软件设计。
良知犹存
2021/03/06
1K0
简单工厂模式、工厂模式、抽象工厂模式比较
简单工厂模式
工厂类:提供一个工厂类用于创建各种产品,在工厂类中提供一个创建产品的工厂方法,该方法可以根据所传入参数的不同创建不同的具体产品对象
千羽
2021/12/29
3550
简单工厂模式
设计模式 之 工厂模式
东汉《风俗通》记录了一则神话故事:“开天辟地,未有人民,女娲搏黄土做人”,讲述的内容就是大家非常熟悉的女娲造人的故事。开天辟地之初,大地上并没有生物,只有苍茫大地,纯粹而洁净的自然环境,寂静而又寂寞,于是女娲决定创造一个新物种(即人类)来增加世界的繁荣,怎么制造呢?
Jacob丶
2020/08/19
4860
设计模式之抽象工厂模式(AbstactFactory )
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
海盗船长
2021/12/07
3630
设计模式之抽象工厂模式(AbstactFactory )
相关推荐
​设计模式之单例、工厂、发布订阅者模式
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档