程序员必备的十大技能(进阶版)之设计模式与架构思维(四)

简介: 教程来源 https://ltglu.cn/ 架构思维聚焦系统级设计:分层架构强调职责分离与上下依赖;六边形架构通过端口/适配器解耦核心业务与外部环境;CQRS分离读写模型提升性能与可维护性;事件驱动架构则以异步事件实现服务松耦合。

五、架构思维:从代码到系统

设计模式解决的是类级别的问题,而架构思维解决的是系统级别的问题。

5.1 架构设计的核心原则
image.png
5.2 分层架构(Layered Architecture)

分层架构(经典四层):
  ┌─────────────────────────────────────┐
  │         表现层 (Presentation)        │  ← Controller, JSP, REST API
  ├─────────────────────────────────────┤
  │         应用层 (Application)         │  ← Service, 业务编排
  ├─────────────────────────────────────┤
  │         领域层 (Domain)              │  ← Entity, 核心业务逻辑
  ├─────────────────────────────────────┤
  │         基础设施层 (Infrastructure)   │  ← Repository, 数据库访问
  └─────────────────────────────────────┘

依赖方向: 上层依赖下层,下层对上层无感知
// 分层架构示例
// 表现层
@RestController
public class OrderController {
    @Autowired
    private OrderApplicationService orderService;

    @PostMapping("/orders")
    public OrderResponse createOrder(@RequestBody CreateOrderRequest request) {
        return orderService.createOrder(request);
    }
}

// 应用层
@Service
public class OrderApplicationService {
    @Autowired
    private OrderDomainService orderDomainService;
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private PaymentGateway paymentGateway;

    @Transactional
    public OrderResponse createOrder(CreateOrderRequest request) {
        // 应用层编排
        Order order = Order.create(request.getUserId(), request.getItems());

        // 调用领域服务
        orderDomainService.calculateDiscount(order);

        // 调用基础设施
        orderRepository.save(order);

        // 外部系统调用
        PaymentResult payment = paymentGateway.charge(order.getTotalAmount());

        order.markAsPaid(payment.getTransactionId());
        orderRepository.save(order);

        return OrderResponse.from(order);
    }
}

// 领域层
public class Order {
    private String orderId;
    private String userId;
    private List<OrderItem> items;
    private OrderStatus status;
    private BigDecimal totalAmount;

    // 领域逻辑(核心业务规则)
    public static Order create(String userId, List<OrderItem> items) {
        Order order = new Order();
        order.orderId = generateOrderId();
        order.userId = userId;
        order.items = items;
        order.status = OrderStatus.PENDING;
        order.totalAmount = calculateTotal(items);
        return order;
    }

    public void markAsPaid(String transactionId) {
        if (this.status != OrderStatus.PENDING) {
            throw new IllegalStateException("Order cannot be paid: status is " + this.status);
        }
        this.status = OrderStatus.PAID;
        // 记录支付信息...
    }
}

// 基础设施层
@Repository
public class OrderRepository {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    public void save(Order order) {
        jdbcTemplate.update("INSERT INTO orders ...", order.getOrderId(), ...);
    }
}

5.3 六边形架构(Hexagonal Architecture / 端口适配器)
六边形架构强调业务逻辑与外部系统的隔离,通过端口(Port)和适配器(Adapter)实现。

┌─────────────────────────────────────────────────────────────────┐
│                        六边形架构                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   ┌─────────────┐                    ┌─────────────┐           │
│   │  HTTP适配器  │                    │ 数据库适配器 │           │
│   └──────┬──────┘                    └──────┬──────┘           │
│          │                                   │                  │
│          ▼                                   ▼                  │
│   ┌─────────────────────────────────────────────────┐         │
│   │                    端口                         │         │
│   │  ┌─────────────────────────────────────────┐   │         │
│   │  │            业务核心(领域模型)          │   │         │
│   │  └─────────────────────────────────────────┘   │         │
│   │                    端口                         │         │
│   └─────────────────────────────────────────────────┘         │
│          ▲                                   ▲                  │
│          │                                   │                  │
│   ┌──────┴──────┐                    ┌──────┴──────┐           │
│   │ 消息适配器   │                    │ 邮件适配器   │           │
│   └─────────────┘                    └─────────────┘           │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘
// 端口接口(内)
public interface OrderService {
    Order createOrder(OrderCommand command);
    Order getOrder(String orderId);
    void cancelOrder(String orderId);
}

public interface PaymentService {
    PaymentResult charge(BigDecimal amount, PaymentMethod method);
}

// 领域模型(核心业务)
public class Order {
    // 纯业务逻辑,不依赖任何外部框架
    private String id;
    private List<OrderLine> lines;
    private OrderStatus status;

    public void addItem(Product product, int quantity) {
        lines.add(new OrderLine(product, quantity));
        recalculateTotal();
    }

    public void cancel() {
        if (status == OrderStatus.SHIPPED) {
            throw new IllegalStateException("Cannot cancel shipped order");
        }
        this.status = OrderStatus.CANCELLED;
    }

    private void recalculateTotal() {
        this.total = lines.stream()
            .map(line -> line.getProduct().getPrice().multiply(BigDecimal.valueOf(line.getQuantity())))
            .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
}

// 端口实现(外)
@RestController
public class OrderController implements OrderService {  // 实现端口接口
    private final OrderApplication orderApp;

    @Override
    @PostMapping("/orders")
    public Order createOrder(@RequestBody OrderCommand command) {
        return orderApp.createOrder(command);
    }
}

@Repository
public class OrderRepository implements OrderPort {  // 另一个端口实现
    // 数据库访问逻辑
}

5.4 CQRS(命令查询职责分离)
CQRS将读操作和写操作分离为不同的模型。

// 命令(写模型)
public class CreateOrderCommand {
    private String userId;
    private List<OrderItemDto> items;
}

@Service
public class OrderCommandService {
    @Autowired
    private OrderRepository writeRepository;
    @Autowired
    private EventPublisher eventPublisher;

    @Transactional
    public String handle(CreateOrderCommand command) {
        // 写模型关注业务规则和事务一致性
        Order order = Order.create(command.getUserId(), command.getItems());
        order.validate();

        writeRepository.save(order);

        // 发布领域事件,用于更新读模型
        eventPublisher.publish(new OrderCreatedEvent(order.getId()));

        return order.getId();
    }
}

// 查询(读模型)
@RestController
public class OrderQueryService {
    @Autowired
    private OrderReadRepository readRepository;  // 可以是Elasticsearch或其他

    @GetMapping("/orders/{id}")
    public OrderReadModel getOrder(@PathVariable String id) {
        // 读模型可以完全去规范化,优化查询性能
        return readRepository.findById(id);
    }

    @GetMapping("/orders")
    public Page<OrderReadModel> listOrders(OrderQueryParams params) {
        // 复杂的查询和聚合
        return readRepository.search(params);
    }
}

// 读模型(去规范化)
@Document(indexName = "orders")
public class OrderReadModel {
    private String id;
    private String userId;
    private String userName;       // 冗余用户姓名,避免JOIN
    private List<OrderItemReadModel> items;
    private String status;
    private LocalDateTime createdAt;
    // 不需要所有业务字段,只存查询需要的字段
}

5.5 事件驱动架构(Event-Driven Architecture)
事件驱动架构通过异步事件解耦服务间的通信。

// 领域事件定义
public abstract class DomainEvent {
    private final String eventId = UUID.randomUUID().toString();
    private final LocalDateTime occurredAt = LocalDateTime.now();

    public String getEventId() { return eventId; }
    public LocalDateTime getOccurredAt() { return occurredAt; }
}

public class OrderCreatedEvent extends DomainEvent {
    private final String orderId;
    private final String userId;
    private final BigDecimal amount;

    public OrderCreatedEvent(String orderId, String userId, BigDecimal amount) {
        this.orderId = orderId;
        this.userId = userId;
        this.amount = amount;
    }
    // getters
}

public class OrderPaidEvent extends DomainEvent {
    private final String orderId;
    private final String transactionId;
    // ...
}

// 事件发布器
@Service
public class DomainEventPublisher {
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;
    @Autowired
    private KafkaTemplate<String, Object> kafkaTemplate;

    @EventListener
    public void handleDomainEvent(DomainEvent event) {
        // 本地事件(同一JVM内)
        applicationEventPublisher.publishEvent(event);

        // 分布式事件(跨服务)
        kafkaTemplate.send("order-events", event.getClass().getSimpleName(), event);
    }
}

// 事件处理器(本地)
@Component
@EventListener
public class InventoryEventHandler {
    public void handleOrderPaid(OrderPaidEvent event) {
        // 扣减库存
        inventoryService.deductStock(event.getOrderId());
    }
}

// 事件处理器(远程)
@Component
@KafkaListener(topics = "order-events")
public class NotificationEventHandler {
    @KafkaHandler
    public void handleOrderCreated(OrderCreatedEvent event) {
        // 发送确认邮件
        emailService.sendOrderConfirmation(event.getUserId(), event.getOrderId());
    }

    @KafkaHandler
    public void handleOrderPaid(OrderPaidEvent event) {
        // 发送支付成功通知
        notificationService.sendPaymentNotification(event.getUserId());
    }
}

来源:
https://xbivx.cn/

相关文章
|
1天前
|
设计模式 架构师 Java
程序员必备的十大技能(进阶版)之设计模式与架构思维(一)
教程来源 https://rvtst.cn/ 本文系统讲解设计模式与架构思维,涵盖SOLID原则、创建型/结构型/行为型模式实战、DDD、分层/六边形/微服务架构等十大维度,助你从写代码进阶到设计系统。
|
8天前
|
存储 程序员 Linux
初级程序员必备的十大技能之 Git 版本控制(一)
教程来源 http://xcfsr.cn Git是程序员的“后悔药”与“时光机”:可随时回退错误修改、隔离并行开发、一键恢复稳定版本。作为分布式版本控制系统,它本地全量存储、离线可用、安全可靠,支撑全球90%以上团队高效协作。
|
18天前
|
前端开发 JavaScript 容器
前端组件库 ——LayUI 知识点大全(三)
教程来源 https://bncne.cn LayUI基础元素丰富实用:按钮支持多色、多尺寸及图标组合;图标为矢量字体,可自由缩放变色;表单模块集成验证与交互;layer弹层、table表格、laydate日期、upload上传等核心模块,让后台开发简洁高效。
|
18天前
|
前端开发 JavaScript 开发者
前端组件库 ——LayUI 知识点大全(四)
教程来源 https://zlpow.cn LayUI 2.8+/3.0 支持 CSS 变量主题定制、深浅色切换;提供移动端专用版本;支持按需引入与模块化加载;可开发自定义模块及集成 ECharts 等第三方插件,兼顾简洁性与扩展性,适合快速构建后台系统。
|
18天前
|
前端开发 JavaScript API
前端组件库 ——LayUI 知识点大全(一)
教程来源 http://oplhc.cn LayUI是由国内开发者“贤心”于2016年推出的经典模块化前端UI框架,MIT开源。不依赖Vue/React等现代框架,零配置、低门槛、开箱即用,尤受后端开发者与中小项目青睐。2026年仍持续更新,最新版2.11+强化组件与工程化支持。
|
23天前
|
Web App开发 前端开发 数据可视化
前端组件库 ——ECharts 知识点大全(一)
教程来源 https://bgnno.cn/ ECharts 是 Apache 顶级开源可视化库,由百度于2013年发起,支持50+图表类型、千万级数据渲染、Canvas/SVG双引擎及深度交互。兼容主流浏览器与移动端,广泛应用于商业、政务与科研领域。
|
23天前
|
编解码 监控 JavaScript
前端组件库 Vue 大屏组件库知识点大全(一)
教程来源 http://unbgv.cn 在数字化转型中,数据大屏已成为企业决策“核心中枢”。本文系统解析Vue大屏组件库,涵盖适配方案(scale/rem/vw-vh)、性能优化、实时渲染与视觉设计,助开发者高效构建高可用、高保真专业大屏应用。
|
1天前
|
Arthas 缓存 安全
【Java并发编程】高频实战:死锁排查、线程安全问题定位、线程dump分析(附《思维导图》+《面试高频考点清单》)
本文系统梳理Java并发编程高频实战知识:涵盖死锁排查(Coffman四条件、jstack/Arthas分析)、线程安全定位(竞态/可见性/有序性问题及原子类、Lock、ThreadLocal等方案)与线程Dump深度解析(状态识别、死锁/锁竞争/死循环模式)。
|
1天前
|
存储 缓存 人工智能
阿里云百炼Qwen3.7-Max简介:智能体时代旗舰模型,面向真实生产力场景,后付费限时5折
阿里云百炼Qwen3.7-Max旗舰模型的能力与优惠参考:该模型参数量超万亿,支持256K超长上下文,采用高效MoE架构,在编程、办公自动化、长周期任务执行等场景表现卓越,当前限时5折(输入6元/百万tokens,输出18元/百万tokens)。用户可通过Token Plan团队版Credits抵扣或按量付费,支持缓存、Batch调用等降本策略,现在开通享后付费限时5折优惠。
|
1天前
|
设计模式 Java 调度
【Java并发编程】锁机制:AQS抽象队列同步器:核心原理、CLH队列、独占/共享模式、基于AQS实现的组件(CountDownLatch、CyclicBarrier等)(附《思维导图》+《面试高频考点清单》)
AQS(AbstractQueuedSynchronizer)是Java并发包(JUC)的基石框架,基于volatile state状态变量与CLH双向等待队列,通过模板方法模式支持独占/共享同步语义,为ReentrantLock、Semaphore、CountDownLatch等核心组件提供统一底层实现。

热门文章

最新文章