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

这篇具有很好参考价值的文章主要介绍了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   = .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 效果图:

Protocols/面向协议编程, DependencyInjection/依赖式注入 的使用,SwiftUI Advanced Learning,iOS,Swift,UI

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 效果图:

Protocols/面向协议编程, DependencyInjection/依赖式注入 的使用,SwiftUI Advanced Learning,iOS,Swift,UI文章来源地址https://www.toymoban.com/news/detail-724513.html

到了这里,关于Protocols/面向协议编程, DependencyInjection/依赖式注入 的使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring DI简介及依赖注入方式和依赖注入类型

    目录 一、什么是依赖注入 二、依赖注入方式 1. Setter注入 2. 构造方法注入 3. 自动注入  三、依赖注入类型 1. 注入bean类型 2. 注入基本数据类型 3. 注入List集合 4. 注入Set集合 5. 注入Map集合 6. 注入Properties对象 往期专栏文章相关导读  1. Maven系列专栏文章 2. Mybatis系列专栏文章

    2024年02月02日
    浏览(47)
  • 【ASP.NET Core 基础知识】--依赖注入(DI)--什么是依赖注入

    依赖注入(Dependency Injection,简称DI)是一种设计模式,用于解耦和管理类之间的依赖关系。它的核心思想是将原本需要在代码中显式创建的依赖关系,交给外部容器进行控制和管理。 具体来说,依赖注入的实现方式是通过将依赖对象的创建和维护责任转移到外部容器中,使

    2024年01月23日
    浏览(64)
  • spring——依赖注入原理及注入方式

    🟣1.依赖注入(Dependency Injection,DI) 是一种设计模式和编程技术,其原理是将对象的依赖关系由外部容器来管理和注入。它的目的是解耦组件之间的依赖关系,提高代码的灵活性、可维护性和可测试性。 🟣2.依赖注入的原理 是通过在对象的构造函数、属性或方法中注入所依

    2024年02月08日
    浏览(43)
  • springIoc依赖注入循环依赖三级缓存

    理论思想,原来的对象是由使用者来进行控制,有了spring之后,可以把整个对象交给spring来帮我们进行管理 依赖注入,把对应的属性的值注入到具体的对象中,@autowired,populateBean完成属性的注入 beanFactory,存储对象,使用map结构来存储,在spring中一般存在三级缓存,singleton

    2024年01月16日
    浏览(45)
  • SpringBoot中的依赖注入和自动注入

    以下内容为本人学习 Spring Boot的依赖注入和自动注入 与ChatGpt提问后对其回答 进行部分修改 (有的错误实在是离谱 = =)、格式调整等操作后的答案, 可能对于其中部分细节(是错是对,能力有限有的看不出来 = =),并未做深入探究 ,大家感兴趣的话可以自行验证。 依赖注

    2024年02月06日
    浏览(78)
  • Spring Boot中的依赖注入和自动注入

    以下内容为本人学习 Spring Boot的依赖注入和自动注入 与ChatGpt提问后对其回答 进行部分修改 (有的错误实在是离谱 = =)、格式调整等操作后的答案, 可能对于其中部分细节(是错是对,能力有限有的看不出来 = =),并未做深入探究 ,大家感兴趣的话可以自行验证。 依赖注

    2024年02月06日
    浏览(47)
  • Spring:依赖注入的方式(setter注入、构造器注入、自动装配、集合注入)

    依赖注入的方式有setter注入、构造器注入、自动装配、集合注入 首先,Maven项目pom.xml依赖包如下: pom.xml 【注】:上述除spring依赖包之外其他三个依赖包用于测试使用。 1. setter注入 先说明一下,这里有的文件为Book2Dao(接口)、Book2DaoImpl(Book2Dao接口实现类)、Book2Service(接口)、

    2024年02月02日
    浏览(46)
  • 使用 @Autowired 依赖注入时警告不建议使用字段注入

    在 Spring 中注入依赖时有 字段注入 、 构造器注入 、S etter 方法注入 三种注入方式。 无法注入 final 字段 在 Spring 2.5 中引入了 @Autowired 注解,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。在成员变量上使用 @Autowired 注解可以进行字段注入,如下:

    2024年02月05日
    浏览(43)
  • quarkus依赖注入之三:用注解选择注入bean

    这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本文是《quarkus依赖注入》系列的第三篇,前文咱们掌握了创建bean的几种方式,本篇趁热打铁,学习一个与创建bean有关的重要知识点:一个接口如果有多个实现类时,bean实例应该如何选择其中的一个

    2024年02月14日
    浏览(46)
  • quarkus依赖注入之四:选择注入bean的高级手段

    这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本文是《quarkus依赖注入》系列的第四篇,在应用中,一个接口有多个实现是很常见的,那么依赖注入时,如果类型是接口,如何准确选择实现呢?前文介绍了五种注解,用于通过配置项、profile等手

    2024年02月14日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包