一、创建型模式:对象创建的艺术

1.1 单例模式的七种写法与 JDK 源码应用

// 方案1:饿汉式(类加载时实例化,可能造成资源浪费)
public class HungrySingleton {
    private static final HungrySingleton INSTANCE = new HungrySingleton();
    private HungrySingleton() {}
    public static HungrySingleton getInstance() { return INSTANCE; }
}

// 方案2:懒汉式(双重检查锁,延迟加载)
public class LazySingleton {
    // volatile 防止指令重排序: INSTANCE = new LazySingleton() 分解为:
    // 1. 分配内存 2. 调用构造器 3. 将引用赋值给 INSTANCE
    // 无 volatile 时另一个线程可能看到半初始化状态
    private static volatile LazySingleton INSTANCE;
    private LazySingleton() {}
    public static LazySingleton getInstance() {
        if (INSTANCE == null) {                      // 第一次检查
            synchronized (LazySingleton.class) {
                if (INSTANCE == null) {               // 第二次检查(必须)
                    INSTANCE = new LazySingleton();
                }
            }
        }
        return INSTANCE;
    }
}

// 方案3:静态内部类(利用类加载锁机制,延迟加载且线程安全)
public class StaticInnerSingleton {
    private StaticInnerSingleton() {}
    private static class Holder {
        static final StaticInnerSingleton INSTANCE = new StaticInnerSingleton();
    }
    public static StaticInnerSingleton getInstance() {
        return Holder.INSTANCE;  // 首次调用时加载,JVM保证线程安全
    }
}

// 方案4:枚举单例(Effective Java 作者推荐,反射/序列化均安全)
public enum EnumSingleton {
    INSTANCE;
    private final Map data;
    EnumSingleton() { this.data = new ConcurrentHashMap<>(); }
    public Object getData(String key) { return data.get(key); }
}

// JDK应用:Runtime.getRuntime()、Desktop.getDesktop()、LogManager.getLogManager()

1.2 工厂模式与 Spring 的 BeanFactory

// 工厂接口
public interface MessageSender {
    void send(String to, String content);
}

// 工厂实现
public class SenderFactory {
    // 简单工厂:违反对修改关闭原则(新增类型需改工厂)
    public static MessageSender create(String type) {
        return switch (type) {
            case "email" -> new EmailSender();
            case "sms" -> new SmsSender();
            case "push" -> new PushSender();
            default -> throw new IllegalArgumentException("Unknown type: " + type);
        };
    }

    // 工厂方法:延迟到子类决定创建逻辑
    public abstract class TransportFactory {
        public abstract Transport createTransport();
    }
}

// Spring 工厂模式的本质:BeanFactory
// 抽象工厂:创建一族相关对象
public interface DataSourceFactory {
    ConnectionFactory createConnectionFactory();
    StatementFactory createStatementFactory();
}

1.3 建造者模式与 Lombok @Builder

// 传统建造者:链式调用,可选参数清晰
public class OrderRequest {
    private final Long orderId;    // 必填
    private final Long userId;     // 必填
    private final String address;   // 可选
    private final String note;      // 可选
    private final BigDecimal discount; // 可选

    private OrderRequest(Builder b) {
        this.orderId = b.orderId;
        this.userId = b.userId;
        this.address = b.address;
        this.note = b.note;
        this.discount = b.discount;
    }

    public static class Builder {
        private final Long orderId;
        private final Long userId;
        private String address = "";
        private String note = "";
        private BigDecimal discount = BigDecimal.ZERO;

        public Builder(Long orderId, Long userId) {
            this.orderId = Objects.requireNonNull(orderId);
            this.userId = Objects.requireNonNull(userId);
        }

        public Builder address(String v) { this.address = v; return this; }
        public Builder note(String v) { this.note = v; return this; }
        public Builder discount(BigDecimal v) { this.discount = v; return this; }
        public OrderRequest build() { return new OrderRequest(this); }
    }
}

// 使用
OrderRequest order = new OrderRequest.Builder(1001L, 2001L)
    .address("北京市朝阳区")
    .discount(BigDecimal.valueOf(10))
    .build();

// Lombok @Builder 注解自动生成建造者
@Builder
public class ProductQuery {
    @NonNull private Long categoryId;
    private String keyword;
    @Builder.Default private Integer page = 1;
    @Builder.Default private Integer pageSize = 20;
}

二、结构型模式:类与对象的组合艺术

2.1 装饰器模式与 Java I/O 源码

Java I/O 类库是装饰器模式最经典的应用。BufferedInputStream 装饰 FileInputStream,两者均可独立使用,也可层层嵌套:

// 装饰器模式:动态添加职责,比继承更灵活
public class DataSourceDecorator implements DataSource {
    protected DataSource wrapped;

    public DataSourceDecorator(DataSource ds) { this.wrapped = ds; }

    @Override
    public void write(String data) { wrapped.write(data); }

    @Override
    public String read() { return wrapped.read(); }
}

// 加密装饰器
public class EncryptionDecorator extends DataSourceDecorator {
    private final String algorithm = "AES/GCM/NoPadding";

    public EncryptionDecorator(DataSource ds) { super(ds); }

    @Override
    public void write(String data) {
        byte[] encrypted = encrypt(data.getBytes());
        super.write(Base64.getEncoder().encodeToString(encrypted));
    }

    private byte[] encrypt(byte[] raw) { /* AES加密 */ return raw; }
}

// 压缩装饰器
public class CompressionDecorator extends DataSourceDecorator {
    public CompressionDecorator(DataSource ds) { super(ds); }

    @Override
    public void write(String data) {
        byte[] compressed = compress(data.getBytes());
        super.write(Base64.getEncoder().encodeToString(compressed));
    }

    private byte[] compress(byte[] raw) { /* GZIP压缩 */ return raw; }
}

// 链式使用:数据源 → 压缩 → 加密 → 写入文件
DataSource ds = new EncryptionDecorator(
    new CompressionDecorator(
        new FileDataSource("data.bin")
    )
);
ds.write("业务数据");

// Java I/O 经典链:InputStream → BufferedInputStream → GZIPInputStream → FileInputStream

2.2 代理模式与 Spring AOP

// JDK 动态代理:要求被代理类实现接口
public class JdkLogProxy implements InvocationHandler {
    private final Object target;

    public JdkLogProxy(Object target) { this.target = target; }

    public static  T bind(T target) {
        return (T) Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            new JdkLogProxy(target)
        );
    }

    @Override
    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
        long start = System.nanoTime();
        String methodName = m.getName();
        try {
            Object result = m.invoke(target, args);
            log.info("{} 执行耗时 {}ns", methodName, System.nanoTime() - start);
            return result;
        } catch (Exception e) {
            log.error("{} 执行异常: {}", methodName, e.getMessage());
            throw e;
        }
    }
}

// CGLIB 代理:可代理无接口类,通过继承 + MethodInterceptor
public class CglibProxy implements MethodInterceptor {
    private final Enhancer enhancer = new Enhancer();

    public Object createProxy(Class clazz) {
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object obj, Method m, Object[] args,
                             MethodProxy proxy) throws Throwable {
        long start = System.nanoTime();
        Object result = proxy.invokeSuper(obj, args);
        log.info("{} 耗时: {}ns", m.getName(), System.nanoTime() - start);
        return result;
    }
}

// Spring AOP 切面
@Aspect
@Component
public class PerformanceAspect {
    @Around("execution(* com.example.service.*.*(..))")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.nanoTime();
        try {
            return pjp.proceed();
        } finally {
            long cost = System.nanoTime() - start;
            if (cost > 1_000_000_000L) { // 超过1秒警告
                log.warn("方法 {} 执行超过1秒: {}ns", pjp.getSignature(), cost);
            }
        }
    }
}

三、行为型模式:对象间的协作

3.1 策略模式与订单计算引擎

// 策略接口
public interface DiscountStrategy {
    BigDecimal calculate(Order order);
}

// 策略实现
public class VipDiscountStrategy implements DiscountStrategy {
    @Override
    public BigDecimal calculate(Order order) {
        return order.getAmount().multiply(BigDecimal.valueOf(0.7)); // VIP 7折
    }
}

public class FestivalDiscountStrategy implements DiscountStrategy {
    @Override
    public BigDecimal calculate(Order order) {
        // 满100减20,上限100
        BigDecimal per100 = order.getAmount().divide(BigDecimal.valueOf(100), 0, RoundingMode.DOWN);
        return per100.min(BigDecimal.valueOf(100));
    }
}

// 策略工厂 + Spring(自动注册)
@Configuration
public class DiscountStrategyConfig {
    @Bean
    public Map discountStrategies(
            List strategies) {
        return strategies.stream()
            .collect(Collectors.toMap(
                s -> s.getClass().getSimpleName().replace("DiscountStrategy", "").toLowerCase(),
                Function.identity()
            ));
    }
}

@Service
public class OrderService {
    private final Map strategies;

    public OrderService(Map strategies) {
        this.strategies = strategies;
    }

    public BigDecimal calculateDiscount(Order order) {
        DiscountStrategy s = strategies.get(order.getDiscountType().toLowerCase());
        return s != null ? s.calculate(order) : BigDecimal.ZERO;
    }
}

3.2 责任链模式与过滤器链

// 标准责任链:抽象类定义链式结构
public abstract class AuthHandler {
    protected AuthHandler next;

    public void setNext(AuthHandler h) { this.next = h; }

    public final Object handle(AuthRequest request) {
        if (!doAuth(request)) {
            throw new SecurityException("认证失败: " + this.getClass().getSimpleName());
        }
        if (next != null) {
            return next.handle(request);
        }
        return "认证通过";
    }

    protected abstract boolean doAuth(AuthRequest request);
}

// 具体处理器
public class TokenAuthHandler extends AuthHandler {
    @Override
    protected boolean doAuth(AuthRequest request) {
        return JwtUtil.verify(request.getToken());
    }
}

public class IpWhitelistHandler extends AuthHandler {
    private final Set whitelist = Set.of("10.0.0.0/8", "192.168.0.0/16");
    @Override
    protected boolean doAuth(AuthRequest request) {
        return whitelist.contains(IpUtils.getCidr(request.getIp()));
    }
}

// Spring Security 过滤器链本质上就是责任链模式
// ClientLoginTokenFilter → JwtAuthFilter → PermissionFilter → ...

// Servlet Filter Chain
@WebFilter(urlPatterns = "/*")
public class LoggingFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest hsr = (HttpServletRequest) req;
        long start = System.currentTimeMillis();
        try {
            chain.doFilter(req, res);
        } finally {
            log.info("{} {} 耗时 {}ms",
                hsr.getMethod(), hsr.getRequestURI(),
                System.currentTimeMillis() - start);
        }
    }
}

四、架构级模式

4.1 CQRS(命令查询职责分离)

CQRS 将读写操作分离,写入用命令模型(聚合根),读取用独立的查询模型(物化视图),实现读写解耦和独立扩展:

// 写入侧:聚合根 + 领域事件
public class OrderAggregate {
    @AggregateIdentifier
    private OrderId id;
    private OrderStatus status;
    private List items = new ArrayList<>();

    // 命令方法(带业务校验)
    public void addItem(Product product, int qty) {
        if (status != OrderStatus.DRAFT) {
            throw new IllegalStateException("已提交的订单不能添加商品");
        }
        items.add(new OrderItem(product.getId(), product.getPrice(), qty));
        // 发布领域事件
        DomainEventPublisher.publish(new OrderItemAddedEvent(id, product.getId(), qty));
    }

    public void place() {
        if (items.isEmpty()) throw new IllegalStateException("空订单无法提交");
        this.status = OrderStatus.PLACED;
        DomainEventPublisher.publish(new OrderPlacedEvent(id));
    }
}

// 读取侧:独立查询模型(直接投影)
public class OrderQueryService {
    @Query("SELECT o.id, o.user_name, o.status, o.total_amount " +
           "FROM orders_v o WHERE o.id = :id", resultSetMapping = "OrderVO")
    OrderVO findById(@Param("id") Long id);

    @Query("SELECT new OrderSummaryVO(o.status, COUNT(o), SUM(o.totalAmount)) " +
           "FROM OrderEntity o GROUP BY o.status")
    List groupByStatus();
}

// Event Sourcing:事件溯源(可选)
// 订单状态 = OrderPlaced + ItemAdded + Paid + Shipped 等事件的历史叠加
// 优势:完整审计日志、支持任意时间点回放、支持并行开发多个读模型

4.2 观察者模式与 Spring Event

// Spring 事件机制 = 观察者模式的实现

// 1. 定义事件
public class OrderPlacedEvent extends ApplicationEvent {
    private final Order order;
    public OrderPlacedEvent(Object src, Order order) {
        super(src);
        this.order = order;
    }
    public Order getOrder() { return order; }
}

// 2. 监听器(同步/异步)
@Async
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
@Order(1)
public class InventoryEventListener {
    @EventListener
    public void handleOrderPlaced(OrderPlacedEvent event) {
        // 扣减库存(异步,事务提交后执行)
        inventoryService.deduct(event.getOrder().getItems());
    }
}

@Service
@Order(2)
public class NotificationEventListener {
    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    public void handleOrderPlaced(OrderPlacedEvent event) {
        // 发送通知邮件
        notificationService.sendOrderConfirmation(event.getOrder());
    }
}

// 3. 发布事件(领域事件发布)
@Service
public class OrderService {
    private final ApplicationEventPublisher publisher;

    public void placeOrder(Order order) {
        order.place();
        orderRepo.save(order);
        publisher.publishEvent(new OrderPlacedEvent(this, order));
    }
}