iOS中的设计模式(四)- 抽象工厂

引言

在软件设计中,创建一个类的对象通常需要客户端知道该类的所有细节。而当需要同时创建一组相关对象时,且这些对象在运行时会根据不同的标准有所变化,这会变得更加复杂。此时,抽象工厂模式能够有效地简化这一过程。

抽象工厂定义了一个用于创建一系列相关或依赖对象的接口,但并不指定具体的实现类。通过这种方式,客户端与具体的工厂和对象之间的耦合度得以降低,使得系统更具扩展性和灵活性。

什么是抽象工厂模式

抽象工厂的定义定义主要有以下两点内容:

  • 抽象工厂模式提供一个接口,用于创建一系列相关或依赖的对象,而不指定它们的具体类。它通常涉及到一组产品(例如,按钮、文本框、滚动条等)和一个工厂(例如,UI 工厂),客户端通过该工厂来获取所需的产品对象。
  • 客户端通过抽象工厂接口来访问产品,而不需要了解具体的产品类和实现细节。这保证了系统的可扩展性和灵活性。

在客户端不知道具体产品实现的情况下,确保产品的一致性和协调性。

  1. AbstractFactory:抽象工厂,定义了一个接口,里面声明了多个方法,这些方法用于创建一组相关的产品。
  2. ConcreteFactory:具体的工厂类,实现了抽象工厂中的方法,负责创建具体的产品。
  3. AbstractProduct:抽象产品类,定义了产品的一般接口。
  4. ConcreteProduct:具体产品类,实现了产品接口,定义了产品的具体行为。

假设我们有一个需求有一组UI需要支持iPhone和iPad但是呢在不同的平台上的按钮和文本框样式是不同的,基于这个场景:

  1. 抽象工厂:UI工厂,提供创建按钮和文本的方法。
  2. 具体工厂:iPhone工厂和iPad工厂,分别创建适合自己平台的UI元素。
  3. 抽象产品:按钮和文本框的接口。
  4. 具体产品:iPhone的按钮,iPhone的文本框,iPad的按钮和iPad的文本框。

抽象工厂与工厂方法

抽象工厂与工厂方法模式在许多方面都非常相似,经常会被人们弄混,搞不清楚应该在什么时候用哪一个。两个模式都用于相同的目的:创建对象而客户端不需要关心返回了什么确切的具体对象。

我们以列表的方式对比一下抽象工厂和工厂方法:

抽象工厂工厂方法
通过对象组合创建抽象产品通过类继承创建抽象产品
创建多系列产品创建一种产品
必须修父类的接口才能支持新的产品子类化创建者并重载工厂方法以创建新产品

在实际使用中,这两种设计模式通常相辅相成,例如抽象工厂定义创建按钮和文本框的方法,工厂方法具体的工厂类通过实现工厂方法来具体生成按钮和文本框。

如何实现抽象工厂模式

我们还是以上面的创建iPhone和iPad中的组件为例,利用抽象工厂模式来帮助我们实现不同平台上UI元素的统一管理和创建。

抽象工厂

首先创建一个抽象工厂UIFactory,定义一个接口声明了创建按钮和文本框的方法。这个接口不会关心具体产品是如何实现的。

protocol UIFactory {func createButton() -> Buttonfunc createTextField() -> TextField
}

具体工厂

每个平台都有自己的具体工厂类,iPhone中的iPhoneFactory以及iPad的iPadFactory,负责创建适合该平台的具体UI元素,按钮和文本框。这些具体的工厂都实现了抽象工厂接口。

class iPhoneFactory: UIFactory {func createButton() -> Button {return iPhoneButton()}func createTextField() -> TextField {return iPhoneTextField()}
}
class iPadFactory: UIFactory {func createButton() -> Button {return iPadButton()}func createTextField() -> TextField {return iPadTextField()}
}

抽象产品

Button和TextField是抽象产品接口,定义了按钮和文本框的行为,这些接口不会关心具体平台的实现,所有具体的按钮和文本都会遵循这个接口。

protocol Button {func render()
}protocol TextField {func render()
}

具体的产品

具体的产品类根据平台的不同,实现了按钮和文本框的不同样式,例如iPhoneButton是为iPhone设计的按钮,iPadButton则是为iPad设计的按钮。

class iPhoneButton: Button {func render() {print("Rendering iPhone-style button")}
}class iPhoneTextField: TextField {func render() {print("Rendering iPhone-style text field")}
}
class iPadButton: Button {func render() {print("Rendering iPad-style button")}
}class iPadTextField: TextField {func render() {print("Rendering iPad-style text field")}
}

客户端使用

客户端使用抽象工厂接口来创建所需的UI元素,而不需要关心具体的产品如何实现。客户端只需要通过工厂接口来获取按钮和文本框,确保一致性和协调性。

class Application {private let factory: UIFactoryinit(factory: UIFactory) {self.factory = factory}func renderUI() {let button = factory.createButton()let textField = factory.createTextField()button.render()textField.render()}
}

在客户端,我们可以根据不同的平台选择不同的工厂类。例如,我们为 iPhone 和 iPad 创建不同的工厂,然后客户端通过工厂来渲染平台特定的 UI 元素。

let iPhoneFactory = iPhoneFactory()
let iPadFactory = iPadFactory()let iosApp = Application(factory: iPhoneFactory)
let ipadApp = Application(factory: iPadFactory)iosApp.renderUI()  // 输出:Rendering iPhone-style button\nRendering iPhone-style text field
ipadApp.renderUI() // 输出:Rendering iPad-style button\nRendering iPad-style text field

结语

在本文中,我们深入探讨了抽象工厂模式及其在创建一组相关对象时的应用场景。通过使用抽象工厂模式,我们能够有效地组织和管理多个相关产品的创建过程,确保不同产品之间的一致性和兼容性,进而提高代码的扩展性和可维护性。

值得注意的是,抽象工厂模式和工厂方法模式在实际开发中通常是相辅相成的。在抽象工厂模式中,工厂方法模式负责具体产品的创建逻辑,确保每个产品的生成遵循一致的接口。通过两者的结合,我们能够灵活地应对不同平台、环境或产品族的需求,减少客户端与具体产品类之间的耦合,从而提高系统的可扩展性和灵活性。

在实际开发中,特别是涉及到跨平台、跨环境的产品设计时,抽象工厂和工厂方法模式无疑是非常有效的工具,它们帮助我们创建出既符合需求又具备高度可维护性的系统。通过恰当地运用这些模式,我们可以使系统在面对需求变化时更加稳健,并提供更好的用户体验。

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

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

相关文章

deeplabv3+街景图片语义分割,无需训练模型,看不懂也没有影响,直接使用,cityscapes数据集_12

目录 1、下载链接1.1、CSDN链接,含权重文件直接使用,建议直接下这个,还不限速。1.2 Github链接:2、下载代码,下载预训练好的权重3、预测代码4、像素提取,或者说类别提取5、文档部分内容截图6、其他数据处理…

Java 基于 SpringBoot 的校园外卖点餐平台微信小程序(附源码,部署,文档)

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

Jetson Xavier NX 安装 CUDA 支持的 PyTorch 指南

本指南将帮助开发者完成在 Jetson Xavier NX 上安装 CUDA 支持的 PyTorch。 安装方法 在 Jetson 上安装 Pytorch 只有两种方法。 一种是直接安装他人已经编译好的 PyTorch 轮子;一种是自己从头开始开始构建 PyTorch 轮子并且安装。 使用轮子安装 可以从我的 Gi…

怎样使用树莓派自己搭建一套ADS-B信号接收系统

0 我们知道,ADS-B全称广播式自动相关监视系统,其实就是飞机发出的广播信号,用明码来对外发送自己的位置、高度、速度、航向等信息,是公开信息。连续接收到一架飞机发出的ADS-B信息后,可以通过其坐标点来描绘出飞机的航…

KETTLE-SAP抽数报错RFC_ERROR_SYSTEM_FAILURE

KETTLE调SAP 合并ECCS相关的函数时报错 2025/01/23 17:56:02 - SAP input.0 - ERROR (version 8.2.0.0-342, build 8.2.0.0-342 from 2018-11-14 10.30.55 by buildguy) : Unexpected error 2025/01/23 17:56:02 - SAP input.0 - ERROR (version 8.2.0.0-342, build 8.2.0.0-3…

困境如雾路难寻,心若清明步自轻---2024年创作回顾

文章目录 前言博客创作回顾第一次被催更第一次获得证书周榜几篇博客互动最多的最满意的引发思考的 写博契机 碎碎念时也运也部分经验 尾 前言 今年三月份,我已写下一篇《近一年多个人总结》,当时还没开始写博客。四月份写博后,就顺手将那篇总…

2024 行远自迩,笃行不怠

2024年是充满变化与挑战的一年,我的开发方向经历了从智能驾驶到工业智能检测,再到机器人感知交互与决策的不断演进。 这一年,我不断拓宽技术视野,深入探索不同领域的技术挑战和应用场景。 最初,我希望专注于单一领域…

【Linux】19.基础IO(1)

文章目录 1. 基础IO1. 文件2. 回顾C文件接口2.1 hello.c写文件2.2 hello.c读文件2.3 接口介绍 3. open函数返回值3.1 文件描述符fd3.2 文件描述符的分配规则3.2.1 代码13.2.2 代码23.2.3 重定向底层原理代码示例3.2.4 使用 dup2 系统调用 3.3 缓冲区刷新问题3.4 FILE 1. 基础IO…

客户案例:向导ERP与金蝶云星空集成方案

一、客户背景 该客户公司主要致力于黄金、铂金、金镶玉首饰的研发设计、生产加工、批发及直营加盟业务。公司总部占地面积目前已达6000多平方米,拥有标准生产厂房和现代化生产设施,拥有一支完善的企业管理团队和专业技工队伍。 该企业目前同时采用向导 E…

RabbitMQ 在实际应用时要注意的问题

1. 幂等性保障 1.1 幂等性介绍 幂等性是数学和计算机科学中某些运算的性质,它们可以被多次应⽤,⽽不会改变初始应⽤的结果. 应⽤程序的幂等性介绍 在应⽤程序中,幂等性就是指对⼀个系统进⾏重复调⽤(相同参数),不论请求多少次,这些请求对系统的影响都是相同的效果. ⽐如数据库…

Cesium特效——城市白模的科技动效的各种效果

最终效果图如下: 实现方法: 步骤一:使用cesiumlib生产白模,格式为3dtiles 注意事项:采用其他方式可能导致白模贴地,从而导致不能实现该效果,例如把步骤二的服务地址改为Cesium Sandcastle 里的…

4_高并发内存池项目_高并发池内存释放设计_ThreadCache/CentralCache/PageCache回收并释放内存

高并发池内存释放设计 对各缓存层释放内存的设计,不仅仅是从上一层回收内存,还包括对回收回来的内存怎样处理更有利于下一缓存层的回收,提高效率。 高并发内存池内存释放步骤: 线程对象释放内存 ↓↓↓↓↓ ThreadCache(1.回收线…

centos9编译安装opensips 二【进阶篇-定制目录+模块】推荐

环境:centos9 last opensips -V version: opensips 3.6.0-dev (x86_64/linux) flags: STATS: On, DISABLE_NAGLE, USE_MCAST, SHM_MMAP, PKG_MALLOC, Q_MALLOC, F_MALLOC, HP_MALLOC, DBG_MALLOC, CC_O0, FAST_LOCK-ADAPTIVE_WAIT ADAPTIVE_WAIT_LOOPS1024, MAX_RE…

分子动力学模拟里的术语:leap-frog蛙跳算法和‌Velocity-Verlet算法

分子动力学模拟(Molecular Dynamics Simulation,简称MD)是一种基于经典力学原理的计算物理方法,用于模拟原子和分子在给定时间内的运动和相互作用‌。以下是关于分子动力学模拟的一些核心术语和概念: ‌定义系统‌&am…

iOS开发设计模式篇第二篇MVVM设计模式

目录 一、什么是MVVM 二、MVVM 的主要特点 三、MVVM 的架构图 四、MVVM 与其他模式的对比 五、如何在iOS中实现MVVM 1.Model 2.ViewModel 3.View (ViewController) 4.双向绑定 5.文中完整的代码地址 六、MVVM 的优缺点 1.优点 2.缺点 七、MVVM 的应用场景 八、结…

【C++图论 并集查找】2492. 两个城市间路径的最小分数|1679

本文涉及知识点 C图论 并集查找(并查集) LeetCode2492. 两个城市间路径的最小分数 给你一个正整数 n ,表示总共有 n 个城市,城市从 1 到 n 编号。给你一个二维数组 roads ,其中 roads[i] [ai, bi, distancei] 表示城市 ai 和 …

Linux应用编程(五)USB应用开发-libusb库

一、基础知识 1. USB接口是什么? USB接口(Universal Serial Bus)是一种通用串行总线,广泛使用的接口标准,主要用于连接计算机与外围设备(如键盘、鼠标、打印机、存储设备等)之间的数据传输和电…

⽤vector数组实现树的存储(孩⼦表示法)c++

在我们遇到的算法题中, ⼀般给出的树结构都是有编号的,这样会简化我们之后存储树的操作 ,⼀般提供两个信息; 结点的个数 n;n-1条x结点与y结点相连的边 题⽬描述: ⼀共9个结点셈 1号结点为根节点,接下来8⾏&#xff…

一个基于Python+Appium的手机自动化项目~~

本项目通过PythonAppium实现了抖音手机店铺的自动化询价,可以直接输出excel,并带有详细的LOG输出。 1.excel输出效果: 2. LOG效果: 具体文件内容见GitCode: 项目首页 - douyingoods:一个基于Pythonappium的手机自动化项目,实现了…

基于微信小程序的童装商城的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…