设计模式详解(二):抽象工厂——Abstract Factory

目录导航

  • 抽象工厂及其作用
  • 工厂方法的好处
  • 工厂方法的实现
    • 关系图
    • 实现步骤
  • 工厂方法的适用场景
  • 工厂方法举例

抽象工厂及其作用

工厂方法是一种创建型设计模式。所谓创建型设计模式是说针对创建对象方面的设计模式。在面向对象的编程语言里,我们通过对象间的相互协作,共同完成复杂的业务逻辑,因为对象之间存在着依赖关系。
当对象A依赖对象B时,我们不采取直接创建对象B的方式,即B productB = new B()

public class A {public void bizLogic(){//do something...B b = new B();//do something...}
}

而是在A的父类中定义一个返回B类型对象的方法,通常该方法的返回值是接口类型或者BaseClass类型,允许A的子类覆盖该方法,返回不同的对象类型C,但需满足C extends/implements B。在父类A中,该方法既可以是抽象方法,也可以不定义为抽象方法(返回默认的B类型实例)。

public abstract class A {public void bizLogic(){//do something...B b = createB();//do something...}public abstract B createB();
}

这种创建对象的设计模式称之为工厂方法。为什么叫工厂方法?通常对象被称之产品,而生产产品的工具称之为工厂,由于在这种设计模式中,是一个方法承担工厂的作用,所以称之为工厂方法。

工厂方法的好处

乍一看,似乎我们只是把创建对象B的代码抽取到了一个方法中而已,实际上这种设计模式有着诸多好处。

  • 解耦。避免对象A与被依赖方B的具体实现类强耦合,对于A来说,我只需要一个B类型的实例,并不关心具体实现类,利于程序扩展。
  • 符合单一职责的原则。类的设计原则之一便是单一职责。A的主要职责肯定不是创建B对象,而是依赖B对象完成特定的业务功能。将创建B的代码单独抽离,使得A的职责更加清晰。
  • 符合开闭原则。后续可以引入多个B的子类而不会“惊动”A的代码。

工厂方法的实现

关系图

依赖方A我们称之为Creator,即需要创建产品B的类,被依赖方B称之为Product,即产品。它们的关系图如下:

在这里插入图片描述

实现步骤

  1. 为对象B定义一个统一的接口B_interface或基类B_base_class,并在其中定义对外提供功能的统一接口方法,定义一批B的子类,以实现差异化功能,所有的子类需实现B_interface或继承B_base_class
  2. 在对象A的父类中定义一个返回B对象的方法,返回值类型为B_interfaceB_base_class。该方法可为抽象方法,也可返回默认的B实例,视实际使用需求而定。
  3. 将对象A中直接创建对象B的代码全部替换成定义好的工厂方法。
  4. 定义一批A的子类,在子类中重写工厂方法,返回不同的B实例。

工厂方法的适用场景

  1. 当我们实现业务代码时,无法提前获知所依赖对象的具体类型,这通常发生在顶层设计的时候,此时可以通过工厂方法抽象定义所需的对象。
  2. 我们打包一个库给他人使用时,其中一些业务逻辑,我们无法确定用户是应该使用库里定义好的一些默认组件,还是想使用自己扩展后的组件(继承默认组件),可通过工厂方法解决该问题。
  3. 被依赖的对象可能比较特殊,占用一定的系统资源,所以不能任意创建,可在工厂方法内实现一定的控制逻辑,控制对象的创建过程,避免资源浪费。

工厂方法举例

工厂方法在代码设计中几乎无处不在,这里举一个Android中的例子。我们在创建Fragment时都要继承Fragment基类,并实现onCreateView方法,该方法负责创建一个视图对象,由于基类并不清楚子类会返回一个什么样的视图对象,所以该方法是一个工厂方法,返回值定义为基类View

public class SubFragment extends Fragment {@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {return new SubView(getContext());}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/187155.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SAP SD 创建交货单 报错 VL461 VL248

因为生产环境已经被改好了,无法跟踪 所以换到测试环境重现一把,如何追根究底 对比正常订单发现 计划行 VBEP-LMENG,VBEP-BMENG这两个字段上的值跟 订单数量不一致。 尝试修改2者的数据跟订单数据一致,则可以正常创建交货单 实际原因是&a…

【每日一坑】KiCAD导Gerber 文件

第一,软件版本 第二、操作选择注意点 第三,那个坑。。。 不知道什么原因,这第二个框里会选其他不必要得一些东西,导致最终光绘是废的; 一定切记只选edge.cut就好了。 最后,上Gerber图,还有一点…

机器学习入门(第六天)——支持向量机(升维打击)

Support vector machines 知识树 Knowledge tree 苹果表示重点 间隔:使用了几何间隔,保证w b的度量,感知机则是函数间隔 间隔最大化思想:则是支持向量机的独有,这使得它找到最优超平面 核函数:面试当中可…

防火墙补充NAT

目录 1.iptables保存规则 2.自定义链 3.NAT NAT的实现分为下面类型&#xff1a; SNAT实验操作 DNAT实验操作 1.iptables保存规则 永久保存方法一&#xff1a; iptables -save > /data/iptables_rule //输出重定向备份 iptables -restore < /data/iptables_r…

Windows安装Kafka3.6,单机

Kafka版本&#xff1a;kafka_2.13-3.6.0 Windows10系统 安装与配置 下载 kafka_2.13-3.6.0.tgz 下载并解压Kafka 3.6.0的压缩包到你选择的目录。 Kafka3.6.0下载链接https://kafka.apache.org/downloads 说明&#xff1a;Kafka3.6内置了Zookeeper&#xff0c;使用内置的Zo…

Ps:用好钢笔工具

使用钢笔工具时&#xff0c;应随时注意鼠标指针的形状。 ◆ ◆ ◆ 基本操作方法 1、绘制闭合路径 路径绘制结束时回到起点即可创建闭合路径。 2、绘制开放路径 想结束绘制时&#xff0c;按住 Ctrl 键点击画布空白处&#xff0c;或者&#xff0c;直接按 Esc 键&#xff0c;即可…

传统算法: Pygame 实现快速排序

使用 Pygame 模块实现了快速排序的动画演示。首先,它生成一个包含随机整数的数组,并通过 Pygame 在屏幕上绘制这个数组的条形图。接着,通过快速排序算法对数组进行排序,动画效果可视化每一步的排序过程。在排序的过程中,程序选择一个基准元素(pivot),将数组分成两部分,…

腾讯云手动下发指令到设备-用于设备调试

打开腾讯云API Explorer&#xff0c;Publish Msg https://console.cloud.tencent.com/api/explorer?Productiotcloud&Version2021-04-08&ActionPublishMessagehttps://console.cloud.tencent.com/api/explorer?Productiotcloud&Version2021-04-08&ActionPub…

C#图像处理OpenCV开发指南(CVStar,04)——图片像素访问与多种局部放大效果的实现代码

​​​​​​​ 使用本文代码需要预先设置一点开发环境&#xff0c;请阅读另外一篇博文&#xff1a; C#图像处理OpenCV开发指南&#xff08;CVStar&#xff0c;03&#xff09;——基于.NET 6的图像处理桌面程序开发实践第一步https://blog.csdn.net/beijinghorn/article/deta…

RocketMQ-RocketMQ快速实战及集群原理

一、MQ简介 ​ MQ&#xff1a;MessageQueue&#xff0c;消息队列。是在互联网中使用非常广泛的一系列服务中间件。 这个词可以分两个部分来看&#xff0c;一是Message&#xff1a;消息。消息是在不同进程之间传递的数据。这些进程可以部署在同一台机器上&#xff0c;也可以分布…

element-ui表格滚动效果,el-table滚动条样式重置

项目首页需要展示一个表格滚动区域&#xff0c;特此来记录一下 HTML <div class"table-box" mouseenter"mouseenter" mouseleave"mouseleave"><el-table :data"tableList" border height"400px" v-loading"…

web前端开发简介及门槛、学习路线

1. 什么是web&#xff1f; Web是 world wide web,万维网,广域网,互联网 Web可以理解是网站 2. 什么网站和网页&#xff1f; 网站是由多个网页和其他文件组成的 3. 什么是web的前端和后端&#xff1f; 4.网页的组成&#xff1a; html: 在网页中真实存在的,例如: 文本,输入…

编程之外,生活的美好航程

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

回顾Django的第二天

1.http 1.1http请求协议与响应协议 1.1.1简介 http协议包含由浏览器发送数据到服务器需要遵循的请求协议与服务器发送数据到浏览器需要遵循的请求协议。用于HTTP协议交互的信被为HTTP报文。请求端(客户端)的HTTP报文 做请求报文,响应端(服务器端)的 做响应报文。HTTP报文本身…

使用JAVA语言写一个排队叫号的小程序

以下是一个简单的排队叫号的小程序&#xff0c;使用JAVA语言实现。 import java.util.LinkedList; import java.util.Queue; import java.util.Scanner;public class NumberingSystem {public static void main(String[] args) {Queue<String> queue new LinkedList<…

PCB布线为什么不能走直角或锐角-笔记

PCB布线为什么不能走直角或锐角-笔记 摘要一.PCB走线在直角转弯的地方&#xff0c;信号前后部分相互影响这几个理由我们来一一分析一下传输线的直角带来的寄生电容从阻抗的角度来看直角的尖角产生放电或者电磁辐射走线直角的工艺问题 摘要 有一定熟悉画过PCB板的人或者PCB教学…

Linux常用命令——mv命令

文章目录 1. 简介2. 命令格式3. 主要参数4. 常见用法及示例4.1 移动文件4.2 重命名文件4.3 交互式移动文件4.4 强制移动文件4.5 移动多个文件4.6 使用通配符移动文件 5. 注意事项6. 结论 1. 简介 mv 命令在Linux系统中用于移动文件或目录&#xff0c;同时也可以用于重命名文件…

Ubuntu Server 20.04.6下Anaconda3安装Pytorch

环境 Ubuntu 20.04.6 LTS Anaconda3-2023.09-0-Linux-x86_64.sh conda 23.7.4 Pytorch 1.11.0 安装 先创建一个工作环境&#xff0c;环境名叫lia&#xff1a; conda create -n lia python3.8环境的使用方法如下&#xff1a; conda activate lia # 激活环境 conda deactiv…

Linux:docker的数据管理(6)

数据管理操作*方便查看容器内产生的数据 *多容器间实现数据共享 两种管理方式数据卷 数据卷容器 1.数据卷 数据卷是一个供容器使用的特殊目录&#xff0c;位于容器中&#xff0c;可将宿主机的目录挂载到数据卷上&#xff0c;对数据卷的修改操作立刻可见&#xff0c;并且更新数…

Springboot快速整合kafka

kafka的基本了解 kafka也是 目前常用的消息中间件,支持同步与异步通信,和rabbitmq一样,工作模式大概相同,并且被spingboot整合的后的都是 中间件Template的实列化客户端类 ,消费者监听注解为KafkaListener,和RabbitListener和很相似,这些消息中间件使用过后,发现大致都是相同的…