Event Driven Architecture
事件驅動設計
Last updated
Was this helpful?
事件驅動設計
Last updated
Was this helpful?
行為松耦合制度,提升未來擴充性
已提交姓名變更事件
已驗證失敗事件
已變更姓名事件
graph LR;
cmd(提交commmand) --> submit
submit(已提交Event)-->ok(已完成姓名變更Event);
submit-->fail(已驗證失敗Event);
當【事件發生】,驅動另一件事件
@Slf4j
@RequiredArgsConstructor
public class NamedEventChannel implements IChannel<NamedEvent> {
private final ChangeNameUseCase changeNameUseCase;
@Override
public void dispatch(NamedEvent message) {
changeNameUseCase.change(message);
}
}
身分證、變更後姓名必填
變更後姓名不得空白
姓名變更最多3次
使用者【UserAggregate】
/**
* 使用者
*
*/
@Data
public class UserAggregate {
private String id;// 統一編號
private String name;
private int changeNameCount = 0;// 姓名變更次數
測試Happy Path路徑
/**
* 輸入正確性名,變更次數小於等於3,取得變更成功事件
*/
@Test
void testCurrentNameAndCountLess3ReturnNamedEvent() {
// GIVE
SubmitNameUseCommand submitNameUseCommand = new SubmitNameUseCommand();
submitNameUseCommand.setId(A123456789);
submitNameUseCommand.setNewNmae(NEW_NAME);
// WHEN
UserAggregate userAggregate = new UserAggregate();
userAggregate.setId(A123456789);
userAggregate.setName(A123456789);
userAggregate.setName(OLD_NAME);
userAggregate.setChangeNameCount(0);
Mockito.when(userAggregateRepository.findById(A123456789)).thenReturn(userAggregate);
// THEN
SubmitNameUseCase submitNameUseCase = new SubmitNameUseCase(userAggregateRepository);
Event event = submitNameUseCase.submit(submitNameUseCommand);
assertThat(event).isExactlyInstanceOf(NamedEvent.class);
NamedEvent namedEvent = (NamedEvent) event;
assertThat(namedEvent.getId()).isEqualTo(A123456789);
assertThat(namedEvent.getNewName()).isEqualTo(NEW_NAME);
assertThat(namedEvent.getOldName()).isEqualTo(OLD_NAME);
assertThat(namedEvent.getChangeNameCount()).isEqualTo(1);
}
撰寫提交案例
@RequiredArgsConstructor
public class SubmitNameUseCase {
private final IUserAggregateRepository userAggregateRepository;
Event submit(SubmitNameUseCommand command) {
UserAggregate user = userAggregateRepository.findById(command.getId());
if (user == null) {
VerifiedFailNameEvent verifiedFailNameEvent = new VerifiedFailNameEvent();
verifiedFailNameEvent.setMessage("帳號不存在:" + command.getId());
return verifiedFailNameEvent;
}
return user.changeName(command);
}
}
使用者行為操作
@Data
public class UserAggregate {
private String id;// 統一編號
private String name;
private int changeNameCount = 0;// 姓名變更次數
public Event changeName(SubmitNameUseCommand command) {
try {
this.checkchangeName(command);
final NamedEvent namedEvent = new NamedEvent();
namedEvent.setOldName(this.name);
namedEvent.setNewName(command.getNewNmae());
namedEvent.setId(id);
namedEvent.setChangeNameCount(++changeNameCount);
this.name = command.getNewNmae();
return namedEvent;
} catch (ApBusinessException e) {
VerifiedFailNameEvent verifiedFailNameEvent = new VerifiedFailNameEvent();
verifiedFailNameEvent.setMessage(e.getMessage());
return verifiedFailNameEvent;
}
}