IOS技术-常用设计模式

常用模式

在 iOS 开发中,有几种常用的设计模式,帮助开发者更好地组织代码、提高可维护性和可扩展性。以下是一些常见的设计模式:

1. MVC(Model-View-Controller)

  • 描述:将应用分为三部分:模型(Model)、视图(View)和控制器(Controller)。模型处理数据,视图负责用户界面,控制器协调两者。
  • 优点:清晰的分离,使得不同部分可以独立开发和维护。

2. MVVM(Model-View-ViewModel)

  • 描述:视图(View)与视图模型(ViewModel)之间有数据绑定,视图模型处理视图逻辑并暴露数据给视图。
  • 优点:增强了视图的可测试性和可重用性,特别适合使用数据绑定的场景。

3. Delegate(委托模式)

  • 描述:通过协议定义一组方法,允许一个对象(委托)响应另一个对象(代理)的事件。
  • 优点:实现了对象之间的解耦,使得代码更加灵活和可重用。

4. Observer(观察者模式)

  • 描述:允许一个对象(被观察者)维护一组依赖于它的对象(观察者),当被观察者的状态变化时,所有观察者都会收到通知。
  • 优点:支持事件驱动编程,适用于处理多个对象之间的动态关系。

5. Singleton(单例模式)

  • 描述:确保一个类只有一个实例,并提供全局访问点。
  • 优点:适合全局共享的资源,如配置管理器、网络管理器等。

6. Factory(工厂模式)

  • 描述:通过一个工厂方法创建对象,而不是直接实例化。
  • 优点:提供了创建对象的灵活性,可以根据条件返回不同的实例。

7. Strategy(策略模式)

  • 描述:定义一系列算法,并将每个算法封装起来,使它们可以互换。
  • 优点:可以在运行时选择和切换算法,符合开放-封闭原则。

8. Command(命令模式)

  • 描述:将请求封装为对象,从而使你可以用不同的请求对客户进行参数化。
  • 优点:支持撤销和重做操作,适用于复杂的用户操作。

9. Adapter(适配器模式)

  • 描述:将一个类的接口转换为客户端所期望的另一种接口,使得不兼容的接口能够协同工作。
  • 优点:提高了代码的灵活性和可重用性。

总结

这些设计模式在 iOS 开发中广泛应用,帮助开发者提高代码的组织性、可读性和可维护性。根据具体的需求和场景,选择合适的设计模式可以显著提升项目的质量。

MVVM

MVVM(Model-View-ViewModel)是一种设计模式,广泛应用于 iOS 开发中,旨在提高代码的可维护性和可重用性。以下是 MVVM 模式在 iOS 开发中的具体应用和结构。

MVVM 结构

  1. Model(模型)

    • 代表应用的数据和业务逻辑,通常是数据结构或网络模型。
    • 负责数据的获取、存储和处理。
  2. View(视图)

    • 用户界面部分,负责呈现数据和响应用户交互。
    • 视图通常是 UIView 或 UIViewController,直接与 ViewModel 进行交互,但不直接处理业务逻辑。
  3. ViewModel(视图模型)

    • 充当视图和模型之间的桥梁。负责从模型中获取数据并将其转换为视图所需的格式。
    • 处理视图逻辑,包含业务逻辑的部分,但不直接调用任何视图的 UI 元素。

MVVM 在 iOS 开发中的具体应用

1. 数据绑定

MVVM 的核心是数据绑定。通常使用框架(如 Combine 或 RxSwift)实现数据的双向绑定。这样,当 ViewModel 中的数据改变时,视图会自动更新。

2. 示例代码

以下是一个简单的 MVVM 示例,展示如何在 iOS 应用中实现 MVVM 模式。

Model

struct User {
    var name: String
    var age: Int
}

ViewModel

import Foundation
import Combine

class UserViewModel: ObservableObject {
    @Published var userName: String = ""
    @Published var userAge: String = ""
    
    private var user: User? {
        didSet {
            guard let user = user else { return }
            userName = user.name
            userAge = "\(user.age)"
        }
    }

    func fetchUser() {
        // 模拟网络请求
        user = User(name: "Alice", age: 30)
    }
}

View

import SwiftUI

struct UserView: View {
    @StateObject private var viewModel = UserViewModel()
    
    var body: some View {
        VStack {
            Text("Name: \(viewModel.userName)")
            Text("Age: \(viewModel.userAge)")
        }
        .onAppear {
            viewModel.fetchUser()
        }
    }
}

3. 优点

  • 分离关注点:视图和业务逻辑分离,使得代码更易于管理和测试。
  • 可重用性:ViewModel 可以在不同的视图之间重用,提升代码的可维护性。
  • 响应式编程:利用 Combine 或 RxSwift 等框架,实现数据的自动更新,提高用户体验。

4. 总结

MVVM 模式在 iOS 开发中通过将视图、视图模型和模型分离,促进了代码的组织性和可维护性。采用数据绑定机制,视图可以自动响应数据的变化,使得界面更新更为高效。适用于需要频繁更新和交互的应用场景。

MMVM Http示例

示例场景

创建一个简单的应用,展示用户列表。应用将从网络获取用户数据,并处理可能出现的错误。

1. Model

首先,我们定义一个 User 模型和一个 API 错误枚举。

import Foundation

struct User: Codable, Identifiable {
    let id: Int
    let name: String
    let age: Int
}

enum APIError: Error {
    case networkError
    case decodingError
}

2. ViewModel

接下来,我们创建一个 UserViewModel,它将处理网络请求、数据绑定和错误处理。

import Foundation
import Combine

class UserViewModel: ObservableObject {
    @Published var users: [User] = []
    @Published var errorMessage: String? = nil
    @Published var isLoading: Bool = false

    private var cancellables = Set<AnyCancellable>()
    
    func fetchUsers() {
        self.isLoading = true
        self.errorMessage = nil
        
        let url = URL(string: "https://api.example.com/users")!
        
        URLSession.shared.dataTaskPublisher(for: url)
            .map { $0.data }
            .decode(type: [User].self, decoder: JSONDecoder())
            .receive(on: DispatchQueue.main)
            .sink(receiveCompletion: { completion in
                switch completion {
                case .finished:
                    self.isLoading = false
                case .failure(let error):
                    self.isLoading = false
                    self.errorMessage = error.localizedDescription
                }
            }, receiveValue: { users in
                self.users = users
            })
            .store(in: &cancellables)
    }
}

3. View

最后,我们创建一个 SwiftUI 视图,展示用户列表和错误消息。

import SwiftUI

struct UserListView: View {
    @StateObject private var viewModel = UserViewModel()

    var body: some View {
        NavigationView {
            VStack {
                if viewModel.isLoading {
                    ProgressView("Loading...")
                } else if let errorMessage = viewModel.errorMessage {
                    Text("Error: \(errorMessage)")
                        .foregroundColor(.red)
                } else {
                    List(viewModel.users) { user in
                        VStack(alignment: .leading) {
                            Text(user.name)
                                .font(.headline)
                            Text("Age: \(user.age)")
                                .font(.subheadline)
                        }
                    }
                }
            }
            .navigationTitle("Users")
            .onAppear {
                viewModel.fetchUsers()
            }
        }
    }
}

4. 总结

在这个示例中,我们实现了一个简单的 MVVM 结构,展示了用户列表并处理了网络请求和错误。关键点包括:

  • 数据绑定:使用 @Published 属性来自动更新视图。
  • 网络请求:使用 URLSessiondataTaskPublisher 进行网络请求,结合 Combine 处理数据流。
  • 错误处理:通过 sink 方法处理请求的成功与失败,并更新错误信息。

这个结构在实际应用中可扩展并适应不同的需求,也是 iOS 开发中常用的模式。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容