当前位置: 首页 > 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 编码上…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

腾讯云V3签名

想要接入腾讯云的Api&#xff0c;必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口&#xff0c;但总是卡在签名这一步&#xff0c;最后放弃选择SDK&#xff0c;这次终于自己代码实现。 可能腾讯云翻新了接口文档&#xff0c;现在阅读起来&#xff0c;清晰了很多&…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

ubuntu22.04有线网络无法连接,图标也没了

今天突然无法有线网络无法连接任何设备&#xff0c;并且图标都没了 错误案例 往上一顿搜索&#xff0c;试了很多博客都不行&#xff0c;比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动&#xff0c;重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...