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

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

MVC 数据库

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

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

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

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

jmeter聚合报告中参数详解

sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample&#xff08;样本数&#xff09; 表示测试中发送的请求数量&#xff0c;即测试执行了多少次请求。 单位&#xff0c;以个或者次数表示。 示例&#xff1a;…...