Protocols/面向协议编程, DependencyInjection/依赖式注入 的使用

1. Protocols 定义实现协议,面向协议编码

  1.1 创建面向协议实例 ProtocolsBootcamp.swift

import SwiftUI/// 颜色样式协议
protocol ColorThemeProtocol {var primary: Color { get }var secondary: Color { get }var tertiary: Color { get }
}struct DefaultColorTheme: ColorThemeProtocol {let primary: Color   = .bluelet secondary: Color = .whitelet tertiary: Color  = .gray
}struct AlternativeColorTheme: ColorThemeProtocol {let primary: Color   = .redlet secondary: Color = .whitelet tertiary: Color  = .orange
}struct AnotherColorTheme: ColorThemeProtocol{var primary: Color  = .bluevar secondary: Color = .redvar tertiary: Color  = .purple
}/// 定义按钮文字协议
protocol ButtonTextProtocol{var buttonText: String { get }
}protocol ButtonPressedProtocol{func buttonPressed()
}protocol ButtonDataSourceProtocol: ButtonTextProtocol, ButtonPressedProtocol{
}class DefaultDataSource: ButtonDataSourceProtocol{var buttonText: String = "Protocols are awesome!"func buttonPressed(){print("Button was pressed!")}
}class AlternativeDataSource: ButtonTextProtocol{var buttonText: String = "Protocols are lame."
}/// 面向协议
struct ProtocolsBootcamp: View {let colorTheme: ColorThemeProtocollet dataSource: ButtonDataSourceProtocolvar body: some View {ZStack {colorTheme.tertiary.ignoresSafeArea()Text(dataSource.buttonText).font(.headline).foregroundColor(colorTheme.secondary).padding().background(colorTheme.primary).cornerRadius(10).onTapGesture {dataSource.buttonPressed()}}}
}struct ProtocolsBootcamp_Previews: PreviewProvider {static var previews: some View {// DefaultColorTheme / AlternativeColorTheme / AnotherColorThemeProtocolsBootcamp(colorTheme: DefaultColorTheme(), dataSource: DefaultDataSource())}
}

  1.2 效果图:

2. DependencyInjection 依赖式注入

  2.1 创建依赖式注入的实例 DependencyInjectionBootcamp.swift

import SwiftUI
import Combine// Problems with singletons
// 1. Singleton's are GLOBAL      单例模式是全局的
// 2. Can't customize the init!   不能自定义初始化
// 3. Can't swap out dependencies 不能交换式依赖
struct PostsMode: Identifiable, Codable{let userId: Intlet id: Intlet title: Stringlet body: String
}/// 定义协议 数据服务
protocol DataServiceProtocol {/// 获取数据func getData() -> AnyPublisher<[PostsMode], Error>
}/// 生产者数据服务
class ProductionDataService: DataServiceProtocol{/// 单例 Singleton// static let instance = ProductionDataService()let url: URLinit(url: URL) {self.url = url}func getData() -> AnyPublisher<[PostsMode], Error>{URLSession.shared.dataTaskPublisher(for: url).map({$0.data}).decode(type: [PostsMode].self, decoder: JSONDecoder()).receive(on: DispatchQueue.main).eraseToAnyPublisher()}
}/// 模拟请求服务器返回数据
class MockDataService: DataServiceProtocol{let testData: [PostsMode]init(data: [PostsMode]? ) {self.testData = data ?? [PostsMode(userId: 1, id: 1, title: "One", body: "One"),PostsMode(userId: 2, id: 2, title: "Two", body: "Two"),PostsMode(userId: 3, id: 3, title: "Three", body: "Three")]}func getData() -> AnyPublisher<[PostsMode], Error> {Just(testData).tryMap({ $0 }).eraseToAnyPublisher()}
}/// 依赖试
class Dependencies {let dataService: DataServiceProtocolinit(dataService: DataServiceProtocol) {self.dataService = dataService}
}/// ViewModel
class DependencyInjectionViewModel: ObservableObject{@Published var dataArray: [PostsMode] = []var cancellables =  Set<AnyCancellable>()let dataService: DataServiceProtocolinit(dataService: DataServiceProtocol) {self.dataService = dataServiceloadPosts()}private func loadPosts(){dataService.getData().sink { _ in} receiveValue: {[weak self] returnedPosts inself?.dataArray = returnedPosts}.store(in: &cancellables)}
}/// 依赖注入
struct DependencyInjectionBootcamp: View {@StateObject private var vm: DependencyInjectionViewModelinit(dataService: DataServiceProtocol){_vm = StateObject(wrappedValue: DependencyInjectionViewModel(dataService: dataService))}var body: some View {ScrollView {VStack {ForEach(vm.dataArray) { post inText(post.title)Divider()}}}}
}struct DependencyInjectionBootcamp_Previews: PreviewProvider {// static let dataService = ProductionDataService(url: URL(string: "https://jsonplaceholder.typicode.com/posts")!)static let dataService = MockDataService(data: [PostsMode(userId: 12, id: 12, title: "test", body: "test"),PostsMode(userId: 123, id: 123, title: "123", body: "123")])static var previews: some View {DependencyInjectionBootcamp(dataService: dataService)}
}

  2.2 效果图:

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

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

相关文章

【基于Kmeans、Kmeans++和二分K均值算法的图像分割】数据挖掘实验三

文章目录 I、项目任务要求II、原理描述KMeansKMeans二分K均值评价指标-轮廓系数 III、数据集描述IV、具体实现过程V、结果分析VI、完整代码VII、深度学习与图片分割&#xff08;补充&#xff09;CNN1. 卷积层&#xff08;Convolutional Layer&#xff09;&#xff1a;2. 激活函…

DAQ进行准确的测量,为决策提供更可靠的依据

进行准确的测量&#xff0c;为决策提供更可靠的依据 DAQExpress提供了交互式分析面板&#xff0c;可帮助您轻松配置兼容的测量硬件&#xff0c;以及查看分析测量数据。无需编程即可立即捕获测量数据&#xff0c;或者在DAQExpress编辑器中创建一个基本的LabVIEW VI&#xff0c;…

LeetCode算法栈—有效的括号

目录 有效的括号 用到的数据结构&#xff1a; 位运算、Map 和 Stack Stack 常用的函数&#xff1a; 题解&#xff1a; 代码&#xff1a; 运行结果; 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符…

上海亚商投顾:沪指震荡调整 转基因概念股逆势大涨

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日低开低走&#xff0c;深成指、创业板指均跌超1%&#xff0c;双双创出年内新低。转基因概念股逆势大涨…

C语言进行实验:通过程序实现线算图取值【支持VC++ 6.0编辑器环境运行】

背景&#xff1a; 一、实验目的和要求 1、能描述数据基本类型及其常量的表示方法&#xff1b; 2、会对变量进行定义及初始化&#xff1b; 3、能使用运算符与表达式对变量赋值&#xff1b; 4、会描述C语句的概念及种类、C语言常用的输入/出方式&#xff1b; 5、会设计顺序…

Java Cache 缓存方案详解及代码-Ehcache

一、Spring缓存概念 Spring从3.1开始定义了 org.springframework.cache.Cache 和 org.springframework.cache.CacheManager 接口来统一不同的缓存技术&#xff1b; 并支持使用 JCache&#xff08;JSR-107&#xff09; 注解简化我们开发。 常用的缓存实现有 RedisCache 、EhCach…

【达梦数据库】mysql函数改写达梦

yearweek 改写为 year(‘2019-07-11’)||WEEK(‘2019-07-11’,1); mysql> select YEARWEEK(2019-07-11,1); -------------------------- | YEARWEEK(2019-07-11,1) | -------------------------- | 201928 | -------------------------- 1 row in set (0…

解决GET请求入参@NotNull验证不生效问题

一、问题 get请求NotNull验证不生效 二、解决方案 两个步骤&#xff1a; 在该方法的controller类上加Validated&#xff1b;在参数面前加NotNull&#xff1b; 三、其他注解 //被注释的元素必须为null Null //被注释的元素不能为null NotNull //被注释的元素必须为true Ass…

[一带一路金砖 2023 CTF]Crypto

题1 题目描述&#xff1a; from Crypto.Util.number import * from flag import flag import gmpy2 assert(len(flag)38) flag bytes_to_long(flag)p getPrime(512) q getPrime(512)e 304 enc pow(flag,e,p*q) print(p) print(q) print(enc) #9794998439882070838464987…

CSS盒子模型的详细解析

03-盒子模型 作用&#xff1a;布局网页&#xff0c;摆放盒子和内容。 盒子模型-组成 内容区域 – width & height 内边距 – padding&#xff08;出现在内容与盒子边缘之间&#xff09; 边框线 – border 外边距 – margin&#xff08;出现在盒子外面&#xff09; d…

赎金信(C++解法)

题目 给你两个字符串&#xff1a;ransomNote 和 magazine &#xff0c;判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以&#xff0c;返回 true &#xff1b;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。 示例 1&#xff1a; 输入…

【Git】bad signature 0x00000000 index file corrupt. fatal: index file corrupt

问题描述 电脑写代码时蓝屏。重启后 git commit 出错。 error: bad signature 0x00000000 fatal: index file corrupt原因分析 当电脑发生蓝屏或异常关机时&#xff0c;Git 的索引文件可能损坏。 解决方案 删除损坏的索引文件。 rm -Force .git/index回退到上一个可用的版…

第十九章 文件操作

程序运行时产生的数据都属于临时数据&#xff0c;程序一旦运行结束都会被释放 通过文件可以将数据持久化 C中对文件操作需要包含头文件 < fstream > 文件类型分为两种&#xff1a; 文本文件 - 文件以文本的ASCII码形式存储在计算机中 二进制文件 - 文件以文本的二进制…

C语言 内存

内存分配 内存分配的类型 C/C中内存分为5个区&#xff0c;分别为栈区、堆区、全局/静态存储区、常量存储区、代码区 静态内存分配&#xff1a;编译时分配&#xff0c;包括全局、静态全局、静态局部三种变量。 动态内存分配&#xff1a;运行时分配&#xff0c;包括栈&#x…

图论相关算法

一、迪杰斯特拉(Dijkstra)算法 迪杰斯特拉算法使用类似广度优先搜索的方法解决了带权图的单源最短路径问题。这是一个贪心算法。 1.核心思想 &#xff08;1&#xff09;每次选中一个点&#xff0c;这个点满足两个条件&#xff1a; 未被选过距离最短 &#xff08;2&#xf…

一些前端面试思考

回流和重绘 先牢记这句话&#xff0c;回流必将引起重绘&#xff0c;而重绘不一定会引起回流。回流的代价要远大于重绘。 当你给一个元素更换颜色&#xff0c;这样的行为是不会影响页面布局的&#xff0c;DOM树不会变化&#xff0c;但颜色变了&#xff0c;渲染树得重新渲染页面&…

Linux系统管理:虚拟机OpenEuler安装

目录 一、理论 1.OpenEuler 二、实验 1.虚拟机OpenEuler安装准备阶段 2.安装OpenEuler 3.进入系统 一、理论 1.OpenEuler &#xff08;1&#xff09;简介 欧拉&#xff08;Euler&#xff09;是数字基础设施的开源操作系统&#xff0c;可广泛部署于服务器、云计算、边缘…

LeetCode75——Day9

文章目录 一、题目二、题解 一、题目 443. String Compression Given an array of characters chars, compress it using the following algorithm: Begin with an empty string s. For each group of consecutive repeating characters in chars: If the group’s length …

如何利用PHP快速抓取音频数据?

以下是一个使用Dusk库和PHP编写的爬虫程序&#xff0c;用于爬取海量的音频数据。这个程序使用了https://www.duoip.cn/get_proxy的代码。 <?php // 引入Dusk库 require Dusk.php;// 创建Dusk对象 $dusk new Dusk();// 设置代理 $dusk->setProxy(127.0.0.1, 8080);// 使…

Unity2023, Unity2022, Unity2021的性能对比(帧率)

最近由于需要用到Unity最新版的一些功能&#xff0c;比如Spline&#xff0c;比如Foward渲染&#xff0c;新项目用了Unity2022.3.5版本&#xff0c;但是出包之后&#xff0c;感觉帧率很低。本着好奇的态度&#xff0c;专门写了一个测试场景&#xff0c;分别在Unity2023.1.15&…