英文:
Android specific code in clean architecture
问题
-
我想知道的是,应该把处理加速度计、地理围栏、位置、短信等功能的代码放在哪里?我最初的想法是将它们放在单独的存储库中。但由于这些是独立的长时间运行的进程,可以启动或停止,这感觉不太对。我尝试将这些类从存储库重命名为服务,以便更清晰地表达意图。但仍然感觉有点不对。有什么好的替代方案吗?
-
为了能够接收已发送短信的状态,我需要注册一个接收器。谁应该负责这个?存储库本身在接收到sendSms()调用时,应该注册接收器、发送消息并释放接收器,还是UseCase首先应该检查SmsRepository是否已启动,如果没有,应该启动它,从而注册接收器,然后调用sendSms()方法?或者也许应该采取另一种方法,在应用程序启动时注册接收器,然后在关闭时取消注册?
-
这是一个合适的包结构吗?
编辑: 4. 如果您想不断监听服务器结果,应该怎么做?您是直接从ViewModel订阅存储库,还是在其完成后不断调用相同的UseCase(其目的是仅返回单个结果)?我理解UseCase只返回单个结果,不应该被订阅。
英文:
I've read multiple clean architecture tutorials for android, but all of them had very basic structure with simple network calls which leaves me wondering.
-
What I want to know is where should I put code that handles accelerometer, geofencing, location, sms and similar? My initial thought was to put them in separate repositories. But as these are separate long running processes that could be started or stopped, it just doesn't feel right. I've tried renaming these classes from repository to service, just so the intent would be more clearly expressed. But still seems a bit off. What would be a good alternative?
-
To be able to receive sent sms status, I need to register a receiver. Who should be responsible for that? Would the repository itself, upon receiving a call to sendSms(), should register that receiver, send message and release receiver, or would a UseCase first would have to check if SmsRepository is started, and if not would start it, thus registering receiver, and then call the sendSms() method? Or maybe there should be another approach taken to register receiver on app start and unregister on close?
-
Is this an appropriate package structure?
EDIT: 4. What to do in case you want to constantly listen for server result? Do you directly subscribe to repository from viewmodel or do you keep calling same usecase (whose purpose is to fetch result once) after it finishes? My understanding of UseCase is that it only returns single result and is not supposed to be subscribable.
答案1
得分: 2
我的谦虚意见:
- 由于加速度计、陀螺仪等属于“数据源”类别,您可以将它们放入SensorRepository/SensorDataSource/(位于领域/核心层之外的数据层,可以包含Android代码)。当您需要访问它们时,可以通过UseCase类进行访问,在那里您将拥有以下逻辑:采样频率、数据过滤器、格式更改、可能的缓冲计数等等…
将加速度计、陀螺仪、位置放入相同或不同的类中,应该根据特征而不是传感器类型来决定。如果一个特征(例如配置文件)需要同时使用位置和短信,它们应该位于同一个类别下。
启动/停止它们可以通过调用StopLocationUseCase、StartLocationUseCase来实现,它们将调用那些Repository的start()/stop()等方法… StartLocationUseCase应该是幂等的,如果已经启动(UseCase会询问Repository),它不会再次启动。
-
知道“短信已发送/未发送”的状态感觉像是“sendSms()”操作的一部分。因此,如果可能的话,所有的注册/发送/注销应该在“sendSms()”中同步调用。
-
基于特征的方式更可取(甚至项目模块也应该是基于特征的)。
-
UseCase可以返回Observable类似的数据类型,但在我看来,它不应该包含状态。
英文:
My humble opinions:
- Since accelerometer, gyroscope.. are kind of
Data Sources
, you can put them in SensorRepository/SensorDataSource/ (Data Layer which sits outside of Domain/Core layer and can have Android code). When you need to access them, you can go through UseCase class, where you would have this logics: sampling frequency, data filter, format changing, maybe buffer count etc...
To put accelerometer, gyroscope, location into same or different classes, should be decided feature based, not by sensor type based. If one feature (e.g. profile) needs both location and sms, they should be under same class.
Starting/stopping them can happen by calling StopLocationUseCase, StartLocationUseCase which will call start()/stop() of those Repository etc... StartLocationUseCase should be idempotent, if there is already started (UseCase will ask Repository), it won't start again.
-
Knowing 'sms sent/not sent' status feels like it is part of
sendSms()
operation. So all register/send/unregister should be called insendSms()
synchronously if possible. -
Feature based is preferred (even project modules should be feature-based)
-
UseCase can return Observable kind of data type but IMHO it should not contain state.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论