一、创建型模式:对象创建的艺术
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));
}
}