为Android构建现代应用——应用架构
选择风格(Choosing a style)
我们将依照Google在《应用架构指南》中推荐的最佳实践和架构指南来构建OrderNow的架构。
这些定义包括通过各层定义组件的一些Clean Architecture原则。
层次的定义(Definition of the layers)
在应用程序中,我们将定义以下主要层次:
• 用户界面(UI)层
• 领域层
• 数据层
UI层(UI Layer)
这一层组合了UI元素,Views视图(composable functions可组合函数),ViewModels和表示层的实用程序,例如格式应用器和动画。 设计这一层的注意事项包括:
• 对于状态处理,遵循设计原则中描述的原则。
• 对于每个屏幕,将实现相应的ViewModel。
•viewmodels也将作为状态持有者,也就是状态管理器。
•导航逻辑将委托给视图,并将依赖于APP的状态。
•副作用应该报告给ViewModel。
•当配置发生变化时,Views模型应该保持它们的状态。
•鼓励使用stateless Views(无状态视图)。
领域层(Domain Layer)
尽管这一层可以是可选的,但我建议包含它,以保持与 Clean Architecture 规定的责任划分一致的设计。
这一层组合了被称为 UseCases 的组件,这些组件将管理业务逻辑和所有可由 ViewModels 重用的逻辑。
这一层还作为 UI 层(UI Layer)和数据层(Data Layer)之间的桥梁。
Models 类型的组件也属于这一层。
这些组件对表示层或领域层使用的实体或数据结构进行建模。例如,在 OrderNow 中,“产品”和“类别”都表示模型或实体。
UseCases (用例)是一种设计模式,用于定义特定的业务逻辑或应用程序功能。它们用于封装特定的应用程序操作,通常涉及从数据层获取数据、处理数据以及将结果传递给UI层。在使用清洁架构时,UseCases 通常在领域层中定义并由UI层调用。
关于这一层的设计考虑包括:
• 所有在视图中重复的展示逻辑都可以放在UseCases (用例)中。
• 属于此层的组件可以是无状态的;它们是不需要临时持久化的组件。
• UseCases (用例)执行的操作必须是主线程安全的。
• UseCases 可以相互通信,以协调用例操作。 • 每个 UseCases 负责一个且只有一个操作。
• 每个 UseCases 可能会使用一个或多个仓库(Repositories)。
数据层(Data Layer)
这一层组织了名为仓库(Repositories)的组件,它们协调和封装了与本地和远程数据源的集成逻辑。如其名称所示,它们遵循仓库模式。 这一层的其他组件包括数据源(Datasources)、映射器(Mappers)和数据传输对象(DTOs)。
• 数据源(Datasource):包含到外部或本地持久化源的逻辑集成。
• 数据传输对象(DTO):它是模型持久化实体的结构。包含持久性机制使用的定义。为了使其他层(UI和领域)不继承这些定义,这些类型的实体通过映射器转换为应用程序域的模型。
映射器:它们将 DTO 转换为领域层的模型实体。对于此层的设计,建议考虑以下事项:
• 此层可用作事实来源。
• 存储库执行的操作必须是主安全的。
• 为每个主要实体类型定义一个存储库,例如,产品存储库、类别存储库。
通用架构(General architecture)
不同集成层的通用图类似如下:
Architecture Layers 架构层 :
关于其他层
补充架构主要层次的其他辅助层将包括:
• Main(主层):包含应用程序的基础构件,例如 MainActivity、Application 和 ApplicationState 等等。
• Common(通用层):包含跨应用程序的构件,例如导航定义、用于其他层的实用工具和依赖管理器等等。
关于 PortsClean 架构的使用
建议在不同层的边界之间包括端口,这种技术允许反转控制,解耦在每层边界之间通信的组件。这种方法将为设计增加更好的可维护性和适应性。我们的示例应用程序 (OrderNow) 将在Domain Layer 和Data layer之间添加端口。
组织目录(Organizing directories)
在我们的OrderNow示例中,为了简单起见,层次将通过单个模块中的目录以单体方式组织。 我将把是否在后续的项目中决定分离各层并为每个层献出一个模块的决定留给读者自行判断。
通过两个定义来进行目录组织:
• 在UI层,将使用按功能组织。
• 在Domain Layer(领域层)和Data Layer(数据层),将使用按组件组织。
元素的命名和规范
对于组件命名,我们将使用以下规则:
使用后缀 只有在以下情况下才会在组件名中使用后缀:
• 包含包的名称没有推断出其类型。
• 需要强制组件代表的结构类型,例如,ProductRepository。
• 为了避免组件类型之间的混淆,例如,一个模型可能被命名为Category,其存储库名为 CategoryRepository。
后缀命名:
命名包
应用程序包的名称必须为小写,不能有分隔符,也不能有驼字。
命名组件
对于组件类型UseCases的名称,表示用例中的操作(do, get, update, save, send, delete, add,执行、获取、更新、保存、发送、删除、添加)的操作被用作前缀。
命名可组合函数
对于UI组件,也就是可组合函数的定义,我们将使用以下的命名规则,这些规则参考了Google在架构指南中的文档²⁷:
Screen:用于表示整个屏幕的可组合函数的后缀。 屏幕
UI:用于composables,这些composables将视图的状态(UI State)与组件的图形表示(UI Elements)结合在一起。 用户界面
Elements:用于定义UI库组件(Buttons, Layouts, Checkbox, TextFields ,如按钮、布局、复选框、文本字段等)的composables的后缀,这些组件构成了视图。 元素
Preview:用于预览视图(元素)的composables的前缀。Screen和UI composables也可以被组合预览,但由于对状态和其他变量的依赖性,它变得更加复杂。
注意:
在构建应用程序时,虽然定义所有的组件类型很重要,但也可能存在例外情况,不需要定义所有的组件类型,可以省略一些。具体取决于应用程序中屏幕的复杂程度,需要决定哪些组件类型适用,哪些不适用。
本章中,我想描述在开始实现之前要遵循的架构定义。还澄清了用于组织应用程序项目的规则。我必须澄清,本章中给出的定义是建议性的。读者可以自定义或假定适合自己的约定和规则,或者在实现中感到舒适的约定和规则。在下一章中,我们将开始实现OrderNow,首先要构建的是它的框架,即它的主要结构。
相关文章:

为Android构建现代应用——应用架构
选择风格(Choosing a style) 我们将依照Google在《应用架构指南》中推荐的最佳实践和架构指南来构建OrderNow的架构。 这些定义包括通过各层定义组件的一些Clean Architecture原则。 层次的定义(Definition of the layers) 在应用程序中,我们将定义以下主要层次…...
49:字符串的新增方法
字符串的新增方法 String.fromCodePoint()String.raw()实例方法:codePointAt()实例方法:normalize()[实例方法:includes(), startsWith(), endsWith()](https://es6.ruanyifeng.com/#docs/string-methods#实例方法:includes(), s…...

Kaggle图表内容识别大赛TOP方案汇总
赛题名称:Benetech - Making Graphs Accessible 赛题链接:https://www.kaggle.com/competitions/benetech-making-graphs-accessible 赛题背景 数以百万计的学生有学习、身体或视力障碍,导致人们无法阅读传统印刷品。这些学生无法访问科学…...

DAY2,Qt(继续完善登录框,信号与槽的使用 )
1.继续完善登录框,当登录成功时,关闭登录界面,跳转到新的界面中,来回切换页面; ---mychat.h chatroom.h---两个页面头文件 #ifndef MYCHAT_H #define MYCHAT_H#include <QWidget> #include <QDebug> /…...
【设计模式】设计原则-开闭原则
单一职责原则 定义 当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。作用 1、方便测试;测试时只需要对扩展的代码进行测试。 2、提高代码的可复用性;粒…...

【2500. 删除每行中的最大值】
来源:力扣(LeetCode) 描述: 给你一个 m x n 大小的矩阵 grid ,由若干正整数组成。 执行下述操作,直到 grid 变为空矩阵: 从每一行删除值最大的元素。如果存在多个这样的值,删除其…...

Superset部署
Superset部署 1、安装依赖 (superset) [hadoopnode1 ~]$ yum install -y python-setuptools (superset) [hadoopnode1 ~]$ yum install -y gcc gcc-c libffi-devel python-devel python-pip python-wheel openssl-devel2、安装Superset 2.1 安装(更新)…...
Python3 学习笔记 ~ 怎样打印字符串
Python中变量的打印方法_python打印变量_清欢依旧的博客-CSDN博客 a 9 b 2print(f"{a} / {b} {a/b}") print(a, "//", b, "", (a//b))a -9 print(f"{a} / {b} {a/b}") print(a, "//", b, "", (a//b))...
postgresql安装
安装postgresql Linux下载安装地址 https://www.postgresql.org/download/linux/redhat/ 指定对应版本,指定完成后会生成对应的安装语句 下载对应的包 yum –y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-l…...

ElasticSearch之IK分词器安装以及使用介绍
文章目录 一、IK 分词器简介1. 支持细粒度分词:2. 支持多种分词模式:3. 支持自定义词典:4. 支持拼音分词:5. 易于集成和使用: 二、安装步骤1、下载 IK 分词器插件:2、安装 IK 分词器插件:3. 安装…...

Linux系统安装部署Jenkins详细教程(图文讲解)
前言:最近需要使用Jenkins部署项目,所以想出一篇关于如何使用Linux系统安装部署Jenkins的相关教程,整体部署过程还是挺顺利的,特此分享一下! 目录 一、安装JDK11和Tomcat11 二、准备Jenkins安装包 三、部署Jenkins…...

基于ChatGPT聊天的零样本信息提取7.25
基于ChatGPT聊天的零样本信息提取 摘要介绍ChatIE用于零样本IE的多轮 QA 实验总结 摘要 零样本信息提取(IE)旨在从未注释的文本中构建IE系统。由于很少涉及人类干预,因此具有挑战性。 零样本IE减少了数据标记所需的时间和工作量。最近对大型…...

Pytorch个人学习记录总结 08
目录 神经网络-搭建小实战和Sequential的使用 版本1——未用Sequential 版本2——用Sequential 神经网络-搭建小实战和Sequential的使用 torch.nn.Sequential的官方文档地址,模块将按照它们在构造函数中传递的顺序添加。代码实现的是下图: 版本1—…...

Ansible自动化运维学习——综合练习
目录 (一)练习一 1.新建一个role——app 2.创建文件 3.删除之前安装的httpd服务和apache用户 4.准备tasks任务 (1)创建组group.yml (2)创建用户user.yml (3)安装程序yum.yml (4)修改模板httpd.conf.j2 (5)编写templ.yml (6)编写start.yml (7)编写copyfile.yml (8…...
Java中正则表达式
一、概念 正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。在众多语言中…...

13 硬链接和软链接
13.1 硬链接和软链接的区别 硬链接:A---B,假设B是A的硬链接,那么只要存在一个,无论删除哪一个,文件都能访问得到。 软链接:类似于快捷方式,删除源文件,快捷方式就访问不了。 13.2 创…...

智能合约安全审计
智能合约安全审计的意义 智能合约审计用于整个 DeFi 生态系统,通过对协议代码的深入审查,可以帮助解决识别错误、低效代码以及这些问题。智能合约具有不可篡改的特点,这使得审计成为任何区块链项目安全流程的关键部分。 代码审计对任何应用…...

矩阵置零(力扣)思维 JAVA
给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]] 输入:matrix [[0,1,2,0],[3,4,5,2],[…...
centos制作openssh 9.3p2 rpm包
标题使用源码制作openssh 9.3p2 的rpm包 准备: 操作系统:CentOS Linux release 7.4.1708 (Core) #测试发现rpm包要在什么系统安装需要就需要在什么系统上制作 工具软件:rpm-build 源码文件:openssh-9.3p2.tar.gz x11-ssh-askpas…...
uni-app:切换页面刷新,返回上一页刷新(onShow钩子函数的使用)
切换页面刷新:通过onShow()便可实现 返回上一页通过uni.navigateBack({delta: 1});实现 以返回上一页刷新为例 从B页面返回上一页到A页面 在A页面写入方法refreshHandler() methods: { // 执行刷新逻辑refreshHandler() {uni.request({url: getApp().globalData.…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...