示例缓存未按用户 ID 区分,可能向请求者返回另一用户的资料
原文依据:2 处示例 Repository 只保存一个 `_cachedUser`。`getUser(id)` 只要缓存非空就立即返回它,并不会确认缓存用户的 ID 是否等于本次请求的 ID。
如果作者或代理把该示例用于可查询多个账户的应用,同一个 Repository 实例先后处理不同用户时,后一次请求可能看到前一个用户的姓名或其他被扩展进模型的资料,同时也会造成错误的账户决策。
该风险由示例代码直接支持,但只会在同一个 `UserRepository` 实例先后查询不同用户 ID 时出现:缓存一旦非空,方法便直接返回旧用户,没有比较本次 `id`。如果用户照搬此示例并在多个账户或资料请求间共享 Repository,界面可能显示另一位先前查询用户的资料。证据只是教学示例,不能证明任何应用已经采用或泄露数据;用户可要求作者将缓存按 ID 建键,或在返回前核对缓存用户 ID。
final ApiClient _apiClient; User? _cachedUser; Future<User> getUser(String id) async { if (_cachedUser != null) return _cachedUser!; final apiModel = await _apiClient.fetchUser(id); _cachedUser = User(id: apiModel.id, name: apiModel.fullName); // Transform to Domain Model return _cachedUser!; }查看另外 1 个位置
// 2. Repository (Single source of truth, returns Domain Model)class UserRepository { UserRepository({required ApiClient apiClient}) : _apiClient = apiClient; final ApiClient _apiClient; User? _cachedUser; Future<User> getUser(String id) async { if (_cachedUser != null) return _cachedUser!; final apiModel = await _apiClient.fetchUser(id); _cachedUser = User(id: apiModel.id, name: apiModel.fullName); // Transform to Domain Model return _cachedUser!; }