设计模式系列(二)—— 工厂方法&抽象工厂

工厂方法

定义与类型

  • 定义:定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类;工厂方法让类的实例化推迟到子类中进行
  • 类型:创建型

在我们创建对象的过程中,往往会是一个非常复杂的过程,同时创建对象也有可能会导致大量重复的代码;而工厂模式通过单独的定义一个创建对象的方法来解决这个问题,由子类实现这个方法,从而来创建具体类型的对象

适用场景

  • 创建对象需要大量重复的代码
  • 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
  • 一个类通过其子类来指定创建哪个对象

客户端不需要知道具体产品类的类名,只需要知道所对应的工厂就可以;具体的产品对象都是由具体的工厂来进行创建,客户端只需要知道我所需要的产品在哪个工厂里即可

优点与缺点

优点:

  • 用户只需要关心所需产品对应的工厂,无须关心创建细节
  • 加入新产品符合开闭原则,提高可扩展性

缺点:

  • 类的个数容易过多,增加复杂度
  • 增加了系统的抽象性和理解难度(如果需要动态创建,还会使用反射这种技术)

coding

具体代码见:factorymethod

VideoFactory使用abstract的原因:

  • 在实际的业务场景中,在该类中某些内容可能是已知的,因此使用abstract进行修饰
  • 如果都是未知的话,可以使用interface接口进行修饰

UML类图:
在这里插入图片描述

  • VideoFactory只定义规范、契约,并不决定产生哪一种类的视频
    VideoFactory把创建具体某个视频的职责已经交由具体的子类来实现了
  • 产生哪一类的视频,完成交由子类来实现
  • 对于应用层(Test)来说,进行修改的时候就会显得比较简单,只需要修改具体的实现类即可

jdk源码解析

Collection

java.util.Collection可以理解为一个抽象工厂(抽象工厂具体下章节细说):
在这里插入图片描述
其中的Iterator iterator()可以理解为工厂方法

在这里插入图片描述
我们可以认为ArrayList在这里就是一个具体的实现工厂,实现了工厂方法iterator

在这里插入图片描述
而具体的抽像产品就是Iterator这个接口,
而实际生产出来的产品即ArrayList中的Itr类,继承了Iterator接口

对应关系如下:

源码中的类案例中的类
CollectionVideoFactory
ArrayListJavaVideoFactory
IteratorVideo
ItrJavaVideo
URLStreamHandlerFactory

URLStreamHandlerFactory在jdk中主要解决url协议扩展进行使用的,protocol决定了交互规范

对应关系如下:

源码中的类案例中的类
URLStreamHandleFactoryVideoFactory
URLStreamHandlerVideo
HandlerJavaVideo
Launcher中的Factory类JavaVideoFactory

抽象工厂

定义与类型

  • 定义:抽象工厂模式提供了一个创建一系列相关或相互依赖对象的接口
  • 无须指定它们具体的类
  • 类型:创建型

抽象工厂可以将一组具有同一主题单独的工厂封装起来
客户端程序需要创建抽象工厂的具体实现,然后使用抽象工厂作为接口来创建这一主题的具体对象;在使用的过程中是不需要知道和关心从这些内部的工厂方法中获得对象的具体类型,因为客户端程序仅使用这些对象的通用接口
抽象工厂模式将一组对象的实现细节与对它们的使用分离开来

适用场景

  • 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
  • 强调一系列相关的产品对象(属于同一产品族),一起使用创建对象需要大量重复的代码
  • 提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现

使用抽象工厂模式,可以在工厂进行变化的时候,不用修改使用工厂的客户端代码

优点与缺点

优点:

  • 具体产品在应用层代码隔离,无须关心创建细节
  • 将一个系列的产品族统一到一起进行创建

缺点:

  • 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口
  • 增加了系统的抽象性和理解难度

产品等级与产品族

在这里插入图片描述
在这里插入图片描述
产品族都是由同一个产品生产的,位于不同的产品等级结构

  • 工厂方法模式针对的是产品等级结构
  • 抽象工厂模式针对的是产品族

coding

场景:
现在每个课程不仅需要有视频,还需要有手记,如果按照工厂方法的方式来进行扩展的话,就需要我们去创建前端的手记类、java的手记类、Python的手记类,以及前端的手记工厂、java的手记工厂、Python的手记工厂,同时还需要创建手记的抽象类、手记的工厂类
如果我们的业务场景发生了比较大的扩展,很容易发生类爆炸的情况,建立很多的类,会显得耦合度太高
因此引入产品族的概念

代码见:abstractfactory

UML类图:
在这里插入图片描述
对比抽象工厂和工厂方法,可以发现我们在使用抽象工厂时并没有去声明视频工厂、手记工厂,而是声明了一个将两者组合在一起的JavaCourseFactory
从代码的实现层面来看,抽象工厂具备如下优点:

  • 应用层代码与具体的video、article都是解耦的
  • 应用层代码不和具体的产品发生依赖,只和具体的工厂发生关系
  • 从具体的产品族工厂中取出来的肯定属于同一产品族
  • 扩展性好,新增产品族,只需要增加XXCourseFactory、XXVideo、XXArticle即可,无需修改现有系统

缺点:

  • 新增产品等级,会比较麻烦;需要对原有的系统进行比较大的修改,既需要修改具体的类实现,又需要新增类

区别:

  • 抽象工厂关注产品族;抽象工厂可以帮助我们针对抽象编程,而不是针对具体的类进行编程
  • 工厂方法关注产品等级结构

jdk&mybatis源码解析

jdk

java.sql.Connection这个接口类即抽象工厂的一个体现,其中返回的都是同一个产品族:mysql、sql server等等

mybatis

在这里插入图片描述
SqlSessionFactory等同于案例中的CourseFactory

在这里插入图片描述
我们查看SqlSessionFactory的具体实现DefaultSqlSessionFactory中的openSessionFromDataSource方法就可以发现与案例中的XXXCourseFactory的实现是一样的,对应关系如下:

源码中的类案例中的类
SqlSessionVideo、Article
SqlSessionFactoryCourseFactory
DefaultSqlSessionJavaVideo、JavaArticle
DefaultSqlSessionFactoryJavaCourseFactory
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这三种工厂模式都是用来创建对象的,但它们的实现方式略有不同: 1. 简单工厂模式:由一个工厂类根据传入的参数,决定创建并返回哪种产品类的实例。它的优点在于工厂类集中了所有产品的创建逻辑,客户端只需要知道工厂类即可,不需要关心具体的产品类。但缺点是当需要添加新的产品时,需要修改工厂类的代码,违反了开闭原则。 2. 工厂方法模式:将工厂类抽象成接口或抽象类,每个具体的产品类都对应一个具体的工厂类。客户端需要知道具体的工厂类和产品类,但每个工厂类只负责创建对应的产品,符合单一职责原则。添加新的产品时,只需要添加一个新的具体产品类和它对应的工厂类即可,不需要修改已有代码。 3. 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。每个具体的工厂类可以创建一组相关的产品类。客户端需要知道具体的抽象工厂类和抽象产品类,但不需要知道具体的实现类。添加新的产品族时,需要添加一个新的抽象产品类和对应的具体产品类,以及一个新的抽象工厂类和对应的具体工厂类,不需要修改已有代码。 简单来说,简单工厂模式是在一个工厂类中创建所有产品;工厂方法模式是将工厂类抽象成接口或抽象类,每个具体产品对应一个具体工厂类;抽象工厂模式是提供一个抽象工厂类,每个具体工厂类可以创建一组相关的产品。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值