Ada*_*ion 5 java oop domain-driven-design
我有一个不可变的User实体:
public class User {
final LocalDate lastPasswordChangeDate;
// final id, name, email, etc.
}
Run Code Online (Sandbox Code Playgroud)
我需要添加一个方法,如果必须更改用户的密码,则该方法将返回信息,而不是因为passwordValidIntervalInDays系统设置更改了该密码.
目前的做法:
public class UserPasswordService {
private SettingsRepository settingsRepository;
@Inject
public UserPasswordService(SettingsRepository settingsRepository) {
this.settingsRepository = settingsRepository;
}
public boolean passwordMustBeChanged(User user) {
return user.lastPasswordChangeDate.plusDays(
settingsRepository.get().passwordValidIntervalInDays
).isBefore(LocalDate.now());
}
}
Run Code Online (Sandbox Code Playgroud)
问题是如何使上面的代码更加面向对象并避免贫血域模型反模式?是否应该将passwordMustBeChanged方法移动到User如何访问SettingsRepository,是否应该将其注入到User构造函数中,还是应该Settings向ctor提供实例,或者该passwordMustBeChanged方法是否需要提供Settings实例?
代码Settings和SettingsRepository并不重要,但对于完整性,这里是:
public class Settings {
int passwordValidIntervalInDays;
public Settings(int passwordValidIntervalInDays) {
this.passwordValidIntervalInDays = passwordValidIntervalInDays;
}
}
public class SettingsRepository {
public Settings get() {
// load the settings from the persistent storage
return new Settings(10);
}
}
Run Code Online (Sandbox Code Playgroud)
对于系统范围的密码过期策略,您的方法并没有那么糟糕,只要您UserPasswordService是域服务,而不是应用程序服务。在 User 中嵌入密码过期策略将违反 SRP 恕我直言,这也好不了多少。
您还可以考虑类似的内容(工厂使用正确的设置进行初始化):
PasswordExpirationPolicy policy = passwordExpirationPolicyFactory().createDefault();
boolean mustChangePassword = user.passwordMustBeChanged(policy);
//class User
public boolean passwordMustBeChanged(PasswordExpirationPolicy policy) {
return policy.hasExpired(currentDate, this.lastPasswordChangeDate);
}
Run Code Online (Sandbox Code Playgroud)
如果最终可以为单个用户指定策略,那么您可以简单地将策略对象存储在 上User。
您还可以将 ISP 与您当前的设计结合使用,并PasswordExpirationPolicy在您的服务上实现一个接口UserPasswordService。这将为您提供稍后重构为实际策略对象的灵活性,而无需更改User与策略的交互方式。
如果你有一个Password值对象,你也可以通过类似的方式让事情变得更有凝聚力(密码创建日期将嵌入到密码 VO 中):
//class User
public boolean passwordMustBeChanged(PasswordExpirationPolicy policy) {
return this.password.hasExpired(policy);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
270 次 |
| 最近记录: |