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、会设计顺序…

CSS盒子模型的详细解析

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

【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;可广泛部署于服务器、云计算、边缘…

如何利用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&…

vue3+koa+axios实现前后端通信

vue3koaaxios实现前后端通信 写了一个小demo来实现前后端通信,涉及跨域问题&#xff0c;非常简单可以给大家平时开发的时候参考 服务端&#xff1a; 目录结构如下&#xff1a; router index.js // router的入口文件 // 引入路由 const Router require("koa-router&quo…

记一次mysql事务并发优化

记一次mysql事务并发优化 背景 事情的情况大致是这样的。一个扣减库存的业务上线以后&#xff0c;隔几天会报一次错&#xff0c;错误内容如下&#xff1a; ERROR - exception: UncategorizedSQLException,"detail":"org.springframework.jdbc.UncategorizedSQ…

Spring framework Day22:Aware接口

前言 在Spring框架中&#xff0c;有许多接口和类都有一个非常重要的作用——让我们能够更方便地构建应用程序和管理组件。其中&#xff0c;Aware接口就是其中一个非常重要的接口之一。通过实现该接口&#xff0c;我们可以让Spring容器感知到特定的组件和资源&#xff0c;并进行…

讲解 CSS 过渡和动画 — transition/animation (很全面)

前言 由于用户越来越注重 Web应用 的使用体验&#xff0c;随之而来的是 Web应用 需要提供了更加完善的 Web 动画 效果来实现以平滑的状态贯穿于用户的整个使用过程中。现在&#xff0c;这已经是司空见惯了&#xff0c;用户潜意识是希望可以获得更快的反馈响应和更友好的用户界…

Elasticsearch系列组件:Beats高效的日志收集和传输解决方案

Elasticsearch 是一个开源的、基于 Lucene 的分布式搜索和分析引擎&#xff0c;设计用于云计算环境中&#xff0c;能够实现实时的、可扩展的搜索、分析和探索全文和结构化数据。它具有高度的可扩展性&#xff0c;可以在短时间内搜索和分析大量数据。 Elasticsearch 不仅仅是一个…

接口自动化测试持续集成,Soapui接口功能测试参数化

按照自动化测试分层实现的原理&#xff0c;每一层的脚本实现都要进行参数化&#xff0c;自动化的目标就是要实现脚本代码与测试数据分离。当测试数据进行调整的时候不会对脚本的实现带来震荡&#xff0c;从而提高脚本的稳定性与灵活度&#xff0c;降低脚本的维护成本。Soapui最…