我正在学习 MVVM 和 Clean Architecture。然后我发现了一些关于 MVVM + Clean Architecture 的文章,但我仍然没有明白 mvvm with clean architecture 和 mvvm without clean architecture 之间的区别。有关于这些东西的总结吗?谢谢你。
我正在尝试Android架构组件中的分页库,但我怀疑将它集成到基于干净架构的项目中.
一般来说我有3个模块:
为了引入分页,我不得不将PagedList<T>类视为域类.(IMO不是一个可怕的想法,因为最终是一个列表,数据源是抽象的)
所以在域层我可以有一个像以下的repostiory:
interface ItemRepository {
fun getItems():PagedList<Item>
}
Run Code Online (Sandbox Code Playgroud)
然后在数据模块中创建如下的实现:
class ItemRepositoryImpl: ItemRepositoy(private val factory:ItemDataSourceFavtory) {
fun getItems():PagedList<Item> {
val pageConfigurations = PagedList.Config.Builder()
.setPageSize(10)
.setInitialLoadSizeHint(15)
.setPrefetchDistance(5)
.setEnablePlaceholders(false)
.build()
return RxPagedListBuilder(locationDataSourceFactory, pageConfigurations)
.setInitialLoadKey(1)
.buildObservable()
}
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.我的疑问是,当我们需要变换域模型为表示层(比方说我的项目需要意识到,如果被检查显示的图标检查),通常我会我的域模型映射到演示文稿一个.
我知道DataSourceFactoryhas map和mapByPage方法,但工厂驻留在数据层.我的Viewmodel使用来自模型层的数据,在这种情况下,这将是一个数据PagedList,据我所知,分页列表不支持映射.
那么在这种情况下适当的做法是什么呢?
android clean-architecture android-architecture-components android-jetpack android-paging
我有 2 个用例,并且LoadA我需要访问从. 该业务被设计为如果尚不存在则返回默认值。LoadSettingsLoadASettingsLoadSettingsSettingsSetting
默认的初始化逻辑放在里面LoadSettings,但是现在LoadA必须依赖于LoadSettings而不是调用SettingsRepository,从而创建了对等依赖。
就严格遵循清洁架构而言,这是反模式吗?
我想知道我是否以正确的方式使用了干净的架构。我试图像这张图一样放置它:
我读过包结构应该按用例安排,但我很难理解如何做到这一点。
我们来看看我的包结构:
请注意,我不知道将活动真正放在 UI 文件夹中的什么位置,您能推荐一下吗?有关系吗?
在数据文件夹中,我有用于存储库设计模式的存储库。 我的改造网络调用与 UI 文件夹处于同一级别。我的依赖注入框架也是如此。
阅读此出版物后,我开始担心我现在想知道我的包结构是否正确?
我想开始使用 NestJs 创建 REST API,但我不确定如何设置可扩展的层通信对象。
因此,从有关如何开始的文档中,我提出了UsersController处理 HTTP 请求和响应的方法,UsersService处理控制器和数据库访问器之间的逻辑以及UsersRepository负责数据库管理的方法。
我使用NestJs提供的TypeORM 包,所以我的数据库模型是
@Entity('User')
export class UserEntity extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ unique: true })
username: string;
@Column()
passwordHash: string;
@Column()
passwordSalt: string;
}
Run Code Online (Sandbox Code Playgroud)
但是您可能知道,这个模型必须映射到其他模型,反之亦然,因为您不想将密码信息发送回客户端。我将尝试用一个简单的例子来描述我的 API 流程:
控制器
首先,我有一个用于GET /users/:id和的控制器端点POST /users。
@Get(':id')
findById(@Param() findByIdParamsDTO: FindByIdParamsDTO): Promise<UserDTO> {
// find user by id and return it
}
@Post()
create(@Body() createUserBodyDTO: CreateUserBodyDTO): Promise<UserDTO> {
// create a …Run Code Online (Sandbox Code Playgroud) 据我了解,
use cases或interactors用于entities执行某些操作,而,entities持有我们的business rules.
根据这个定义:
用例与实体交互并依赖于实体
用例以什么方式依赖于实体,关系是什么?
例如,假设我们有一个具有三个功能的银行应用程序:login、view balance和transfer funds。
因此,为了能够转移资金,用户必须登录并且应该有足够的余额。
我猜我们这里的用例是,transfer funds上面的语句是business rule,如果是这样的话,如何实现它?
类比很多,但正确的实现却很少。
我目前正在创建一个微服务项目,在其中实现 Bob Martin 创造的清洁架构模式。虽然我的代码运行良好,但我对干净的架构模式有疑问,特别是接口和 use_cases 层。该应用程序是我正在开发的一个小型电子商务 POC。话虽如此,由于它正在实现微服务,所以我有 3 个不同的服务。产品、图片和评论。每当发出获取“完整产品”的请求时,客户端都会 ping 完整产品的端点,它会抓取该端点,并使用其 id 来 ping 我的图像和评论服务,以获取该产品的所有图像和评论。
那么,我的问题是我应该在哪里实现创建这些调用的逻辑?我的直觉告诉我应该将它放在控制器层中,因为这是两个层中最抽象的,而且我不会因为将 axios 依赖项放在其中而感到难过。但可惜的是,我也觉得“完整的产品必须包括产品详细信息、图像和所有评论”这句话听起来很像商业规则。
我知道这个问题主要是主观的,但我想知道你如何实现这个逻辑,为什么?
我还应该提到,在我当前的解决方案中,我的 use_case 是我调用存储库并实际从数据库中获取产品的地方。话虽这么说,如果我将 API 调用放入控制器层,我必须首先调用我的 use_case 来获取产品,然后可能创建一个单独的 use_case 来检查我的最终对象是否实际上是“完整产品”。
在"干净架构"中,交互者(用例)负责定义业务逻辑.大多数示例以这种方式定义用例:
public MyUseCase() {
public boolean execute(...) {
int id = repository.insert(a)
if(id > 0) {
b.aId= id;
repository.insert(b);
...
}
}
}
Run Code Online (Sandbox Code Playgroud)
Interactors主要使用简单的CRUD操作或存储库查询.上面的示例在简单的情况下是同步的,但您可以使用异步解决方案(如回调或rxjava)以相同的方法找到repos.
但是用例不完整呢?例如,您不能100%确定插入后a它仍然会在插入时存在b.如果在插入后,a你得到一些RepositoryException同时插入b.
我到目前为止看到的所有回购都没有考虑到,所以我的问题是:
清洁架构中上述问题的解决方案是什么?
我正在使用以下插件:https : //pub.dev/packages/freezed
我想子类化冻结的数据类以在我的数据层中提供附加功能。所以我有我的数据类,它看起来像:
import 'dart:ui';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'card.freezed.dart';
@freezed
abstract class Card with _$Card {
factory Card({String text, Color color, List<String> categories}) = _Card;
}
Run Code Online (Sandbox Code Playgroud)
现在我想将此 Card 类作为我的 CardModel 的超类,以便 CardModel 可以访问相同的字段、copyWith 方法、值相等......但我不知道如何去做。我正在尝试这样的事情:
import 'package:flutter/widgets.dart';
import 'package:growthdeck/features/card_deck/domain/entities/card.dart';
import '../../domain/entities/card.dart';
abstract class CardModel extends Card {
factory CardModel.fromMap(Map<String, dynamic> card) => Card(
text: card["text"],
color: Color(int.parse(card['color'])),
categories: card['categories'] as List<String>,
);
}
Run Code Online (Sandbox Code Playgroud)
这会引发以下错误:
package:growthdeck/features/card_deck/data/models/card_model.dart 11:9 new CardModel.fromMap
test/features/card_deck/data/models/card_model_test.dart 13:23 main.<fn>
type '_$_Card' is not a subtype of type …Run Code Online (Sandbox Code Playgroud) android ×3
architecture ×2
android-architecture-components ×1
dart ×1
flutter ×1
interactors ×1
mvp ×1
mvvm ×1
nestjs ×1
node.js ×1
typescript ×1
use-case ×1