万字长文+示例代码详解DDD中常用的架构(含代码示例)

目录

分层架构(Layered Architecture)

概念

示例代码

总结

领域驱动设计的六边形架构(Hexagonal Architecture)

概念

示例代码

总结

CQRS(Command Query Responsibility Segregation)

概念

示例代码

总结

微服务架构(Microservices Architecture)

概念

示例代码

总结

领域事件驱动架构(Domain Event-Driven Architecture)

概念

示例代码

总结

如何选择?


分层架构(Layered Architecture)

概念

分层架构是一种常见的架构模式,将应用程序分为不同的层次,每个层次有特定的职责。典型的分层架构包括表示层(Presentation Layer)、应用层(Application Layer)、领域层(Domain Layer)和基础设施层(Infrastructure Layer)。分层架构能够将关注点分离,提高系统的可维护性和可扩展性。

常见的分层架构通常包括以下几个层次:

  1. 表示层(Presentation Layer):表示层负责处理用户界面和用户交互。它可以是Web界面、移动应用程序界面或其他用户界面。表示层负责接收用户的请求,将其转发给应用层进行处理,并将应用层的响应反馈给用户。

  2. 应用层(Application Layer):应用层是系统的核心,负责协调业务逻辑的执行。它接收来自表示层的请求,将请求转化为适当的领域操作,并协调领域层的对象进行处理。应用层不包含具体的业务逻辑,而是将业务逻辑委托给领域层。

  3. 领域层(Domain Layer):领域层包含系统的核心业务逻辑和领域模型。它包含了领域对象、实体、值对象以及领域服务。领域层负责实现业务规则、验证和状态变更等核心领域逻辑。

  4. 基础设施层(Infrastructure Layer):基础设施层提供与外部系统的交互,如数据库、文件系统、消息队列等。它包含了各种技术实现和框架,用于支持应用程序的运行。基础设施层还可以包括数据访问层、消息传递层、日志记录等。

示例代码

举一个栗子,如下:

// 表示层
public class UserController {
    private UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    public void createUser(String name, String email, String password) {
        // 处理用户创建请求
        userService.createUser(name, email, password);
        // 返回响应给用户
    }

    // 其他用户相关操作的方法
}

// 应用层
public class UserService {
    private UserRepository userRepository;
    // 可能还有其他依赖注入的服务或组件

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void createUser(String name, String email, String password) {
        // 执行业务逻辑,如验证、密码加密等
        User user = new User(name, email, password);
        userRepository.save(user);
    }

    // 其他用户相关操作的方法
}

// 领域层
public class User {
    private String name;
    private String email;
    private String password;

    public User(String name, String email, String password) {
        // 属性赋值和验证等逻辑
    }

    // 其他领域逻辑和操作的方法
}

// 基础设施层
public class UserRepository {
    public void save(User user) {
        // 将用户保存到数据库
    }

    // 其他数据库操作的方法
}

// 在应用程序的入口点或配置中,组装和注入各个层次的对象
public class Application {
    public static void main(String[] args) {
        UserRepository userRepository = new UserRepository();
        UserService userService = new UserService(userRepository);
        UserController userController = new UserController(userService);

        // 启动应用程序,处理用户请求等
    }
}

将应用程序分为表示层、应用层、领域层和基础设施层。每个层次都有明确的职责,表示层处理用户界面和交互,应用层协调业务逻辑的执行,领域层包含核心业务逻辑和领域模型,基础设施层处理与外部系统的交互。

总结

通过分层架构,我们可以将关注点分离,使代码更易于维护、测试和扩展。每个层次可以独立变化,而不会对其他层次产生过多影响。这种组织方式可以帮助我们更好地遵循领域驱动设计的原则,并支持清晰的代码组织和职责划分。

领域驱动设计的六边形架构(Hexagonal Architecture)

概念

领域驱动设计的六边形架构(Hexagonal Architecture),也被称为端口和适配器模式(Ports and Adapters Pattern),是一种用于构建可测试、可扩展和松耦合系统的架构模式。它强调将领域模型作为核心,并将其与外部系统隔离开来,以便更好地实现领域模型的独立演化。

在六边形架构中,系统被视为一个六边形,核心领域模型位于中心,与外部系统通过适配器(Adapter)进行交互。领域模型定义了系统的核心业务逻辑和领域对象,而适配器负责将外部系统与领域模型连接起来。

示例代码

// 领域模型
public class Product {
    private String name;
    private String description;
    private BigDecimal price;

    // 构造函数、属性和方法等
}

// 适配器接口
public interface ProductRepository {
    void save(Product product);
    Product getById(String id);
    List<Product> getAll();
    // 其他与数据存储相关的方法
}

// 适配器实现
public class InMemoryProductRepository implements ProductRepository {
    private Map<String, Product> productMap = new HashMap<>();

    @Override
    public void save(Product product) {
        productMap.put(product.getId(), product);
    }

    @Override
    public Product getById(String id) {
        return productMap.get(id);
    }

    @Override
    public List<Product> getAll() {
        return new ArrayList<>(productMap.values());
    }
}

// 领域服务接口
public interface ProductService {
    void createProduct(String name, String description, BigDecimal price);
    Product getProductById(String id);
    List<Product> getAllProducts();
    // 其他领域服务方法
}

// 领域服务实现
public class ProductServiceImpl implements ProductService {
    private ProductRepository productRepository;

    public ProductServiceImpl(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }

    @Override
    public void createProduct(String name, String description, BigDecimal price) {
        Product product = new Product(name, description, price);
        productRepository.save(product);
    }

    @Override
    public Product getProductById(String id) {
        return productRepository.getById(id);
    }

    @Override
    public List<Product> getAllProducts() {
        return productRepository.getAll();
    }

    // 其他领域服务方法的实现
}

// 在应用程序的入口点或配置中,组装和注入适配器和领域服务
public class Application {
    public static void main(String[] args) {
        ProductRepository productRepository = new InMemoryProductRepository();
        ProductService productService = new ProductServiceImpl(productRepository);

        // 启动应用程序,使用领域服务进行业务操作
    }
}

在上面的栗子中,我们有一个核心的领域模型Product,它表示产品实体。然后,我们定义了适配器接口ProductRepository,它定义了与数据存储相关的操作。InMemoryProductRepository是一个适配器的实现,它使用内存来存储产品数据。在领域服务方面,我们定义了ProductService接口,它提供了对产品领域的操作。ProductServiceImpl是领域服务的具体实现,它依赖于ProductRepository适配器进行数据存储。领域模型和领域服务就位于系统的核心位置,与外部系统通过适配器进行交互。

总结

六边形架构的优势在于它的灵活性和可测试性。通过将领域模型与外部系统隔离开来,我们可以独立地测试领域逻辑,并对外部系统进行模拟或替代。此外,六边形架构还支持领域模型的独立演化,使系统更具灵活性和可扩展性。

CQRS(Command Query Responsibility Segregation)

概念

CQRS 是一种将读操作(Query)和写操作(Command)分离的架构模式。它通过将读模型和写模型分开来优化系统的可扩展性和性能。在 CQRS 中,读操作可以通过专门的查询模型进行处理,而写操作则由领域模型负责。

在传统的 CRUD(Create, Read, Update, Delete)模式中,通常将读写操作合并在同一个接口或服务中。而在 CQRS 中,将读操作和写操作分离为独立的接口和服务,分别针对不同的需求进行优化。

示例代码

// Command 模型
public class CreateUserCommand {
    private String name;
    private String email;
    private String password;

    // 构造函数、属性和方法等
}

// Command 处理器
public class UserCommandHandler {
    public void handleCreateUserCommand(CreateUserCommand command) {
        // 执行创建用户的业务逻辑,包括验证、密码加密等
        User user = new User(command.getName(), command.getEmail(), command.getPassword());
        // 将用户保存到数据库或事件日志等
    }

    // 其他 Command 处理器的方法
}

// Query 模型
public class GetUserQuery {
    private String userId;

    // 构造函数、属性和方法等
}

// Query 处理器
public class UserQueryHandler {
    public User handleGetUserQuery(GetUserQuery query) {
        // 查询用户的业务逻辑,可能涉及数据库查询、缓存等
        User user = // 从数据库或缓存中获取用户信息
        return user;
    }

    // 其他 Query 处理器的方法
}

// 在应用程序的入口点或配置中,组装和注入 Command 处理器和 Query 处理器
public class Application {
    public static void main(String[] args) {
        UserCommandHandler commandHandler = new UserCommandHandler();
        UserQueryHandler queryHandler = new UserQueryHandler();

        // 启动应用程序,处理命令和查询
    }
}

代码中,Command 模型和对应的 Command 处理器,用于处理写操作。CreateUserCommand表示创建用户的命令,UserCommandHandler负责处理该命令并执行相应的业务逻辑。Query 模型和对应的 Query 处理器,用于处理读操作。GetUserQuery表示获取用户的查询,UserQueryHandler负责处理该查询并返回相应的结果。

总结

CQRS 的优势在于它能够根据不同的操作类型进行优化,提高系统的性能和可伸缩性。通过将读写操作分离,可以针对不同的操作类型采用不同的数据存储和处理方式。此外,CQRS 还能够帮助实现更好的领域模型设计,使系统更加灵活和可扩展。

微服务架构(Microservices Architecture)

概念

微服务架构是一种将应用程序拆分为一组小型、独立部署的服务的架构模式。每个微服务都专注于某个特定的业务领域,并通过轻量级的通信机制进行交互。微服务架构有助于团队的自治性和系统的可扩展性,但也增加了系统的复杂性。

微服务架构的主要特点包括:

  1. 服务拆分:应用程序被拆分为多个小型服务,每个服务具有清晰的边界和独立的责任。

  2. 独立部署:每个服务可以独立地进行开发、测试、部署和扩展,不会影响其他服务。

  3. 松耦合通信:服务之间使用轻量级的通信机制进行通信,如RESTful API、消息队列等。

  4. 基础设施自治:每个服务可以选择适合自身需求的技术栈和基础设施,不受其他服务的限制。

示例代码

// 用户服务
public class UserService {
    public User createUser(String name, String email) {
        // 创建用户的业务逻辑
        User user = new User(name, email);
        // 保存用户到数据库
        return user;
    }

    public User getUserById(String userId) {
        // 根据用户ID查询用户的业务逻辑
        // 从数据库或缓存中获取用户信息
        return user;
    }
    
    // 其他用户相关的业务逻辑和操作方法
}

// 订单服务
public class OrderService {
    public Order createOrder(String userId, List<Product> products) {
        // 创建订单的业务逻辑
        User user = userService.getUserById(userId);
        // 根据产品信息计算订单金额等
        Order order = new Order(user, products);
        // 保存订单到数据库
        return order;
    }

    public Order getOrderById(String orderId) {
        // 根据订单ID查询订单的业务逻辑
        // 从数据库或缓存中获取订单信息
        return order;
    }
    
    // 其他订单相关的业务逻辑和操作方法
}

// 在应用程序的入口点或配置中,组装和注入各个微服务对象
public class Application {
    public static void main(String[] args) {
        UserService userService = new UserService();
        OrderService orderService = new OrderService(userService);

        // 启动应用程序,处理用户请求等
    }
}

两个微服务:用户服务(UserService)和订单服务(OrderService)。每个服务都有自己的业务逻辑和操作方法,并通过依赖注入的方式组装和协调。微服务之间可以使用RESTful API或其他通信机制进行通信。例如,在订单服务中,我们通过调用用户服务的getUserById方法来获取用户信息。

总结

通过微服务架构,我们可以将大型应用程序拆分为多个小型服务,每个服务专注于特定的业务功能。这样做有助于提高系统的灵活性、可伸缩性和可维护性,同时也可以加快开发速度和团队的独立性。

需要注意的是,微服务架构需要仔细考虑服务之间的边界、通信机制、数据一致性等方面的设计。此外,微服务架构也引入了一些挑战,如服务发现、负载均衡、错误处理等,需要合适的工具和框架来支持。

领域事件驱动架构(Domain Event-Driven Architecture)

概念

领域事件驱动架构(Domain Event-Driven Architecture)是一种架构模式,它基于领域事件的概念,将领域模型中的事件作为系统中的核心驱动力。领域事件表示领域中发生的重要事实或状态变化,它们被捕获并在系统中传播,以影响其他部分的行为和状态。在领域事件驱动架构中,系统中的各个模块(或领域服务)都可以订阅感兴趣的领域事件,并根据事件进行相应的处理。这样做的好处是,模块之间的耦合度降低,各模块之间可以更灵活地协同工作,同时也能更好地支持系统的扩展和演进。

示例代码

// 领域事件
public class OrderCreatedEvent {
    private String orderId;
    private String customerId;
    private BigDecimal amount;

    // 构造函数、属性和方法等
}

// 领域服务
public class OrderService {
    private EventPublisher eventPublisher;

    public OrderService(EventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;
    }

    public void createOrder(String customerId, List<Product> products) {
        // 创建订单的业务逻辑
        Order order = new Order(customerId, products);
        // 订单创建后发布订单创建事件
        OrderCreatedEvent event = new OrderCreatedEvent(order.getId(), order.getCustomerId(), order.getAmount());
        eventPublisher.publish(event);
    }
    
    // 其他订单相关的业务逻辑和操作方法
}

// 订单处理器,订阅订单创建事件并进行相应的处理
public class OrderCreatedEventHandler {
    public void handle(OrderCreatedEvent event) {
        // 处理订单创建事件的业务逻辑
        String orderId = event.getOrderId();
        String customerId = event.getCustomerId();
        BigDecimal amount = event.getAmount();
        // 执行相应的操作,如发送通知、更新报表等
    }
}

// 领域事件发布者接口
public interface EventPublisher {
    void publish(DomainEvent event);
}

// 领域事件发布者的具体实现
public class EventPublisherImpl implements EventPublisher {
    private List<EventHandler> handlers;

    public EventPublisherImpl() {
        this.handlers = new ArrayList<>();
    }

    public void registerHandler(EventHandler handler) {
        handlers.add(handler);
    }

    @Override
    public void publish(DomainEvent event) {
        for (EventHandler handler : handlers) {
            if (handler.canHandle(event)) {
                handler.handle(event);
            }
        }
    }
}

// 在应用程序的入口点或配置中,组装和注入事件发布者和事件处理器
public class Application {
    public static void main(String[] args) {
        EventPublisher eventPublisher = new EventPublisherImpl();
        eventPublisher.registerHandler(new OrderCreatedEventHandler());

        OrderService orderService = new OrderService(eventPublisher);

        // 启动应用程序,处理用户请求等
    }
}

在上面的栗子中,定义了一个领域事件OrderCreatedEvent表示订单创建的事件。在OrderService中,当创建订单时,会发布OrderCreatedEventEventPublisher负责将事件传播给对应的事件处理器。OrderCreatedEventHandler是一个事件处理器,它订阅并处理订单创建事件。在EventPublisherImpl中,我们注册了OrderCreatedEventHandler作为事件处理器,并在事件发布时触发相应的处理逻辑。

总结

通过领域事件驱动架构,系统中的各个模块可以根据感兴趣的事件进行订阅和处理,从而实现模块之间的解耦和灵活性。事件的传播机制可以基于同步或异步方式进行,取决于系统的需求和性能要求。

如何选择?

  1. 分层架构:

    • 简要说明:分层架构是一种经典的架构模式,将应用程序按照功能划分为多个层次,通常包括表示层、应用层、领域层和基础设施层。每个层次具有不同的职责和关注点,通过层与层之间的解耦来实现可维护性和可扩展性。
    • 使用场景:适用于小型和中型应用程序,领域模型相对简单,没有明显的复杂性和高性能要求的场景。
  2. 领域驱动设计的六边形架构:

    • 简要说明:六边形架构是一种基于领域驱动设计原则的架构模式,将应用程序划分为三个主要部分:应用服务(Application Services)、领域模型(Domain Model)和基础设施(Infrastructure)。通过六边形架构,可以更好地实现领域模型的解耦、灵活性和可测试性。
    • 使用场景:适用于具有复杂领域模型和高度可扩展性要求的应用程序,强调领域模型的核心性和业务驱动设计。
  3. CQRS:

    • 简要说明:CQRS(Command Query Responsibility Segregation)是一种架构模式,将读操作(查询)和写操作(命令)分离到不同的模块中。通过使用不同的数据模型和处理机制来处理读写操作,可以提高系统的性能、可伸缩性和灵活性。
    • 使用场景:适用于需要高性能读操作和复杂写操作的应用程序,例如具有高并发查询需求或需要实时分析的场景。
  4. 微服务架构:

    • 简要说明:微服务架构将大型应用程序拆分为一组小型、独立的服务,每个服务都运行在自己的进程中,并通过轻量级的通信机制进行通信。每个服务专注于单个业务功能,可以独立开发、部署和扩展。
    • 使用场景:适用于大型和复杂应用程序,需要高度的可扩展性和自治性。适合团队之间的独立开发和部署,以及使用不同技术栈和基础设施的情况。
  5. 领域事件驱动架构:

    • 简要说明:领域事件驱动架构将领域事件作为系统的核心驱动力,通过事件的发布和订阅来实现模块之间的解耦。模块可以订阅感兴趣的事件,并根据事件进行相应的处理。
    • 使用场景:适用于需要实现领域模型的事件驱动、模块之间的松耦合和灵活协同工作的应用程序。特别适合领域模型复杂、演进频繁的领域。
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
MySQL多数据源是指在一个应用程序同时使用多个不同的MySQL数据库来存储和管理数据的技术。它可以帮助开发人员更灵活地处理各种数据库操作,提高程序的性能和可扩展性。下面是一个完整的MySQL多数据源教程。 一、设置数据库连接信息 1. 在应用程序的配置,创建多个数据库连接的配置项。例如,可以为每个数据源创建一个配置项,分别命名为db1、db2等。 2. 在配置项,设置每个数据源的连接信息,包括数据库地址、用户名、密码等。 二、创建数据源管理器 1. 创建一个数据源管理器类,用于管理多个数据源。该类需要实现数据源的动态切换和获取。 2. 使用Java的线程安全的数据结构,如ConcurrentHashMap来存储数据源信息。将配置的数据库连接信息加载到数据结构。 3. 实现方法来切换不同的数据源,通过传入数据源的名称来切换到对应的数据库。 三、实现数据源切换 1. 在应用程序,根据业务需求选择需要使用的数据源。可以通过调用数据源管理器的方法来切换数据源。 2. 在DAO层的代码,根据当前使用的数据源名称,选择对应的数据源进行数据库操作。 四、使用多数据源进行数据库操作 1. 在DAO层的代码,区分不同的数据源,并将数据库操作的代码包装在对应的数据源。 2. 在业务层的代码,调用DAO层的方法来进行数据库操作。不同的数据源会自动切换。 五、处理事务 1. 如果需要在一个事务操作多个数据源,可以使用分布式事务的方式来处理。 2. 可以使用开源的分布式事务框架,如Atomikos、Bitronix等来实现多数据源的事务管理。 六、监控和维护 1. 使用监控工具来监控多个数据源的使用情况,包括连接数、查询次数等。 2. 定期对数据库进行维护,包括索引优化、数据清理等工作,以保证数据库的性能和稳定性。 通过以上步骤,我们可以实现MySQL多数据源的配置和使用。使用多数据源可以更好地管理和处理不同的数据库操作,在提高程序性能和可扩展性的同时,也提供了更灵活的数据操作方式。同时,需要注意合理选择和配置数据源,以及监控和维护数据库,以保证系统的运行效率和数据的安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枫飞雪飘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值