hac*_*024 7 architecture authentication state flutter clean-architecture
我一直在尝试使用Reso Coder 的 Flutter对 Uncle Bob 的 Clean Architecture 的改编。
我的应用程序连接到 API,大多数请求(登录除外)都需要身份验证令牌。此外,登录后,会收到用户个人资料信息(如姓名和个人资料图片)。
我需要一种方法来在登录时保存这些数据,并在未来的 API 请求和我的应用程序的 UI 中使用它。
由于我是鲍勃叔叔的干净架构的新手,我不太确定这些数据属于哪里。以下是我提出的想法,所有这些都涉及将数据存储在User对象中:
将其存储User在存储库层的authentication功能目录中。其他存储库级别的方法可以将其传递给适当的数据源方法。
这似乎是最有道理的;调用其他 API 调用的其他存储库级方法可以User轻松使用存储的内容,将其传递给数据源层中的方法。
如果这是要走的路,我不太确定其他功能(使用 API)将如何访问User- 让一个存储库依赖于另一个存储库并将authentication存储库传递到新功能存储库可以吗?
将其存储User在存储库层的authentication功能目录中。其他(非登录)用例可以依赖于该存储库以及与其自身功能相关的存储库,并将其传递User给其存储库方法。
这也打破了垂直功能障碍,但它可能比想法 1 更清晰。
对于这两个想法,我的存储库如下所示:
abstract class AuthenticationRepository {
/// The current user.
User get currentUser;
/// True if logged in.
bool get loggedIn;
/// Logs in, saving the [User].
Future<void> login(AuthenticationParams params);
/// Logs out, disposing of the [User].
Future<void> logout();
/// Same as [logout], but logs out of all devices.
Future<void> logoutAll();
/// Retrieves stored login credentials.
Future<AuthenticationParams> retrieveStoredCredentials();
}
Run Code Online (Sandbox Code Playgroud)
这些想法“有效”吗?有更好的方法吗?
我看到了解决这个问题的另一种选择。我要讲的解决方案来自领域驱动设计,是一种基于事件的方法。
在 DDD 中,有限界上下文的概念。业务对象(鲍勃叔叔的实体)在不同的有界上下文中可以具有不同的含义。查看您的用户业务对象。某些用例使用的数据和方法通常与其他用例使用的数据和方法不同。这就是为什么在不同的有界上下文中有不同的用户对象。它们是每个用例对同一业务对象的一种视角。
如果在一个有界上下文中修改业务对象,它可以发出业务事件。另一个功能可以监听这些事件。事件机制可以是简单的观察者模式,或者如果您需要通过微服务消息队列分发应用程序功能。如果您使用简单的观察者模式,事件发射器和事件处理程序可以在同一数据源事务中运行。但它们也可以在不同的环境中运行。这取决于您的需求。
因此,当注册用例注册新用户时,它会发出一个UserSignedUpEvent. 其他功能现在可以侦听此事件。该事件携带用户的信息,例如电子邮件、姓名、个人资料图片以及用户在注册期间提供的其他信息。其他功能现在可以将他们需要的数据保存到自己的数据源中。它可以与注册用例使用的相同(只是其他表或另一个模式)。但也有可能是完全不同的数据源,可能是另一种数据源,例如 nosql 数据库。如果您有不同的数据源,我上面写的有关事务的部分当然会更困难。
要点是每个功能都有自己的数据并对其进行管理。它可能是整个用户信息的副本,但在很多情况下它只是一个子集。
基于事件的方法可以为您提供完美的模块化。但正如事情总是看起来很棒一样,它是有代价的。您必须复制某些部分甚至全部数据。当您考虑微服务架构时,某些功能位于不同的微服务中,这意味着重复增加了服务的可用性。即使管理数据的主服务关闭,该服务也可以运行,因为存在本地副本。但现在你必须处理一致性问题——最终一致性。
此时,我想停下来引导您到其他来源了解详细信息:
| 归档时间: |
|
| 查看次数: |
2009 次 |
| 最近记录: |