谈谈 MVX 中的 Model

站在思想层面看MVX架构 程序的本质 程序的本质在于模拟现实,但是有更明确的分工 简单的一个例子: 我 写 代码。 这是一个主谓结构: 主语->我,谓语->写,宾语->代码。 现在让我们来面向视角看问题: 代码: 是个物体,是用来 被 写 的 写: 是个动作,是用来 被 我执行的 我: 是个物体,是用来 执行 写 这个动作 写代码的。 好,接着我们来面向对象写代码: 首先,创建一个我,这是个物体,所以应该创建一个对象: public class Me { } 然后,需要有代码,才能写,代码也 阅读详情

谈谈 MVX 中的 Model


常见的 Model 层

在大多数 iOS 的项目中,Model 层只是一个单纯的数据结构,你可以看到的绝大部分模型都是这样的:

Swift

struct User {
    enum Gender: String {
        case male = "male"
        case female = "female"
    }
    let name: String
    let email: String
    let age: Int
    let gender: Gender
}

模型起到了定义一堆『坑』的作用,只是一个简单的模板,并没有参与到实际的业务逻辑,只是在模型层进行了一层抽象,将服务端发回的 JSON 或者说 Dictionary 对象中的字段一一取出并装填到预先定义好的模型中。

我们可以将这种模型层中提供的对象理解为『即开即用』的 Dictionary 实例;在使用时,可以直接从模型中取出属性,省去了从 Dictionary 中抽出属性以及验证是否合法的过程。

Swift

let user = User...

nameLabel.text = user.name
emailLabel.text = user.email
ageLabel.text = "\(user.age)"
genderLabel.text = user.gender.rawValue

JSON -> Model

使用 Swift 将 Dictionary 转换成模型,在笔者看来其实是一件比较麻烦的事情,主要原因是 Swift 作为一个号称类型安全的语言,有着使用体验非常差的 Optional 特性,从 Dictionary 中取出的值都是不一定存在的,所以如果需要纯手写这个过程其实还是比较麻烦的。

Swift

extension User {
    init(json: [String: Any]) {
        let name = json["name"] as! String
        let email = json["email"] as! String
        let age = json["age"] as! Int
        let gender = Gender(rawValue: json["gender"] as! String)!
        self.init(name: name, email: email, age: age, gender: gender)
    }
}

这里为 User 模型创建了一个 extension 并写了一个简单的模型转换的初始化方法,当我们从 JSON 对象中取值时,得到的都是 Optional 对象;而在大多数情况下,我们都没有办法直接对 Optional 对象进行操作,这就非常麻烦了。

麻烦的 Optional

在 Swift 中遇到无法立即使用的 Optional 对象时,我们可以会使用 ! 默认将字典中取出的值当作非 Optional 处理,但是如果服务端发回的数据为空,这里就会直接崩溃;当然,也可使用更加安全的 if let 对 Optional 对象进行解包(unwrap)。

Swift

extension User {
    init?(json: [String: Any]) {
        if let name = json["name"] as? String,
            let email = json["email"] as? String,
            let age = json["age"] as? Int,
            let genderString = json["gender"] as? String,
            let gender = Gender(rawValue: genderString) {
            self.init(name: name, email: email, age: age, gender: gender)
        }
        return nil
    }
}

上面的代码看起来非常的丑陋,而正是因为上面的情况在 Swift 中非常常见,所以社区在 Swift 2.0 中引入了 guard 关键字来优化代码的结构。

Swift

extension User {
    init?(json: [String: Any]) {
        guard let name = json["name"] as? String,
            let email = json["email"] as? String,
            let age = json["age"] as? Int,
            let genderString = json["gender"] as? String,
            let gender = Gender(rawValue: genderString) else {
                return nil
        }
        self.init(name: name, email: email, age: age, gender: gender)
    }
}

不过,上面的代码在笔者看来,并没有什么本质的区别,不过使用 guard 对错误的情况进行提前返回确实是一个非常好的编程习惯。

不关心空值的 OC

为什么 Objective-C 中没有这种问题呢?主要原因是在 OC 中所有的对象其实都是 Optional 的,我们也并不在乎对象是否为空,因为在 OC 中向 nil 对象发送消息并不会造成崩溃,Objective-C 运行时仍然会返回 nil 对象。

这虽然在一些情况下会造成一些问题,比如,当 nil 导致程序发生崩溃时,比较难找到程序中 nil 出现的原始位置,但是却保证了程序的灵活性,笔者更倾向于 Objective-C 中的做法,不过这也就见仁见智了。

OC 作为动态语言,这种设计思路其实还是非常优秀的,它避免了大量由于对象不存在导致无法完成方法调用造成的崩溃;同时,作为开发者,我们往往都不需要考虑 nil 的存在,所以使用 OC 时写出的模型转换的代码都相对好看很多。

Objective-C

// User.h
typedef NS_ENUM(NSUInteger, Gender) {
    Male = 0,
    Female = 1,
};

@interface User: NSObject

@property (nonatomic, strong) NSString *email;
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSUInteger age;
@property (nonatomic, assign) Gender gender;

@end

// User.m
@implementation User

- (instancetype)initWithJSON:(NSDictionary *)json {
    if (self = [super init]) {
        self.email = json[@"email"];
        self.name = json[@"name"];
        self.age = [json[@"age"] integerValue];
        self.gender = [json[@"gender"] integerValue];
    }
    return self;
}

@end

当然,在 OC 中也有很多优秀的 JSON 转模型的框架,如果我们使用 YYModel 这种开源框架,其实只需要写一个 User 类的定义就可以获得 -yy_modelWithJSON: 等方法来初始化 User 对象:

Objective-C

User *user = [User yy_modelWithJSON:json];

而这也是通过 Objective-C 强大的运行时特性做到的。

除了 YYModel,我们也可以使用 Mantle 等框架在 OC 中解决 JSON 到模型的转换的问题。

元编程能力

从上面的代码,我们可以看出:Objective-C 和 Swift 对于相同功能的处理,却有较大差别的实现。这种情况的出现主要原因是语言的设计思路导致的;Swift 一直鼓吹自己有着较强的安全性,能够写出更加稳定可靠的应用程序,而安全性来自于 Swift 语言的设计哲学;由此看来静态类型、安全和动态类型、元编程能力(?)看起来是比较难以共存的。

其实很多静态编程语言,比如 C、C++ 和 Rust 都通过宏实现了比较强大的元编程能力,虽然 Swift 也通过模板在元编程支持上做了一些微小的努力,不过到目前来看( 3.0 )还是远远不够的。

OC 中对于 nil 的处理能够减少我们在编码时的工作量,不过也对工程师的代码质量提出了考验。我们需要思考 nil 的出现会不会带来崩溃,是否会导致行为的异常、增加应用崩溃的风险以及不确定性,而这也是 Swift 引入 Optional 这一概念来避免上述问题的初衷。

相比而言,笔者还是更喜欢强大的元编程能力,这样可以减少大量的重复工作并且提供更多的可能性,与提升工作效率相比,牺牲一些安全性还是可以接受的。

网络服务 Service 层

现有的大多数应用都会将网路服务组织成单独的一层,所以有时候你会看到所谓的 MVCS 架构模式,它其实只是在 MVC 的基础上加上了一个服务层(Service),而在 iOS 中常见的 MVC 架构模式也都可以理解为 MVCS 的形式,当引入了 Service 层之后,整个数据的获取以及处理的流程是这样的:

![](现有的大多数应用都会将网路服务组织成单独的一层,所以有时候你会看到所谓的 MVCS 架构模式,它其实只是在 MVC 的基础上加上了一个服务层(Service),而在 iOS 中常见的 MVC 架构模式也都可以理解为 MVCS 的形式,当引入了 Service 层之后,整个数据的获取以及处理的流程是这样的:)

  1. 大多数情况下服务的发起都是在 Controller 中进行的;
  2. 然后会在 HTTP 请求的回调中交给模型层处理 JSON 数据;
  3. 返回开箱即用的对象交还给 Controller 控制器;
  4. 最后由 View 层展示服务端返回的数据;

不过按理来说服务层并不属于模型层,为什么要在这里进行介绍呢?这是因为Service 层其实与 Model 层之间的联系非常紧密;网络请求返回的结果决定了 Model 层该如何设计以及该有哪些功能模块,而 Service 层的设计是与后端的 API 接口的设计强关联的,这也是我们谈模型层的设计无法绕过的坑。

iOS 中的 Service 层大体上有两种常见的组织方式,其中一种是命令式的,另一种是声明式的。

命令式

命令式的 Service 层一般都会为每一个或者一组 API 写一个专门用于 HTTP 请求的 Manager 类,在这个类中,我们会在每一个静态方法中使用 AFNetworking 或者 Alamofire 等网络框架发出 HTTP 请求。

Objective-C

import Foundation
import Alamofire

final class UserManager {
    static let baseURL = "http://localhost:3000"
    static let usersBaseURL = "\(baseURL)/users"

    static func allUsers(completion: @escaping ([User]) -> ()) {
        let url = "\(usersBaseURL)"
        Alamofire.request(url).responseJSON { response in
            if let jsons = response.result.value as? [[String: Any]] {
                let users = User.users(jsons: jsons)
                completion(users)
            }
        }
    }

    static func user(id: Int, completion: @escaping (User) -> ()) {
        let url = "\(usersBaseURL)/\(id)"
        Alamofire.request(url).responseJSON { response in
            if let json = response.result.value as? [String: Any],
                let user = User(json: json) {
                completion(user)
            }
        }
    }
}

在这个方法中,我们完成了网络请求、数据转换 JSON、JSON 转换到模型以及最终使用 completion 回调的过程,调用 Service 服务的 Controller 可以直接从回调中使用构建好的 Model 对象。

Objective-C

UserManager.user(id: 1) { user in
    self.nameLabel.text = user.name
    self.emailLabel.text = user.email
    self.ageLabel.text = "\(user.age)"
    self.genderLabel.text = user.gender.rawValue
}

声明式

使用声明式的网络服务层与命令式的方法并没有本质的不同,它们最终都调用了底层的一些网络库的 API,这种网络服务层中的请求都是以配置的形式实现的,需要对原有的命令式的请求进行一层封装,也就是说所有的参数 requestURL、method 和 parameters 都应该以配置的形式声明在每一个 Request 类中。

如果是在 Objective-C 中,一般会定义一个抽象的基类,并让所有的 Request 都继承它;但是在 Swift 中,我们可以使用协议以及协议扩展的方式实现这一功能。

Swift

protocol AbstractRequest {
    var requestURL: String { get }
    var method: HTTPMethod { get }
    var parameters: Parameters? { get }
}

extension AbstractRequest {
    func start(completion: @escaping (Any) -> Void) {
        Alamofire.request(requestURL, method: self.method).responseJSON { response in
            if let json = response.result.value {
                completion(json)
            }
        }
    }
}

在 AbstractRequest 协议中,我们定义了发出一个请求所需要的全部参数,并在协议扩展中实现了 start(completion:) 方法,这样实现该协议的类都可以直接调用 start(completion:) 发出网络请求。

Swift

final class AllUsersRequest: AbstractRequest {
    let requestURL = "http://localhost:3000/users"
    let method = HTTPMethod.get
    let parameters: Parameters? = nil
}

final class FindUserRequest: AbstractRequest {
    let requestURL: String
    let method = HTTPMethod.get
    let parameters: Parameters? = nil

    init(id: Int) {
        self.requestURL = "http://localhost:3000/users/\(id)"
    }
}

我们在这里写了两个简单的 Request 类 AllUsersRequest 和 FindUserRequest,它们两个一个负责获取所有的 User 对象,一个负责从服务端获取指定的 User;在使用上面的声明式 Service 层时也与命令式有一些不同:

Swift

FindUserRequest(id: 1).start { json in
    if let json = json as? [String: Any],
        let user = User(json: json) {
        print(user)
    }
}

因为在 Swift 中,我们没法将 JSON 在 Service 层转换成模型对象,所以我们不得不在 FindUserRequest 的回调中进行类型以及 JSON 转模型等过程;又因为 HTTP 请求可能依赖其他的参数,所以在使用这种形式请求资源时,我们需要在初始化方法传入参数。

命令式 vs 声明式

现有的 iOS 开发中的网络服务层一般都是使用这两种组织方式,我们一般会按照资源或者功能来划分命令式中的 Manager 类,而声明式的 Request 类与实际请求是一对一的关系。

这两种网络层的组织方法在笔者看来没有高下之分,无论是 Manager 还是 Request 的方式,尤其是后者由于一个类只对应一个 API 请求,在整个 iOS 项目变得异常复杂时,就会导致网络层类的数量剧增。

这个问题并不是不可以接受的,在大多数项目中的网络请求就是这么做的,虽然在查找实际的请求类时有一些麻烦,不过只要遵循一定的命名规范还是可以解决的。

小结

现有的 MVC 下的 Model 层,其实只起到了对数据结构定义的作用,它将服务端返回的 JSON 数据,以更方便使用的方式包装了一下,这样呈现给上层的就是一些即拆即用的『字典』。

单独的 Model 层并不能返回什么关键的作用,它只有与网络服务层 Service 结合在一起的时候才能发挥更重要的能力。

而网络服务 Service 层是对 HTTP 请求的封装,其实现形式有两种,一种是命令式的,另一种是声明式的,这两种实现的方法并没有绝对的优劣,遵循合适的形式设计或者重构现有的架构,随着应用的开发与迭代,为上层提供相同的接口,保持一致性才是设计 Service 层最重要的事情。

FPGA实战笔记——SDRAM乒乓缓存与OV5640视频采集(VGA显示优化篇) 本文详细介绍了基于FPGA的SDRAM乒乓缓存技术在OV5640视频采集与VGA显示优化中的应用。通过设计多时钟域同步和双Bank乒乓缓存策略,有效解决了摄像头30fps输出与VGA 60fps显示之间的帧率不匹配问题,实现了720P高清视频的流畅稳定显示,为实时图像处理系统提供了可靠的硬件解决方案。 阅读详情

相关推荐

基于Codex与Skills的学术研究自动化全流程实战指南

还在为海量文献下载、整理、阅读和综述写作而头疼吗?面对堆积如山的PDF,你是否感到无从下手?从选题、文献检索、到写作、绘图、润色,再到应对AI检测和审稿意见,学术研究的每一步都充满挑战。本文将为你带来一套堪称“王炸组合”的解决方案: Codex + Skills 。这不是简单的工具介绍,而是一套从零开始,覆盖学术研究全流程的保姆级实战教程。我们将手把手教你如何安装、配置,并利用强大的Skills(技能)自动化处理文献下载管理、高效撰写综述、生成专业图表、智能润色降重,直至应对审稿。无论你是科研新手还是希望提

weixin_29041195的博客 762

MVX总结

汽车要运载人,人还要携带物品,汽车和人直接交互==要有限的和其他对象交互(不要了解其内部细节,不和不直接对象交互):迪米特原则,最少知识原则。View:视图,不同架构中充当角色不同 xml(java)/composable/kotlin。Android平台的实现中,有大量的View的操作在COntroller(Activity)中。思考:如果Presenter可以操作View和Model,不就等于是之前的Activity吗?MVI流程:ui,intent,viewmodel,uistate,ui。

feather(猎羽) 965

从零到一:手把手教你用YonBuilder for NCC搭建NC Cloud 2021.11开发环境(含避坑指南)

本文详细指导如何使用YonBuilder for NCC搭建NC Cloud 2021.11开发环境,涵盖硬件要求、软件安装、YonBuilder配置及常见故障排除。特别提供避坑指南,帮助开发者快速上手NCC开发,确保环境配置的原子化分解和开发思维的体系化建立。

weixin_42523326的博客 344

如何应对Android面试官 -> 玩转 MVx(MVC、MVP、MVVM、MVI)

本章主要讲解下 MVx;

IT_Android的博客 1327

037、有源钳位反激变换器(ACF)原理

文章摘要 有源钳位反激变换器(ACF)是一种克服常规反激电路漏感能量处理瓶颈的高效解决方案。文章从实际炸机案例切入,指出RCD钳位电路在高压、宽范围、高功率场景下的局限性。ACF通过增加钳位管和钳位电容,将漏感能量回收而非消耗,实现效率提升2-3%、精准电压钳位和更好EMI性能。文章详细解析了ACF四阶段工作过程、关键波形特征,并指出设计陷阱:漏感需保持1%-3%特定范围、钳位电容ESR要求严格、需专用控制IC支持互补驱动。最后给出实用调试建议,强调ACF适用于65W+功率场景,低压验证后再逐步升压的调试方

Jack010169的博客 258

MATLAB地理数据处理 25:植被物候提取及分析模型优化(Savitzky-Golay)

之前我写过一篇使用Savitzky-Golay处理遥感数据,获取地面物候信息的MATLAB代码,但是发现存在一些问题:对物候开始期和物候结束期的阈值设定都为相同值,但是有些研究中,需要根据不同的环境条件,设置不同的物候阈值,所以对其进行相应的修改。

amyniez的博客,欢迎交流讨论 2233

Android架构学习之路三-MVX

前言 这是架构学习系列的第三篇,主要介绍一下 MVC, MVP 以及 MVVM 架构,至于 MVI 后面会单独介绍。这些 MVX 的目的都是为了将业务和视图分离,松耦合,作为 Android 程序猿,大多不陌生了。 一个 App 离不开 Model 和 View 这两个角色, Model 决定了 App 的数据,而 View 决定怎么向用户展示这些数据,大多框架或组件基本上都是用来处理这两者之间的交互关系的。 因此一个 App 的架构需要处理两个任务: 更新 Model —— 如何处理...

chuyouyinghe的专栏 1020

踩坑实录:C#上位机YOLOv11从2FPS到45FPS,ONNX Runtime GPU加速全解析

算力迁移:将推理核心从CPU迁移至GPU(核心提速手段);内存复用:避免重复分配/释放内存,减少GC压力;维度固定:工业场景固定输入分辨率,关闭动态维度;资源限制:合理限制GPU/CPU/内存占用,避免资源耗尽;解耦设计:推理线程与UI线程解耦,避免跨线程问题。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 570

三层架构 与 MVC、MVP、MVVM 模式的区别

三层架构 与 MVC、MVP、MVVM 模式的区别 1、三层架构 三层架构是一种软件架构(software architecture) ,是一种分层结构。在软件体系架构设计中,分层式结构是最常见,也是最重要的一种结构,它将整个业务应用从上到下划分为:表示层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access la...

weixin_43747073的博客 3445

【PyTorch】CNN(一维卷积Conv1D)实现时间序列预测

本文介绍了一维卷积神经网络(Conv1D)在时间序列预测中的应用,展示了其基本原理及实现方式。通过合适的数据预处理和模型调参,Conv1D可以有效地捕捉时间序列数据中的模式,从而进行精准预测。

走向CTO的路上... 1172

YOLO26涨点改进 | 检测头改进篇 | 利用ASFF改进YOLO26检测头,自适应空间特征融合模块,在所有的目标检测上均有大幅度的涨点效果

本文提出了一种自适应空间特征融合(ASFF)检测头YOLO26,用于解决目标检测中特征金字塔跨尺度特征不一致的问题。ASFF通过学习空间权重图,自适应地融合不同尺度的特征,抑制特征层间的冲突信息。实验表明,该方法在MSCOCO数据集上显著提升了检测精度(45FPS下AP达42.4%),且仅引入极小推理开销。ASFF模块具有可微分性、模型无关性和计算成本低等优势,能够有效改善特征尺度不变性,实现速度与精度的良好平衡。文章详细介绍了ASFF的原理、实现代码及其在YOLO模型中的集成方法。

Ai缝合怪、助力小伙伴高效发论文 550

vue-study-1 mvx模式

1、首先了解一下mvx框架模式 MVX框架模式:MVC+MVP+MVVM 1、mvc model(模型)+view(视图)+co'n'roller(控制器),主要基于分层,让彼此的职责都分开。 view通过controller来与model联系,controller事view和model的协调者,view和model不直接联系,基本的联系都是单向的。用户通过控制器controller来操作模

eazdp 531

聊聊MVX中的Model

写在前面 随着Android架构的不断演进,从最初的MVC到MVP再到MVVM,变化的只有M和V层之间的部分,M和V层开发者似乎都已经统一了意见。 Model 层 : 实体模型、数据的获取、存储等等 View层:向用户展示UI及处理交互 但据我在GitHub上看过的各种项目代码而言,许多人仅仅停留在字面上的理解,而没有真正的处理好三层间的边界。 今天,我们来聊一聊MVX中的Model。 Mod...

weixin_33743248的博客 182

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

MVX框架模式

MVX框架模式:MVC+MVP+MVVM 1.MVC Model(模型)+View(视图)+controller(控制器),主要是基于分层的目的,让彼此的职责分开。 View通过Controller来和Model联系,Controller是View和Model的协调者,View和Model不直接联系,基本联系都是单向的。 用户User通过控制器Controller来操作模板Model从...

MagicGirl 478

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

第1章 MVX模式与Vue.js

1.1 MVX模式 1.1.1 MVC模式 MVC是应用最广泛的软件架构之一,分为 Model 模型,Controller 控制器,View视图。基于分层目的,让彼此职责分开。 view通过Controller联系Model,Controller是View和Model的协调者 View和Model不直接联系,基本联系是单向的。 用户通过操作Controller来操作Model以改变View 参考 MVC模式简介 在网页当中, V即View视图是指用户看到并与之交互的界面。比如由html元素组成的网页

qiao_qiao_happy的博客 441

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

MVX模式汇总

MVX模式是什么 最早是Java领域的MVC,然后是MVP,及现在成熟的MVVW。 MVC MVC是最广泛的软件架构之一,一般MVC分为: Model(模型)、Controller(控制器)、view(视图)。 它的主要是分层,将彼此的职责分开。 关系 view一般是通过controller来和model进行联系;controller是view和model的协调者;view与model不直接联系...

sinat_33255495的博客 799

浅谈MVX

转载地址:http://www.jianshu.com/p/9a6845b26856 “Android MVP 详解(下)”已经发布,欢迎大家提建议。 MVP 在 Android 上的使用其实已经有挺长一段时间了,长到似乎有点“过时”了(目前风头正劲的是MVVM),那为什么现在还要讲 MVP。今天我想要讨论它的主要原因有如下几点: 1. MVP 并未过

wanderer_ankey的博客 3723

Android开发模式万佛朝中MVX(MVC、MVP、MVVM)

今天公司的测试服务器开小差了,后台被吐槽的体无完肤,虽然我们都知道跟他没有什么关系,但是生活需要乐趣,总要有人背锅,哈哈!~~~暂时没有环境开发了,那就分享一下之前做的一篇关于Android开发模式的总结,MVC,MVP,MVVM对于刚了解或者没有好好归纳总结的朋友来说,特别是那些像我记性很差的朋友来说,很容易忘记。 下面我们一起归纳总结一下,这样屡清楚他们的关系我们用起来就可以迎刃有余,也不会...

u014736095的专栏 419

关于MVC/MVP/MVVM的一些错误认识

在 Android 开发中使用 MVP 和 MVVM 模式早已不是新鲜事了,各种 MVP/MVVM 相关的文章、开源库也已屡见不鲜,甚至是让人眼花撩乱,那么我为什么还要在这个早已被画满涂鸦的黑板上再来涂涂画画呢?是想彰显我的存在感吗?那当然!啊不不不……不完全是!我还想要警醒读到这篇文章的各位:你们对于MVX的理解可能并不完全正确!我们都知道 MVX 的进化过程是从滚球兽进化到 MVC ,然后从 MVC 进化到 MVP,再从 MVP 超进化到 MVVM。

一个码农的博客 1997

Github标星5-8K今年最热门技术-Android-MVP-阿里大牛-倾情-详解(上)

三层架构是一个分层式的软件体系架构设计,它可适用于任何一个项目。通常意义上的三层架构就是将整个业务应用划分为:界面层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer)。区分层次的目的即为了“高内聚低耦合”的思想。在软件体系架构设计中,分层式结构是最常见,也是最重要的一种结构。微软推荐的分层式结构一般分为三层,从下至上分别为:数据访问层、业务逻辑层(又或称为领域层)、表示层。(参考自:百度百科)

2401_84123077的博客 756

Android编码架构MVx演进历史

架构模式的理解 架构为了解决特定的问题而提出,按照特定的原则将系统整体进行模块/组件/角色的划分,建立模块/组件/角色间的沟通机制。 具体解释一下,首先是要有特定的问题,没有问题空谈架构,仿佛是空中楼阁,没有实用价值,而对应到不同的问题,会有不同的解决方式。 其次是模块的划分要根据特定的原则,没有原则随意划分,也就无从去评估一个架构的好坏。最后就是模块间的通信机制,让系统成为一个整体。 最后,架构模式,其实更多的是一种思想,一种规则,往往一种架构模式可能会有不同的实现方式,而实现方式之间,只有合适与否,并没

李林杰的博客 595

Github标星5-8K今年最热门技术-Android-MVP-阿里大牛-倾情-详解(上)(2)

三层架构是一个分层式的软件体系架构设计,它可适用于任何一个项目。通常意义上的三层架构就是将整个业务应用划分为:界面层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer)。区分层次的目的即为了“高内聚低耦合”的思想。在软件体系架构设计中,分层式结构是最常见,也是最重要的一种结构。微软推荐的分层式结构一般分为三层,从下至上分别为:数据访问层、业务逻辑层(又或称为领域层)、表示层。(参考自:百度百科)

2401_84412895的博客 713
上一篇: AVFoundation编程指南
下一篇: AVFoundation编程-AVPlayer使用
Philm_iOS
博客等级 码龄8年 74粉丝 53原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值