前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式(一)工厂模式

设计模式(一)工厂模式

作者头像
lomtom
发布2021-10-27 14:59:31
4740
发布2021-10-27 14:59:31
举报
文章被收录于专栏:博思奥园

你能get到的知识点

1.工厂模式的介绍2.工厂模式通过代码的实现

本文首发于CSDN,作者:lomtom 原文链接:https://blog.csdn.net/qq_41929184/article/details/118366444 你的支持就是我最大的动力。

1 简介

创建者模式模式提供创建对象的机制, 能够提升已有代码的灵活性和可复⽤性。

创建者模式包括:工厂方法、抽象工厂、生成器、原型、单例,这5类。

这一节主要讲述工厂模式:

1.简单工厂模式

•定义:定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类•核心就是用一个类来负责控制创建实例的过程。• 适用场景:

1.工厂类负责创建对的对象比较少,因为不会造成工厂方法中的业务逻辑过于复杂2.客户端只知道传入工厂类的参数,对如何创建对象不关心

2.工厂模式

•定义:在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型。•适用场景:

1.当你在编写代码的过程中, 如果无法预知对象确切类别及其依赖关系时, 可使用工厂方法。2.如果你希望用户能扩展你软件库或框架的内部组件, 可使用工厂方法。3.如果你希望复用现有对象来节省系统资源, 而不是每次都重新创建对象, 可使用工厂方法。

2 场景引入

2.1 初始场景

场景实例:小葛参加Jd平台的抽奖活动,而此时只有一种奖品奖品是1000元购物卡一张。为了更好的模拟,假设没有不抽中的情况

那么我们来模拟小葛参加抽奖的这个过程,代码如下

目录结构:

代码语言:javascript
复制

功能

AwardService

模拟发放1000元购物卡奖品

Test

测试

实现发放奖品类

代码语言:javascript
复制

测试验证

代码语言:javascript
复制

模拟十次抽奖,结果:

代码语言:javascript
复制

2.2 增加需求

场景实例:小葛参加Jd平台的抽奖活动,平台为了增加奖品的多样性,在原来只有一种奖品的情况下新增两种奖品,分别为Iphone12 和3000元现金

如果代码其余部分与现有类已经存在耦合关系, 那么向程序中添加新类其实并没有那么容易。

下面我们不使用设计模式的情况下,我们一般还用if...else...来实现需求,通过一个标志awardNumber来表示小葛获得的奖品类型。

工程结构

代码语言:javascript
复制

功能

AwardService

模拟发放三种奖品

Test

测试

实现发放奖品类 通过一个变量awardNumber来表明小葛抽中哪一个奖品,并且发放相应的奖品。

代码语言:javascript
复制

测试验证

代码语言:javascript
复制

这里使用0 - 2的随机数来代表小葛抽中了具体哪种商品,测试结果

代码语言:javascript
复制

小结: 使用if...else...非常直接的实现了业务需求,如果只从产品需求来说,使用if...else...确实满足了需求,并且也能缩短上线的时间,但是这样简单粗暴的方式,在一定程度上给我们带来了便捷,但是也种下了一定的隐患

1.当产品后续迭代时,需要引入更多的需求时,代码将变得臃肿;2.并且也在一定程度上提高的重构代码的难度与成本;3.一旦出现问题,测试所花的时间也会相应的增加。

那么,问题来了,我们怎么使用工厂模式来进行优化呢?

3 运用到简单工厂模式

使用简单工厂模式步骤:

1.创建抽象产品接口

2.创建具体产品类 3.创建工厂类 4.客户端调用工厂类

场景实例:小葛参加Jd平台的抽奖活动,平台为了增加奖品的多样性,在原来只有一种奖品的情况下新增两种奖品,分别为Iphone12 和3000元现金

对上面使用if...else...的代码进行抽取,将其每个奖品发放的功能相应的抽取出来,然后使用一个工厂来决定发放哪一个奖品。

工程结构

代码语言:javascript
复制

我们创建一个发放奖品的接口(AwardService)和发放奖品接口的实现类,并且使用AwardFactory来获取AwardService对象,从而实现奖品的发放。

功能

AwardService

奖品方法接口

CashAwardService

模拟发放现金

IphoneAwardService

模拟发放手机

MallCardAwardService

模拟发放购物卡

AwardFactory

发放奖品工厂

Test

测试

实现发放奖品接口与其实现类 首先创建发放奖品的接口。其次创建具体的发放奖品的实现类。

代码语言:javascript
复制

工厂类 使用一个变量awardNumber来代表小葛是抽中了哪一个奖品,然后来决定具体实现哪一个实现类。

代码语言:javascript
复制

测试验证 用test来模拟客户端发起请求。

代码语言:javascript
复制

结果:

代码语言:javascript
复制

优点:简单工厂模式分离产品的创建者和消费者,有利于软件系统结构的优化,消费者的逻辑较为复杂时,这样的代码风格能够让我们对其功能一目了然; 缺点:但是由于一切逻辑都集中在一个工厂类中,导致了没有很高的内聚性,同时也违背了“开放封闭原则”。也就是说我需要增加一个其他的奖品,则需要修改工厂类,重新进行编译。

4 运用到工厂模式

使用简单工厂模式步骤:

1.创建抽象产品接口2.创建具体产品类实现产品接口3.创建工厂(具体创建者)接口4.创建具体产品工厂类实现该工厂接口5.创建工厂类(抽象创建者,可以说是一个调度中心)6.客户端调用工厂类

小疑问?具体创建者与抽象创建者是什么东西? 在本实例中,因为这里有两种类型的工厂,AwardFactory 来实现具体需要创建的产品(来发放需要发放的产品),所以这个工厂叫做具体的创建者,而FactoryFactory并没有参与到产品的创建,而是将产品的创建延迟到AwardFactory来进行创建,所以FactoryFactory被称为抽象的创建者。

场景实例:小葛参加Jd平台的抽奖活动,平台为了增加奖品的多样性,在原来只有一种奖品的情况下新增两种奖品,分别为Iphone12 和3000元现金

工程结构

代码语言:javascript
复制

首先第一步:让所有产品都遵循同一接口。

代码语言:javascript
复制

其次,创建工厂接口(具体创建者),然后创建具体产品的工厂类实现工厂接口(一个工厂只负责生产一个产品,做到专职)

代码语言:javascript
复制

最后,创建抽象创建者工厂,工厂方法中添加临时参数来控制返回的需要发放奖品的类型。

代码语言:javascript
复制

测试验证

代码语言:javascript
复制

结果

代码语言:javascript
复制

从结果中我们可以看出,我们使用工厂模式同样到达了预期效果,相对于最开始使用if...else...来实现,

1.其更满足设计模式中的单一职责原则开闭原则,我们每一种奖品的发放都由相应的类来进行控制,以及在后续进行扩展的时候,我们能够更加方便的进行扩展。2.其代码可以在一定程度上避免创建者与产品的解耦

当然,面对非常复杂的业务,仅仅使用工厂模式远远是不够的,还需要配合其他的设计模式来进行使用。而对于特别简单的业务,使用工厂模式往往会增加系统的复杂性,具体使用场景还是根据当前的业务来。

5 工厂模式在源码的应用:

1.jdk 的Integer的valueOf方法(静态工厂方法)

代码语言:javascript
复制

JDK在1.5中添加的一项新特性,把-128~127的数字缓存起来了。所以这个范围内的自动装箱的数字都会从缓存中获取,返回同一个数字。这样的好处就是提升性能和节省内存。

2.Mybatis数据源[1](工厂 + 代理)3.Dubbo - Registry提供服务的注册[2] (工厂 + 模板)

References

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-09-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 博思奥园 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 你能get到的知识点
  • 1 简介
  • 2 场景引入
    • 2.1 初始场景
      • 2.2 增加需求
      • 3 运用到简单工厂模式
      • 4 运用到工厂模式
      • 5 工厂模式在源码的应用:
        • References
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档