Java中六边形架构的快速实用实例
软件设计模式的实践
1.概述
六边形架构是由Alistair Cockburn首次提出的一种软件设计模式。它提供了一种使用Java或Java相关框架(如Spring)设计Web应用架构的意见。在这篇文章中,我们将研究Java中的六边形架构,并在一个使用Spring框架实现的实际例子的帮助下展示其用法。
2.六边形架构
六边形架构的主要思想是通过接口隔离原则对逻辑进行明确隔离。此外,六边形架构通过端口和适配器的概念创建松散耦合的应用程序。这里的端口指的是接口,适配器指的是其实现类(如下图所示)。
六角架构
上图显示了典型的六边形架构中的各种端点。通过应用层,用户通过端口和适配器与核心应用逻辑进行交互。应用层由GUI客户端、社交媒体客户端、HTTP/API调用等组成。同样地,应用程序的另一半显示了持久性或基础设施层,数据通过它流向其他组件。持久层包含外部组件,如数据库、邮件和消息传递队列等。
3.例子
为了更好地理解六边形架构,让我们考虑一个比萨饼服务应用程序的例子。在这个应用程序中,我们将有以下功能。
- 列出所有可用的比萨饼
- 在数据库中插入一个新的比萨饼
- 通过名称获取比萨饼
4.域对象
域或实体对象是六边形架构的核心部分。它可以有状态和行为。这个对象对任何应用组件都没有任何依赖性。如果业务需求本身有变化,领域对象的任何变化都会发生。
public class Pizza { private String name; private int price; private String[] toppings; // code for getters & setters}
5.5.端口
六边形架构中的端口是指允许入站或出站的接口。一个入站端口将核心应用功能暴露给外部世界。例如,对服务接口的API调用。
让我们定义一个PizzaService接口,将其功能暴露给外部组件(如API调用)。这就是我们的入站端口。
public interface PizzaService { public void createPizza(Pizza pizza); public Pizza getPizza(String name); public List<Pizza> laodPizza();}
同样地,出站端口用于连接到一些外部资源库,如数据库。
让我们定义一个PizzaRepository,它将访问外部持久化系统(DB)。
public interface PizzaRepo { public void createPizza(Pizza pizza); public Pizza getPizza(String name); public List<Pizza> getAllPizza();}
6.适配器
适配器指的是六边形架构中各自端口的实现类。它们是应用程序的外部部分(如GUI、API调用、Webviews、Dao等),分别通过入站和出站端口与应用程序交互。此外,适配器使得交换应用程序的特定层变得简单。根据所需的变化,我们只需要添加一个实现输入或输出端口的适配器。
6.1 初级适配器
它们也被称为输入或驱动适配器,因为它们通过使用入站端口调用应用程序的核心部分来驱动应用程序。
让我们把PizzaRestContoller 定义为一个REST控制器作为我们的主要适配器。它为创建和获取披萨提供端点,也实现了PizzaRestUI(Webview)。除此之外,它还使用PizzaService (入站端口)来调用不同的方法。
@RestController@RequestMapping(value="/pizza")public class PizzaRestController implements PizzaRestUI { @Autowired private PizzaService pizzaService; @Override public void createPizza(@RequestBody Pizza pizza) { pizzaService.createPizza(pizza); } @Override public Pizza getPizza(@PathVariable String name) { return pizzaService.getPizza(name); } @Override public List<Pizza> listPizza() { return pizzaService.laodPizza(); }}
6.2 二级适配器
它们被称为输出或驱动适配器,实现了一个出站端口接口。这些适配器提供了一个实现,用于访问应用程序的二级组件,如数据库、消息传递队列等。在服务层实现输入端口的同时,使用持久化层实现输出端口。
在我们的例子中,PizzaRepoImpl是实现PizzaRepo (出站端口)的出站适配器。
@Repositorypublic class PizzaRepoImpl implements PizzaRepo { private Map<String, Pizza> pizzaStore = new HashMap<String, Pizza>(); @Override public void createPizza(Pizza pizza) { pizzaStore.put(pizza.getName(), pizza); } @Override public Pizza getPizza(String name) { return pizzaStore.get(name); } @Override public List<Pizza> getAllPizza() { return pizzaStore.values().stream().collect(Collectors.toList()); }}
接下来,我们可以使用任何API测试工具如Postman来测试GET和POST端点。
我们可以通过*http://localhost:8080/pizza-service/pizza/*来测试POST端点。
{ "name" : "Margherita", "price": "25", "toppings" : ["tomato","onion","cucumber","jalapeno"]}
同样地,我们可以通过http://localhost:8080/pizza-service/pizza/Margherita 来测试GET端点。
{ "name": "Margherita", "price": 25, "toppings": [ "tomato", "onion", "cucumber", "jalapeno" ]}
7.优点
与传统的分层架构相比,六边形架构有几个优点,比如。
- 它通过分离应用程序的内部和外部组件简化了架构设计
- 核心业务逻辑与任何外部依赖关系分离,从而实现高度解耦
- 基于端口的架构允许我们的应用程序轻松地适应新的渠道或使用新的通信协议,这在开发领域驱动的应用程序时非常有用。
8.结语
在这篇文章中,我们通过一个用Spring框架实现的简单例子了解了Java中的六边形架构。此外,我们还讨论了使用六边形架构比传统分层架构的一些优势。
所给例子的代码可以在Github上找到。