为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,首先要构建的是它的框架,即它的主要结构。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/14409.shtml

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

相关文章

小程序创建

1,下载HBuilder X ;(3.8.7) HBuilderX-高效极客技巧 2,下载模板(不选云服务的); 3,运行-运行到小程序模拟器; 4,安装小程序开发工具; 5,选择稳定版-windows64版&…

SpringBoot 统⼀功能处理

目录 前言 1.⽤户登录权限效验 1.1、最初⽤户登录效验 1.2、Spring AOP ⽤户统⼀登录验证的问题 1.3、Spring 拦截器 了解 创建一个 Spring 拦截器 的流程 1、 创建自定义拦截器,实现 HandlerInterceptor 接⼝的preHandle(执⾏具体⽅法之前的预处理…

win10日程怎么同步到安卓手机?电脑日程同步到手机方法

在如今快节奏的生活中,高效地管理时间变得至关重要。而对于那些经常在电脑上安排日程的人来说,将这些重要的事务同步到手机上成为了一个迫切的需求。因为目前国内使用win10系统电脑、安卓手机的用户较多,所以越来越多的职场人士想要知道&…

Jenkins 安装构建

一、CentOS 安装 1. 使用该存储库 sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key 2. 安装 Java yum install fontconfig java-11-openjdk配…

解决eclipse 打开报错 An error has occurred. See the log file null.

解决eclipse 打开报错an error has ocurred. See the log file null 出现原因:安装了高版本的jdk,更换 jdk 版本,版本太高了。 解决方案:更改环境变量 改成 jkd 1.8

【深度学习实践】垃圾检测

简介 本项目使用深度学习目标检测开源框架PaddleDetection中的yolox算法实现了垃圾检测,本文包含了从头训练yolox模型和直接使用训练好的模型进行推理的代码及相关权重。 一、数据集准备 本次训练的数据集为coco格式,共包含150张垃圾的照片&#xff0…

利用小波分解信号,再重构

function [ output_args ] example4_5( input_args ) %EXAMPLE4_5 Summary of this function goes here % Detailed explanation goes here clc; clear; load leleccum; s leleccum(1:3920); % 进行3层小波分解,小波基函数为db2 [c,l] wavedec(s,3,db2); %进行…

hcip——路由策略

要求: 基础配置 AR1 [R1]int g 0/0/0 [R1-GigabitEthernet0/0/0]ip add 12.0.0.1 24[R1-GigabitEthernet0/0/0]int g 0/0/1 [R1-GigabitEthernet0/0/1]ip add 14.0.0.1 24[R1]int loop0 [R1-LoopBack0]ip add 1.1.1.1 24[R1]rip 1 [R1-rip-1]vers 2 [R1-rip-1]net…

Unity 性能优化五:渲染模块压力

CPU压力 Batching 在GPU渲染前,CPU会把数据按batch发送给GPU,每发送一次,都是一个drawcall,GPU在渲染每个batch的时候,会切换渲染状态,这里的渲染状态指的是:影响对象在屏幕上的外观的渲染属性…

深入学习java虚拟机||JVM内存结构五大模型

目录 程序计数器 栈 虚拟机栈 垃圾回收是否涉及栈内存? 栈内存分配越大越好吗? 方法内的局部变量是否线程安全? 栈内存溢出 本地方法栈 堆 方法区 先看内存图总览 程序计数器 定义:全称P r o g r a m C o u n t e r R e …

windows下配置vue开发环境

安装nodejs,配置npm 1.下载安装包:下载地址:https://nodejs.org/en/download 2.安装node:下载完成后进行安装,记住安装的文件夹。本人安装路径为 D:\Program Files\nodejs 3.配置环境变量: ①安装完成后…

基于传统检测算法hog+svm实现图像多分类

直接上效果图: 代码仓库和视频演示b站视频005期: 到此一游7758258的个人空间-到此一游7758258个人主页-哔哩哔哩视频 代码展示: 数据集在datasets文件夹下 运行01train.py即可训练 训练结束后会保存模型在本地 运行02pyqt.py会有一个可视化…

某信用中心之加速乐实战分析

某信用中心之加速乐实战分析 某信用中心之加速乐实战分析声明逆向目标逆向分析第一层cookie获取第二层cookie获取调试分析JS文件 模拟执行致谢 某信用中心之加速乐实战分析 声明 本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理&#x…

QTday2信号和槽

点击登录按钮,关闭Widget登录窗口,打开QQList窗口 widget.cpp #include "widget.h"void my_setupUI(Widget *w);Widget::Widget(QWidget *parent): QWidget(parent) {my_setupUI(this); }Widget::~Widget() { }void Widget::login_slots() {//fixemit jump_signal(…

CAN学习笔记1:计算机网络

计算机网络 1 概述 计算机网络就是把多种形式的计算机用通信线路连接起来,并使其能够互相进行交换的系统。实际上,计算机网络包括了计算机、各种硬件、各种软件、组成网络的体系结构、网络传输介质和网络通信计数。因此,计算机网络是计算机…

SpringCloudAlibaba之Ribbon

Ribbon是nacos自带的负载均衡器,属于客户端的负载均衡 但是在Spring高级版本中让LoadBalancer替代了 本人用的是2.1.0的nacos,ribbon还没有被替换。 使用: 在配置类中:LoadBalanced BeanLoadBalancedpublic RestTemplate restT…

【点云处理教程】05-Python 中的点云分割

一、说明 这是我的“点云处理”教程的第 5 篇文章。“点云处理”教程对初学者友好,我们将在其中简单地介绍从数据准备到数据分割和分类的点云处理管道。 在上一教程中,我们看到了如何过滤点云以减少噪声或其密度。在本教程中,我们将应用一些聚…

Redis(五)—— Redis进阶部分

一、Redis配置文件详解 注意这是Redis服务本身的配置文件&#xff0c;相当于maven的settings.xml&#xff0c;而不是我们在springboot去配置Redis的那个application.yml。 核心部分include 引入其他redis配置文件&#xff0c;相当于spring的<import>bind 设置IP&#xf…

Elasticsearch:通过动态修剪实现更快的基数聚合

作者&#xff1a;Adrien Grand Elasticsearch 8.9 通过支持动态修剪&#xff08;dynamic pruning&#xff09;引入了基数聚合加速。 这种优化需要满足特定的条件才能生效&#xff0c;但一旦实现&#xff0c;通常会产生惊人的结果。 我们观察到&#xff0c;通过此更改&#xff0…

C语言指针应该这么学?

数组名的意义&#xff1a; 1. sizeof(数组名)&#xff0c;这里的数组名表示整个数组&#xff0c;计算的是整个数组的大小。 2. &数组名&#xff0c;这里的数组名表示整个数组&#xff0c;取出的是整个数组的地址。 3. 除此之外所有的数组名都表示首元素的地址。 根据以上数…