基于领域驱动设计 (DDD) 四层架构实现订单系统

DDD 四层架构包括用户界面层 (UI)、应用层 (Application)、领域层 (Domain)、和基础设施层 (Infrastructure)。我们将按此结构实现订单系统。

项目结构

首先,让我们定义项目结构:

src
├── main
│   ├── java
│   │   └── com
│   │       └── example
│   │           ├── OrdersystemApplication.java
│   │           ├── ui
│   │           │   └── OrderController.java
│   │           ├── application
│   │           │   └── OrderService.java
│   │           ├── domain
│   │           │   ├── Order.java
│   │           │   ├── OrderItem.java
│   │           │   ├── ValueObjects
│   │           │   │   ├── OrderId.java
│   │           │   │   ├── OrderStatus.java
│   │           │   │   ├── ProductName.java
│   │           │   │   ├── Quantity.java
│   │           │   │   └── Price.java
│   │           │   ├── OrderRepository.java
│   │           │   └── OrderService.java
│   │           └── infrastructure
│   │               └── JpaOrderRepository.java
│   └── resources
│       └── application.properties

1. 用户界面层 (UI)

OrderController.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.example.ui;

import com.example.application.OrderService;
import com.example.domain.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/orders")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @PostMapping
    public Order createOrder(@RequestBody Order order) {
        return orderService.createOrder(order);
    }

    @GetMapping("/{id}")
    public Order getOrder(@PathVariable String id) {
        return orderService.getOrder(id);
    }

    @PutMapping("/{id}")
    public Order updateOrder(@PathVariable String id, @RequestBody Order order) {
        return orderService.updateOrder(id, order);
    }

    @DeleteMapping("/{id}")
    public void deleteOrder(@PathVariable String id) {
        orderService.deleteOrder(id);
    }
}

2. 应用层 (Application)

OrderService.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.example.application;

import com.example.domain.Order;
import com.example.domain.OrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class OrderService {

    @Autowired
    private OrderRepository orderRepository;

    public Order createOrder(Order order) {
        return orderRepository.save(order);
    }

    public Order getOrder(String id) {
        Optional<Order> order = orderRepository.findById(id);
        return order.orElse(null);
    }

    public Order updateOrder(String id, Order order) {
        Optional<Order> existingOrder = orderRepository.findById(id);
        if (existingOrder.isPresent()) {
            Order updatedOrder = existingOrder.get();
            updatedOrder.setItems(order.getItems());
            updatedOrder.setStatus(order.getStatus());
            return orderRepository.save(updatedOrder);
        }
        return null;
    }

    public void deleteOrder(String id) {
        orderRepository.deleteById(id);
    }
}

3. 领域层 (Domain)

Order.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.example.domain;

import com.example.domain.ValueObjects.OrderId;
import com.example.domain.ValueObjects.OrderStatus;

import java.util.List;

public class Order {
    private OrderId id;
    private List<OrderItem> items;
    private OrderStatus status;

    public Order(OrderId id, List<OrderItem> items, OrderStatus status) {
        this.id = id;
        this.items = items;
        this.status = status;
    }

    public OrderId getId() {
        return id;
    }

    public List<OrderItem> getItems() {
        return items;
    }

    public void setItems(List<OrderItem> items) {
        this.items = items;
    }

    public OrderStatus getStatus() {
        return status;
    }

    public void setStatus(OrderStatus status) {
        this.status = status;
    }
}

OrderItem.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.example.domain;

import com.example.domain.ValueObjects.Price;
import com.example.domain.ValueObjects.ProductName;
import com.example.domain.ValueObjects.Quantity;

public class OrderItem {
    private ProductName productName;
    private Quantity quantity;
    private Price price;

    public OrderItem(ProductName productName, Quantity quantity, Price price) {
        this.productName = productName;
        this.quantity = quantity;
        this.price = price;
    }

    public ProductName getProductName() {
        return productName;
    }

    public Quantity getQuantity() {
        return quantity;
    }

    public Price getPrice() {
        return price;
    }
}

值对象 (Value Objects)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package com.example.domain.ValueObjects;

public class OrderId {
    private String id;

    public OrderId(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }
}

public class OrderStatus {
    private String status;

    public OrderStatus(String status) {
        this.status = status;
    }

    public String getStatus() {
        return status;
    }
}

public class ProductName {
    private String name;

    public ProductName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

public class Quantity {
    private int quantity;

    public Quantity(int quantity) {
        this.quantity = quantity;
    }

    public int getQuantity() {
        return quantity;
    }
}

public class Price {
    private double amount;

    public Price(double amount) {
        this.amount = amount;
    }

    public double getAmount() {
        return amount;
    }
}

OrderRepository.java

1
2
3
4
5
6
7
8
9
package com.example.domain;

import java.util.Optional;

public interface OrderRepository {
    Order save(Order order);
    Optional<Order> findById(String id);
    void deleteById(String id);
}

4. 基础设施层 (Infrastructure)

JpaOrderRepository.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package com.example.infrastructure;

import com.example.domain.Order;
import com.example.domain.OrderRepository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface JpaOrderRepository extends OrderRepository, JpaRepository<Order, String> {
}

OrdersystemApplication.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class OrdersystemApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrdersystemApplication.class, args);
    }
}

application.properties

1
2
3
4
5
6
spring.datasource.url=jdbc:mysql://localhost:3306/ordersystem
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect

通过上述代码,我们使用领域驱动设计 (DDD) 原则实现了订单系统。该系统包括用户界面层、应用层、领域层和基础设施层,各层之间通过依赖注入和接口解耦,实现了高内聚、低耦合的系统架构。