当前位置: 首页 > news >正文

iOS--工厂设计模式

iOS--工厂设计模式

  • 设计模式的概念和意义
    • 类族模式
      • UIButton作为类族模式的例子
      • 总结
  • 三种工厂设计模式
    • 简单工厂模式(Simple Factory Pattern):
      • 代码实例
    • 工厂方法模式(Factory Method Pattern):
      • 代码实例
    • 抽象工厂模式(
      • 代码实例

设计模式的概念和意义

设计模式(Design Patterns)是一套被反复使用、代码设计经验的总结,一般与编程语言无关,是一套比较成熟的编程思想。它主要解决的是在软件设计中反复出现的问题,并提供了一种解决方案。这些方案是在长期软件开发实践中逐步形成的,旨在提高代码的可重用性、可维护性和可扩展性。
在iOS开发中,设计模式通常与面向对象编程(OOP)的概念相结合,通过类和对象来描述问题域中的事物及其关系。设计模式将最佳实践封装成可复用的代码片段,使开发者能够更快速、更高效地构建高质量的应用程序。

设计模式的意义

  • 代码重用性:设计模式提供了一种标准化的方式来组织代码,使得相同的解决方案可以在不同的项目中被重用。这减少了开发人员的工作量,提高了代码的质量。

  • 提高代码可读性:设计模式遵循一定的命名和结构规范,使得代码更加清晰易懂。其他开发者可以更容易地理解代码的目的和功能,从而加快项目的开发进度。

  • 保证代码可靠性:设计模式经过长期实践的检验,已经被证明是有效的解决方案。使用设计模式可以降低代码出错的可能性,提高应用程序的稳定性。

  • 降低维护成本:设计模式使得代码结构更加清晰,易于维护和扩展。当需要修改或添加新功能时,开发人员可以更容易地找到相关的代码并进行修改。

  • 促进团队协作:设计模式为开发人员提供了一种共同的语言和框架,使得团队成员之间可以更容易地交流和协作。这有助于提高项目的整体质量和效率。

类族模式

在之前的学习中,我们了解到了类族模式;这里的工厂设计模式和类族模式很像 ;

UIButton作为类族模式的例子

  1. 抽象基类:UIButton是抽象基类,它定义了按钮的基本属性和行为。开发者通常不会直接创建UIButton的实例,而是通过调用其类方法来创建特定类型的按钮实例。

  2. 具体子类:虽然开发者无法直接访问或看到UIButton的具体子类,但系统框架中确实存在多个私有子类来实现不同类型的按钮。这些子类根据按钮的类型(如系统按钮、自定义按钮等)和样式(如普通按钮、高亮按钮、禁用按钮等)进行不同的绘制和行为处理。

  3. 创建按钮实例:
    开发者通过调用UIButton的类方法(如buttonWithType:)来创建按钮实例。该方法根据传入的类型参数(如UIButtonTypeSystem、UIButtonTypeRoundedRect等)返回不同子类的实例。

  4. 在下面的代码中,我们调用buttonWithType:方法并传入UIButtonTypeSystem作为参数来创建一个系统类型的按钮。然后,我们设置按钮的标题、添加点击事件的处理方法,并将其添加到视图中。

UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];  
[button setTitle:@"Click Me" forState:UIControlStateNormal];  
[button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];  
[self.view addSubview:button];
  1. 隐藏实现细节
    作为开发者,我们无需关心UIButton背后具体是由哪个子类实现的。我们只需要使用UIButton提供的公共接口来设置按钮的属性、添加事件处理方法等。系统框架会根据我们的需求自动选择并创建合适的子类实例。

总结

通过类族模式,UIButton能够隐藏其背后的实现细节,提供统一的公共接口供开发者使用。这简化了开发过程,提高了代码的可读性和可维护性。同时,由于系统框架内部可以根据需要动态选择并创建不同的子类实例,因此也提高了代码的灵活性和可扩展性。

三种工厂设计模式

工厂设计模式主要分为以下三种,每种模式都有其特定的应用场景和优缺点:

简单工厂模式(Simple Factory Pattern):

  • 又称为静态工厂方法模式(Static Factory Method Pattern)。
  • 通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。不过其实可以使用协议;
  • 特点:代码简单,虽有多处if分支且违背开闭原则(对扩展开放,对修改关闭),但扩展性和可读性尚可,这样的代码在大多数情况下并无问题。

代码实例

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

上面创建了一个专门的工厂类来创建产品类,来实现隐藏产品类的创建实现,其产品类都遵循operation协议并展示接口,但最终只有工厂类的类方法暴露在外被人调用 ;

在这里插入图片描述

工厂方法模式(Factory Method Pattern):

  • 定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。
  • 核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口。
  • 特点:通过不同的工厂创建不同的对象,每个对象都有自己的工厂来创建。当对象的创建过程比较复杂,需要组合其他类对象做各种初始化操作时,推荐使用工厂方法模式。

代码实例

在这里插入图片描述

创建一个抽象类ShapeFactory作为核心工厂类,该类遵循CreateFactory协议中声明的接口 ;

#import <Foundation/Foundation.h>
#import "CreateFactory.h"
NS_ASSUME_NONNULL_BEGIN@interface ShapeFactory : NSObject <CreateFactory>@endNS_ASSUME_NONNULL_END

在这里插入图片描述

由该抽象工厂类调用接口创建具体的产品工厂类 ;再由具体的产品工厂类创建产品对象 ;

#import "ShapeFactory.h"NS_ASSUME_NONNULL_BEGIN@interface Factory01 : ShapeFactory
- (id <Shape>)createProduct ;
@endNS_ASSUME_NONNULL_END
#import "Factory01.h"
#import "Product01.h"
@implementation Factory01
- (id <Shape> )createProduct {return [[Product01 alloc] init];
}
@end

抽象工厂模式(

Abstract Factory Pattern):

  • 是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。
  • 提供了一种创建对象的最佳方式,当需要创建一组相关或互相依赖的对象时,抽象工厂模式非常有用。
  • 特点:工厂方法模式中虽然解决了简单工厂模式中需要修改已有代码的问题,但当具体的产品种类变多时,就会出现大量的和他们对应的具体工厂类对象。抽象工厂模式是工厂方法模式的升级版,它用来创建一组相关或者互相依赖的对象。

代码实例

首先定义两个产品类 ;遵循并实现一个display接口 ;

#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@protocol display <NSObject>
- (void)display ;
@endNS_ASSUME_NONNULL_END
#import <Foundation/Foundation.h>
#import "display.h"
NS_ASSUME_NONNULL_BEGIN@interface FstButton : NSObject <display>
- (void)display ;
@endNS_ASSUME_NONNULL_END//
#import "FstButton.h"@implementation FstButton
- (void)display {NSLog(@"1") ;
}
@end
#import <Foundation/Foundation.h>
#import "display.h"
NS_ASSUME_NONNULL_BEGIN@interface SedButton : NSObject <display>
- (void)display ;
@endNS_ASSUME_NONNULL_END//
#import "SedButton.h"@implementation SedButton
- (void)display  {NSLog(@"2") ;
}
@end

定义两个产品的具体工厂类;它们遵循并实现协议中定义的createProduct接口 ;

#import <Foundation/Foundation.h>
#import "display.h"
NS_ASSUME_NONNULL_BEGIN@protocol CreateProduct <NSObject>
- (id <display>) createProduct ;
@endNS_ASSUME_NONNULL_END
#import <Foundation/Foundation.h>
#import "CreateProduct.h"
#import "FstButton.h"
NS_ASSUME_NONNULL_BEGIN@interface FstFactory : NSObject <CreateProduct>
- (id <display>) createProduct ;
@endNS_ASSUME_NONNULL_END
//
#import "FstFactory.h"@implementation FstFactory
- (id <display>) createProduct {return [[FstButton alloc] init];
}
@end
#import <Foundation/Foundation.h>
#import "CreateProduct.h"
#import "SedButton.h"
NS_ASSUME_NONNULL_BEGIN@interface SedFactory : NSObject <CreateProduct>
- (id <display>) createProduct ;
@endNS_ASSUME_NONNULL_END//
#import "SedFactory.h"@implementation SedFactory
- (id <display>)createProduct {return [[SedButton alloc] init];
}
@end

定义一个超级工厂类来创建具体工厂类

#import <Foundation/Foundation.h>
#import "FstFactory.h"
#import "SedFactory.h"NS_ASSUME_NONNULL_BEGIN@interface BaseFactory : NSObject
+ (id <CreateProduct>) createFactory : (NSString*) type ;
@endNS_ASSUME_NONNULL_END//
#import "BaseFactory.h"@implementation BaseFactory
+ (id <CreateProduct>) createFactory:(NSString *)type {if ([type isEqualToString:@"1"]) {return [[FstFactory alloc] init] ;} else if ([type isEqualToString:@"2"]) {return [[SedFactory alloc] init] ;} else {return nil;}
}
@end

在这里插入图片描述

相关文章:

iOS--工厂设计模式

iOS--工厂设计模式 设计模式的概念和意义类族模式UIButton作为类族模式的例子总结 三种工厂设计模式简单工厂模式&#xff08;Simple Factory Pattern&#xff09;&#xff1a;代码实例 工厂方法模式&#xff08;Factory Method Pattern&#xff09;&#xff1a;代码实例 抽象工…...

[Python]用Qt6和Pillow实现截图小工具

本文章主要讲述的内容是&#xff0c;使用python语言借助PyQt6和Pillow库进行简单截图工具的开发&#xff0c;含义一个简单的范围裁剪和软件界面。 主要解决的问题是&#xff0c;在高DPI显示屏下&#xff0c;坐标点的偏差导致QWidget显示图片不全、剪裁范围偏差问题。 适合有一点…...

Podman和Docker的区别

Podman 和 Docker 都是用于容器化的工具&#xff0c;但它们在架构、安全性、容器编排以及一些设计理念上有显著的区别&#xff1a; 架构设计: Docker 使用客户端-服务器&#xff08;C/S&#xff09;架构&#xff0c;包含一个名为 dockerd 的守护进程&#xff0c;该进程以 root …...

Go微服务: 分布式Cap定理和Base理论

分布式中的Cap定理 CAP理论 C: 一致性&#xff0c;是站在分布式的角度&#xff0c;要么读取到数据&#xff0c;要么读取失败&#xff0c;比如数据库主从&#xff0c;同步时的时候加锁&#xff0c;同步完成才能读到同步的数据&#xff0c;同步完成&#xff0c;才返回数据给程序&…...

Mysql学习(四)——SQL通用语法之DQL

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 DQLDQL-语法基本查询条件查询聚合函数分组查询排序查询分页查询 DQL DQL数据查询语言&#xff0c;用来查询数据库中表的记录。 DQL-语法 select 字段列表 from 表…...

【ARFoundation自学05】人脸追踪(AR Face manager)实现

1. 修改摄像机朝向渲染方式-选中user 这个方式就会调用前置摄像头 2 创建 AR Session、XR Origin&#xff0c;然后在XR Origin上面添加组件 注意&#xff1a;XR Origin 老版本仍然叫 AR Session Origin 接下来在XR Origin上面添加AR Face Manager组件&#xff0c;如下图&am…...

Vulnhub-DC-2

靶机IP:192.168.20.135 网络有问题的可以看下搭建Vulnhub靶机网络问题(获取不到IP) kaliIP:192.168.20.128 扫描靶机端口及服务版本 发现开放了80和7744端口 并且是wordpress建站 dirsearch扫描目录 访问前端界面&#xff0c;发现存在重定向 在hosts文件中增加192.168.2…...

VNC server ubuntu20 配置

介绍 最近想使用实验室的4卡服务器跑一些深度学习实验&#xff0c;因为跑的是三维建图实验&#xff0c;需要配上可视化界面&#xff0c;本来自带的IPMI可以可视化&#xff0c;但分辨率固定在640*480&#xff0c;看起来很别扭&#xff0c;就捣鼓服务器远程可视化访问了两天&…...

c++--priority_queue和仿函数

目录 1.priority_queue 实现&#xff1a; 2.仿函数 priority_queue仿函数 实现代码 1.priority_queue 优先队列是一种容器适配器&#xff0c;根据严格的弱排序标准&#xff0c;它的第一个元素总是它所包含的元素中最大的&#xff0c;其实就是个堆&#xff0c;默认是大根堆。…...

Harmony os Next——关系型数据库relationalStore.RdbStore的使用

Harmony os Next——关系型数据库relationalStore.RdbStore的使用 描述数据库的使用建表定义表信息创建数据库表 创建数据库操作对象增更新查询删数据库的初始化 描述 本文通过存储一个简单的用户信息到数据库中为例&#xff0c;进行阐述relationalStore.RdbStore数据库的CRUD…...

快手直播限流怎么办?

直播限流怎么办&#xff1f;这期把直播间限流的所有原因都讲得明明白白&#xff0c;如果你直播间昨天还播的好好的&#xff0c;今天突然间贴地飞行&#xff0c;按照这个思路框架去排查&#xff0c;准没问题。 第一件事情肯定是排查一下评分问题&#xff0c; 信用分、口碑分、…...

【MySQL】数据库入门基础

文章目录 一、数据库的概念1. 什么是数据库2. 主流数据库3. mysql和mysqld的区别 二、MySQL基本使用1. 安装MySQL服务器在 CentOS 上安装 MySQL 服务器在 Ubuntu 上安装 MySQL 服务器验证安装 2. 服务器管理启动服务器查看服务器连接服务器停止服务器重启服务器 3. 服务器&…...

cannot allocate memory in static TLS block

如果不是内存太小&#xff0c;那是不是因为glibc太旧呢&#xff1f; 考虑 glibc 2.22 以后的版本。 glibc-2.22 中加入了如下commit&#xff1a;f8aeae347377f3dfa8cbadde057adf1827fb1d44 https://sourceware.org/git/?pglibc.git;acommit;hf8aeae347377f3dfa8cbadde057adf1…...

Leetcode 654:最大二叉树

给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。递归地在最大值 左边 的 子数组前缀上 构建左子树。递归地在最大值 右边 的 子数组后缀上 构建右子树。 返回 nums 构建的 最大二叉树…...

uniapp小程序src引用服务器图片时全局变量与图片路径拼接

理论上&#xff0c;应该在main.js中定义一个全局变量&#xff0c;然后在页面的<image>标签上的是src直接使用即可 main.js 页面上 看上去挺靠谱的&#xff0c;实际上小程序后台会报一个错 很明显这种方式小程序是不认的&#xff0c;这就头疼了&#xff0c;还想过另外一个…...

比较PWM调光和无极调光

在比较PWM调光和无极调光哪种方式更节能时&#xff0c;需要综合考虑多个因素&#xff0c;如灯具类型、光源效率、调光范围以及使用场景等。 PWM调光系统通过调节LED驱动电流的占空比来实现LED亮度的调节&#xff0c;具有高精度、高稳定性、无闪烁现象以及适用范围广等优点。其节…...

【高校科研前沿】新疆生地所陈亚宁研究员团队在GeoSus发文:在1.5°C和2°C全球升温情景下,中亚地区暴露于极端降水的人口增加

目录 文章简介 1.研究内容 2.相关图件 3.文章引用 文章简介 论文名称&#xff1a;Increased population exposures to extreme precipitation in Central Asia under 1.5 ◦C and 2 ◦C global warming scenarios&#xff08;在1.5C和2C全球变暖情景下&#xff0c;中亚地区…...

使用 OKhttp3 实现 智普AI ChatGLM HTTP 调用(SSE、异步、同步)

SSE 调用 SSE&#xff08;Sever-Sent Event&#xff09;&#xff0c;就是浏览器向服务器发送一个HTTP请求&#xff0c;保持长连接&#xff0c;服务器不断单向地向浏览器推送“信息”&#xff08;message&#xff09;&#xff0c;这么做是为了节约网络资源&#xff0c;不用一直…...

智慧校园教学模式的崛起:优化学习体验

在当今数字化时代&#xff0c;智慧校园教学模式正在成为教育界的热门话题。随着科技的不断发展&#xff0c;传统的教学方式已经无法满足现代学生的需求。智慧校园教学模式以其灵活性、互动性和个性化的特点&#xff0c;正逐渐改变着教育的面貌。 首先&#xff0c;智慧校园教学模…...

ffmpeg视频编码原理和实战-(5)对编码过程进行封装并解决丢帧问题

头文件&#xff1a; xencode.h #pragma once #include <mutex> #include<vector> struct AVCodecContext; struct AVPacket; struct AVFrame; class XEncode { public:///// 创建编码上下文/// para codec_id 编码器ID号&#xff0c;对应ffmpeg/// return 编码上…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

WebRTC从入门到实践 - 零基础教程

WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC&#xff1f; WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个支持网页浏览器进行实时语音…...