(资料图)
番茄(tomato)架构是一种遵循常识宣言的软件架构方法:
1、将业务逻辑执行与输入源(Websearch控制器、消息监听器、计划作业等)分开Websearch控制器、消息监听器、计划作业等输入源应该是一个薄层,从请求中提取数据并将实际业务逻辑执行委托给“应用程序核心”。不要这样做:
@RestControllerclass CustomerController { private final CustomerService customerService; @PostMapping("/api/customers") void createCustomer(@RequestBody Customer customer) { if(customerService.existsByEmail(customer.getEmail())) { throw new EmailAlreadyInUseException(customer.getEmail()); } customer.setCreateAt(Instant.now()); customerService.save(customer); }} |
相反,这样做:
@RestControllerclass CustomerController { private final CustomerService customerService; @PostMapping("/api/customers") void createCustomer(@RequestBody Customer customer) { customerService.save(customer); }}@Service@Transactionalclass CustomerService { private final CustomerRepository customerRepository; void save(Customer customer) { if(customerRepository.existsByEmail(customer.getEmail())) { throw new EmailAlreadyInUseException(customer.getEmail()); } customer.setCreateAt(Instant.now()); customerRepository.save(customer); }} |
使用这种方法,无论您是尝试从 REST API 调用还是从 CLI 创建客户,所有业务逻辑都集中在 Application Core应用程序核心 中。
2、不要让“外部服务集成”对“应用程序核心”的影响太大从应用程序核心中,我们可以与数据库、消息代理或第 3 方 Web 服务等进行对话。必须注意业务逻辑执行者不要严重依赖外部服务集成。例如,假设您正在使用 Spring Data JPA 进行持久化,并且您希望使用分页从CustomerService获取客户。不要这样做:
@Service@Transactionalclass CustomerService { private final CustomerRepository customerRepository; PagedResult |
相反,这样做
@Service@Transactionalclass CustomerService { private final CustomerRepository customerRepository; PagedResult |
这样,任何持久性库更改都只会影响存储库层。
3、将领域逻辑保留在领域对象中有影响领域对象状态更改方法或从对象状态计算某些内容的方法,则将这些方法放入该域对象。不要这样做
class Cart { List |
相反,应该这样做:
class Cart { List |