番茄架构是遵循Common Sense Manifesto的软件架构的一种方法
Common Sense Manifesto
- 选择适合你的软件的架构而不是流行的的架构: 在盲目追随流行人物的建议之前,要考虑软件最佳实践。
- 不要过度设计: 努力保持简单,而不是过度工程化,试图猜测未来十年的需求。
- 进行研究与开发,选择一项技术并拥抱它,而不是为了可替代性而创建抽象层。
- 确保你的解决方案作为整体工作正常,而不仅仅是单个组件。
架构图
实施指南(架构核心:关注点分离):
-
按功能进行打包
将代码按照功能分成不同的包是一种常见的模式,通常会根据技术层次(如 controllers, services, repositories等)进行划分。如果你正在构建一个专注于特定模块或业务能力的微服务,那么这种方法可能是可行的。
如果你正在构建一个单体应用或者模块化单体应用,强烈建议首先按照功能而非技术层进行划分。
详细信息请阅读链接: https://phauer.com/2020/package-by-feature/
-
“应用核心”独立于交付机制(Web, Scheduler Jobs, CLI)
应用核心应该公开可以从主方法调用的API。为了实现这一点,“应用核心”不应该依赖于其调用上下文。这意味着“应用核心”不应依赖于任何HTTP/Web层的库。同样,如果你的应用核心被用于定时任务或命令行接口,任何调度逻辑或命令行执行逻辑都不应泄露到应用核心中。
-
将业务逻辑执行与输入源(Web Controllers, Message Listeners, Scheduled Jobs等)分离
输入源,如Web Controllers, Message Listeners, Scheduled Jobs等,应该是很薄的一层,在提取请求数据后将实际的业务逻辑执行委托给“应用核心”。
比如:
坏味道:
@RestController
class 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);
}
}
纠正:
@RestController
class CustomerController {
private final CustomerService customerService;
@PostMapping("/api/customers")
void createCustomer(@RequestBody Customer customer) {
customerService.save