六邊形架構是一種設計風格,通過分層實現核心邏輯與外部對象隔離。其核心邏輯是業務模塊,外部元素是整合點,比如數據庫、外部 API、界面等。它將軟件分爲內部與外部,內部包含了核心業務邏輯與領域層(所謂分層架構),外部包含界面、數據庫、消息傳遞及其他內容。內部與外部通過端口和適配器相互通信。
*譯註:六邊形架構(Hexagonal Architecture)由Alistair Cockburn 提出,解決了傳統的分層架構所帶來的問題。*
1. 優點
使用六邊形架構開發的軟件與通道獨立,因此能支持多通道
易於置換入站和出站整合點
測試軟件變得更簡單,因爲可以很容易地模擬集成點
2. Java 實現
按照上面的描述,六邊形架構更多地是圍繞端口和適配器開展工作。在 Java 中,用 interface 定義端口,實現類作爲適配器。下面用一個簡單的 Spring Boot 應用示例瞭解如何應用六邊形架構。
示例應用主要功能是創建並查看僱員信息,核心業務邏輯在 `EmployeeService` 中實現,領域對象定義爲 `Employee` ,這些都可以看做內部模塊。
**EmployeeService.java** ```java @Service public class EmployeeService { @Autowired private EmployeeRepositoryPort employeeRepository; public void create(String name, String role, long salary){ employeeRepository.create(name, role, salary); } public Employee view(Integer userId){ return employeeRepository.getEmployee(userId); } } ```
**Employee.java** ```java @Entity @Table(name = "employee") public class Employee{ @Id @GeneratedValue @Column(name = "id") private Integer id; @Column(name = "name", nullable = false) private String name; @Column(name = "role", nullable = false) private String role; @Column(name = "salary", nullable = false) private long salary; // Setter、Getter 方法 } ```
現在,示例應用可以通過 REST 或消息機制提供服務。創建實現了 `EmployeeUIPort` 接口的`EmployeeControllerAdapter` 類提供 REST 服務。
**EmployeeControllerAdapter.java** ```java RestController @RequestMapping("/employees/") public class EmployeeControllerAdapter implements EmployeeUIPort{ @Autowired private EmployeeService employeeService; @Override public void create(@RequestBody Employee request) { employeeService.create(request.getName(), request.getRole(), request.getSalary()); } @Override public Employee view(@PathVariable Integer id) { Employee employee = employeeService.view(id); return employee; } } ```
```java public interface EmployeeUIPort { @PostMapping("create") public void create(@RequestBody Employee request); @GetMapping("view/{id}") public Employee view(@PathVariable Integer userId); } ```
作爲業務邏輯的一部分,`EmployeeService` 還需要調用外部 DB 集成點。因此,我們創建了`EmployeeRepositoryPort` 以及實現了該接口的 `EmployeeServiceAdapter`。
**EmployeeServiceAdapter.java** ```java @Service public class EmployeeServiceAdapter implements EmployeeRepositoryPort { @PersistenceContext private EntityManager entityManager; @Transactional @Override public void create(String name, String role, long salary) { Employee employee = new Employee(); employee.setName(name); employee.setRole(role); employee.setSalary(salary); entityManager.persist(employee); } @Override public Employee getEmployee(Integer userId) { return entityManager.find(Employee.class, userId); } } ```
**EmployeeRepositoryPort.java** ```java public interface EmployeeRepositoryPort { void create(String name, String role, long salary); Employee getEmployee(Integer userId); } ```
至此,我們可以看到 `EmployeeService` 是如何使用 `EmployeeUIPort` 端口提供服務,通過 `EmployeeRepositoryPort` 調用 DB 並通過 `EmployeeControllerAdapter`和`EmployeeServiceAdapter` 提供 REST API 服務。
3. 總結
總結一下,六邊形架構是一種將應用劃分成內外兩部分的設計方法。通過內部公開的端口與外部實現的適配器進行溝通。應用這種方法,在保持核心用例代碼不變的情況下,可以服務多個通道、支持多種不同協議。 不僅如此,它還能有效提高應用程序的可測性。儘管如此,不建議在整個應用中完全實現六邊形架構,而是有選擇地使用接口與適配器。
歡迎工作一到五年的Java工程師朋友們加入Java程序員開發: 721575865
羣內提供免費的Java架構學習資料(裏面有高可用、高併發、高性能及分佈式、Jvm性能調優、Spring源碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)合理利用自己每一分每一秒的時間來學習提升自己,不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代!