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

news2024/11/25 23:02:37

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   = .blue
    let secondary: Color = .white
    let tertiary: Color  = .gray
}

struct AlternativeColorTheme: ColorThemeProtocol {
    let primary: Color   = .red
    let secondary: Color = .white
    let tertiary: Color  = .orange
}

struct AnotherColorTheme: ColorThemeProtocol{
    var primary: Color  = .blue
    var secondary: Color = .red
    var 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: ColorThemeProtocol
    let dataSource: ButtonDataSourceProtocol
    
    var 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 / AnotherColorTheme
        ProtocolsBootcamp(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: Int
    let id: Int
    let title: String
    let body: String
}

/// 定义协议 数据服务
protocol DataServiceProtocol {
    /// 获取数据
    func getData() -> AnyPublisher<[PostsMode], Error>
}

/// 生产者数据服务
class ProductionDataService: DataServiceProtocol{
    /// 单例 Singleton
   // static let instance = ProductionDataService()
    
    let url: URL
    
    init(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: DataServiceProtocol
    
    init(dataService: DataServiceProtocol) {
        self.dataService = dataService
    }
}

/// ViewModel
class DependencyInjectionViewModel: ObservableObject{
    @Published var dataArray: [PostsMode] = []
    var cancellables =  Set<AnyCancellable>()
    let dataService: DataServiceProtocol
    
    init(dataService: DataServiceProtocol) {
        self.dataService = dataService
        loadPosts()
    }

    private func loadPosts(){
        dataService.getData()
            .sink { _ in
                
            } receiveValue: {[weak self] returnedPosts in
                self?.dataArray = returnedPosts
            }
            .store(in: &cancellables)
    }
}

/// 依赖注入
struct DependencyInjectionBootcamp: View {
    @StateObject private var vm: DependencyInjectionViewModel
    
    init(dataService: DataServiceProtocol){
        _vm = StateObject(wrappedValue: DependencyInjectionViewModel(dataService: dataService))
    }
    
    var body: some View {
        ScrollView {
            VStack {
                ForEach(vm.dataArray) { post in
                    Text(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.coloradmin.cn/o/1097507.html

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

相关文章

MySQL JSON_TABLE() 函数

JSON_TABLE()函数从一个指定的JSON文档中提取数据并返回一个具有指定列的关系表。 应用&#xff1a;数据库字段以JSON 存储后&#xff0c;实际应用需要对其中一个字段进行查询 语法 JSON_TABLE(json,path COLUMNS(column[,column[,...]]))column:name参数 json必需的。一个 …

2023年全球半导体零部件市场发展现状分析:半导体零部件行业集中度高[图]

半导体零部件指的是在材料、结构、工艺、精度和品质、稳定性及可靠性等性能方面符合半导体设备技术要求的零部件&#xff0c;如O-Ring密封圈、精密轴承、射频电源、静电吸盘&#xff08;ESC&#xff09;、MFC流量计、石英件、硅及碳化硅件等。 半导体零部件分类 资料来源&…

【JVM面试】从JDK7 到 JDK8, JVM为啥用元空间替换永久代?

系列文章目录 【JVM系列】第一章 运行时数据区 【面试】第二章 从JDK7 到 JDK8, JVM为啥用元空间替换永久代&#xff1f; 大家好&#xff0c;我是青花。拥有多项发明专利&#xff08;都是关于商品、广告等推荐产品&#xff09;。对广告、Web全栈以及Java生态微服务拥有自己独到…

【京东开源项目】微前端框架MicroApp 1.0正式发布

介绍 MicroApp是由京东前端团队推出的一款微前端框架&#xff0c;它从组件化的思维&#xff0c;基于类WebComponent进行微前端的渲染&#xff0c;旨在降低上手难度、提升工作效率。MicroApp无关技术栈&#xff0c;也不和业务绑定&#xff0c;可以用于任何前端框架。 源码地址…

如何优雅的实现接口统一调用

耦合问题 有些时候我们在进行接口调用的时候&#xff0c;比如说一个push推送接口&#xff0c;有可能会涉及到不同渠道的推送&#xff0c;以我目前业务场景为例&#xff0c;我做结算后端服务的&#xff0c;会与金蝶财务系统进行交互&#xff0c;那么我结算后端会涉及到多个结算…

第二证券:国际油价大幅上涨 后市恐难持续走高

上个买卖周&#xff0c;受巴以冲突影响&#xff0c;原油商场成为各方关注的焦点。到上星期五收盘&#xff0c;布伦特原油周内涨幅达7%以上&#xff0c;为本年2月以来最大周涨幅&#xff0c;WTI原油周内累计上涨近6%。业内人士认为&#xff0c;其时地缘要素是导致油价出现异动的…

3分钟,快速上手Postman接口测试!

Postman是一个用于调试HTTP请求的工具&#xff0c;它提供了友好的界面帮助分析、构造HTTP请求&#xff0c;并分析响应数据。实际工作中&#xff0c;开发和测试基本上都有使用Postman来进行接口调试工作。有一些其他流程的工具&#xff0c;也是模仿的Postman的风格进行接口测试工…

DDD之上下文映射图(Context Mapping)

领域驱动设计系列文章&#xff0c;点击上方合集↑ 1. 开头 在DDD中&#xff0c;限界上下文与限界上下文之间需要相互集成&#xff0c;这种集成关系在DDD中称为上下文映射&#xff08;Context Mapping&#xff09;&#xff0c;也就是子域与子域之间的集成关系。 所以首先我们…

2023年中国微创手术器械及耗材发展趋势分析:发展呈现集成化、智能化[图]

随着微创外科手术渗透率的提升&#xff0c;国内微创外科手术器械及配件&#xff08;MISIA&#xff09;市场迎来爆发&#xff0c;预计2023年微创手术器械及耗材&#xff08;MISIA&#xff09;市场规模将达到238亿元&#xff0c;其中一次性MISIA市场规模约为204亿元&#xff0c;可…

网络安全——自学(黑客技术)

前言 前几天发布了一篇 网络安全&#xff08;黑客&#xff09;自学 没想到收到了许多人的私信想要学习网安黑客技术&#xff01;却不知道从哪里开始学起&#xff01;怎么学&#xff1f;如何学&#xff1f; 今天给大家分享一下&#xff0c;很多人上来就说想学习黑客&#xff0c…

【OpenVINO】OpenVINO C# API 常用 API 详解与演示

OpenVINO C# API 常用 API 详解与演示 1 安装OpenVINO C# API2 导入程序集 3 初始化OpenVINO 运行时内核4 加载并获取模型信息4.1 加载模型4.2 获取模型信息 5 编译模型并创建推理请求6 张量Tensor6.1 张量的获取与设置6.2 张量的信息获取与设置 7 加载推理数据7.1 获取输入张量…

vue2 引用3D模型

一、首先安装对应的插件&#xff08;前往查看model-viewer&#xff09; # install peer dependency ThreeJS npm install three # install package npm install google/model-viewer二、页面直接引用组件&#xff08;例子&#xff09; <model-viewer style"width: 5…

Clion debug查看cv::Mat或多维数组的变量值

在使用Clion的debug模式查看变量的数据值时,一般在variable窗口下直接查看,比如: 可当变量为cv::Mat或其它类型的多维数组的,尤其当数组以指针或引用形式传递时,如cv::Mat& imgSrcL,在variable窗口下查看,会发现Clion只提供这个变量的维度和data的首个数据信息等,如…

科普向丨语音芯片烧录工艺的要求

语音芯片烧录工艺要求烧录精度、速度、内存容量、电源稳定性、兼容性和数据安全性。这些要素需优化和控制以保证生产高效、稳定、安全并烧录出高质量的语音芯片。不同厂家生产的语音芯片在烧录工艺上存在差异&#xff0c;需相应设计和研发以实现兼容。 一、烧录精度 语音芯片烧…

Nginx:URL重写(示意图+举例+配置讲解)

示意图&#xff1a; URL Rewrite URL Rewrite 是一种用于修改网站 URL 结构或改变 URL 路径的技术。它允许网站管理员修改 URL 的外观&#xff0c;使其更加友好、可读&#xff0c;并且有助于改善网站的搜索引擎优化&#xff08;SEO&#xff09;。通过 URL Rewrite&#xff0c;…

iCloud涨价不用慌!学会使用群晖生态将本地SSD“上云”

文章目录 前言本教程解决的问题是&#xff1a;按照本教程方法操作后&#xff0c;达到的效果是想使用群晖生态软件&#xff0c;就必须要在服务端安装群晖系统&#xff0c;具体如何安装群晖虚拟机请参考&#xff1a; 1. 安装并配置synology drive1.1 安装群辉drive套件1.2 在局域…

【应用程序代理对象ApplicationDelegate-应用程序启动过程介绍 Objective-C语言】

一、那我们接着昨天的内容,继续往下讲 1.有人对昨天最后这块儿内容有点儿晕,再捋一下吧, 1)我们刚开始的时候,是不是在Main.storyboard里面,放了一个按钮 2)我呢,想在点击按钮的时候,执行一些操作,对吧, 所以呢,我给它拖了一个事件, 拖到类实现里面, 3)那,首…

.NET Core/.NET6 使用DbContext 连接数据库,SqlServer

安装以下NuGet包 Microsoft.EntityFrameworkCore.SqlServer&#xff1a;SQL server 需要添加包 Microsoft.EntityFrameworkCore.Tools Newtonsoft.Json&#xff1a;用于Json格式转换 创建一个实体类来表示数据库表。在项目中创建一个名为Customer.cs的文件&#xff0c;并添加以…

国内原汁原味的免费sd训练工具--哩布哩布AI

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 公众号&#xff1a;网络豆云计算学堂 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a; 网络豆的主页​​​​​ 目录 写在前面 一.体验与操作 1.注册 2.为何可…

享搭低代码平台:加速企业应用开发,轻松搭建表单和报表

在当今快节奏的商业环境中&#xff0c;企业需要快速响应市场需求并提供高效的解决方案。然而&#xff0c;传统的应用开发过程繁琐、耗时&#xff0c;并且需要专业的编程技能。为了解决这些问题&#xff0c;享搭低代码平台应运而生。本文将详细介绍享搭低代码平台的特点和优势&a…