美文网首页
用java快速实现一个六边形架构的例子

用java快速实现一个六边形架构的例子

作者: water_lang | 来源:发表于2019-01-08 15:46 被阅读0次
    图片.png

    您是否遇到过将业务逻辑与UI或者n层体系结构中的其他方法混合在一起的混乱代码?您是否曾经也遇到过这样的问题,当你在测试业务逻辑的时候并没有将应用程序和数据库隔离开来?幸运的是,Hexagonal Architecture(例如:端口和适配器架构,此名称将在此后通过本教程使用)来可以帮助你解决问题。

    Loyalty应用

    现在,让我们以一个例子来开始Ports&Adapters旅程。我们正在构建一个客户忠诚度(loyalty)应用程序,该应用程序能够注册客户,升级和降级客户状态。

    这个应用程序由三个组成部分。第一个组件appcore是整个应用程序的核心,主要包括业务领域对象和业务逻辑的实现。appcore组件无法单独执行任何操作。然后,第二个组件是command-console-adapter他主要是接收请求并通过命令行控制台驱动appcore组件中的所有业务方法。 最后一个组件inmemory-repository-adapter作为内存数据存储解决方案,它处理所有与数据存储相关的方法。此组件提供来自appcore的调用,并相应地提供响应。

    Application Core(应用核心)

    该组件代表整个架构的业务核心。然后定义端口,在架构上下文中,端口表示对不同的业务案例提供对应的扩展和支持。在大多数语言中,可以把他理解成是一个接口(因为接口具有多态能力)。

    初始化和驱动业务核心的端口是主端口。来自业务核心调用的服务和响应端口是辅助端口。

    在我们的例子中,CustomerService接口就是主端口,CustomerRepository接口是辅助端口。我们可以看到端口通常是业务核心组件的一部分,如本例中的appcore。

    CustomerRepository接口有关于数据存储相关的方法:

    package com.codespeaks.hexagonal.repository;
    import java.util.List;
    import java.util.Optional;
    import com.codespeaks.hexagonal.domain.Customer;
    import com.codespeaks.hexagonal.exception.CustomerNotFoundException;
    
    public interface CustomerRepository {
        public Customer CreateCustomer(Customer customer);
        public Customer UpdateCustomer(Customer customer) throws CustomerNotFoundException;
        public List<Customer> findAll();
        public Optional<Customer> findCustomerById(int customerId);
    }
    

    然后,CustomerService接口暴露所有业务方法:

    package com.codespeaks.hexagonal.service;
    import java.util.List;
    import java.util.Optional;
    import com.codespeaks.hexagonal.domain.Customer;
    import com.codespeaks.hexagonal.exception.CustomerNotFoundException;
    public interface CustomerService {
        public Customer registerCustomer(Customer customer);
        public Customer upgradeCustomer(Customer customer) throws CustomerNotFoundException;
        public Customer downgradeCustomer(Customer customer) throws CustomerNotFoundException;
        public List<Customer> getAllCustomers();
        public Optional<Customer> findCustomerById(int customerId);
    }
    

    内存Repository 适配器

    在端口&适配器架构中他是一个适配器组件。适配器表示端口的实现,以满足不同的业务需求。有时,它可能只是一个简单的实现接口的类。有时,它可能是涉及第三方服务的库的集合。根据适配器实现的端口,我们还有主适配器和辅助适配器。

    在组件inmemory-repository-adapter中,类InMemoryCusotmerRepositoryImpl实现接口CustomerRepository。他为组件appcore提供内存中数据操作调用,因此它是辅助适配器。

    命令控制台适配器

    这是本示例中的另一个适配器组件:命令控制台适配器。它包含CommandInterface接口以与命令控制台的输入进行交互:

    package com.codespeaks.hexagonal.adapter.console;
    import java.util.Scanner;
    public interface CommandInterface {
        public void list(Scanner scanner);
        public void register(Scanner scanner);
        public void upgrade(Scanner scanner);
        public void downgrade(Scanner scanner);
        public void info();
    }
    

    虽然端口通常被描述为接口,但这个组件中的接口CommandInterface根本不是端口。从架构的角度来看,组件整体代表适配器。通过它的实现CommandInterfaceImpl,它使CustomerService适应命令控制台操作。

    该适配器组件是主适配器,因为它通过主端口CustomerService驱动整个应用程序。

    总结:

    如示例所示,端口和适配器之间的边界很清晰。业务逻辑不会透过业务核心边界并泄漏到周围适配器,反过来也是一样的。

    要添加Web展示端与业务核心进行交互,我们可以通过创建另一个适配器组件web-ui-apdater来实现此目标。 因此,它对任何其他现有代码逻辑没有影响。我们还可以为事件通知定义新端口和各种适配器实现,并记录日志以满足业务需求。

    它还有益于对业务核心组件和任何适配器的集成测试。可以使用子实现来轻松替换每个相关组件,以便可以轻松地测试任何组件。

    代码例子在: https://github.com/letcodespeak/hexagonal-architecture

    相关文章

      网友评论

          本文标题:用java快速实现一个六边形架构的例子

          本文链接:https://www.haomeiwen.com/subject/sofbrqtx.html