Java设计模式精讲:创建型+结构型模式(含生产级案例+相似模式对比)

设计模式是软件开发中沉淀的通用、可复用的最佳解决方案,专门解决项目中代码冗余、耦合度过高、扩展性差、维护成本高昂、架构混乱 等核心问题。本文将系统讲解5大创建型模式、7大结构型模式,严格贴合核心设计思想,拆解每种模式的原理、适用场景、核心特点,提供可直接上线的生产级代码案例,同时重点辨析高频相似设计模式的核心区别,完全适配业务开发、源码研读、面试刷题三大场景。

一、创建型设计模式

创建型模式核心定位:专注对象的创建逻辑,屏蔽对象实例化的复杂细节,解耦对象创建与业务逻辑,统一对象创建规范,让代码更优雅、更易拓展。包含:简单工厂、工厂方法、抽象工厂、建造者、原型、单例。

1. 简单工厂模式

简单工厂不属于GOF23种经典设计模式,但却是最基础的对象创建模式。其核心是通过一个统一的工厂类,根据传入的参数,通过if/else、switch判断,创建并返回不同的对象实例。客户端无需关注对象创建细节,直接调用工厂方法即可获取对象。​

简单工厂并非GOF23经典设计模式,是最基础的对象创建方案。核心逻辑:通过一个统一的工厂类,基于 if/else、switch 条件判断,根据传入参数创建不同的产品对象,客户端无需关注对象创建细节,直接调用工厂方法获取实例。

优缺点

优点:统一对象创建入口,封装创建逻辑,简化客户端调用。

缺点:严重违背开闭原则,新增产品必须修改工厂类的判断逻辑,产品越多,工厂类越臃肿、维护难度越高。

生产级实战案例

业务场景:支付渠道统一创建,系统支持微信、支付宝支付,通过简单工厂动态生成对应支付对象

复制代码
import java.math.BigDecimal;

// 支付产品抽象接口
public interface Pay {
    void pay(BigDecimal money);
}

// 微信支付实现
public class WechatPay implements Pay {
    @Override
    public void pay(BigDecimal money) {
        System.out.println("微信支付成功,支付金额:" + money);
    }
}

// 支付宝支付实现
public class Alipay implements Pay {
    @Override
    public void pay(BigDecimal money) {
        System.out.println("支付宝支付成功,支付金额:" + money);
    }
}

// 统一简单工厂类
public class PaySimpleFactory {
    public static Pay createPay(String payType) {
        if ("WECHAT".equalsIgnoreCase(payType)) {
            return new WechatPay();
        } else if ("ALIPAY".equalsIgnoreCase(payType)) {
            return new Alipay();
        } else {
            throw new RuntimeException("不支持的支付渠道");
        }
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        Pay pay = PaySimpleFactory.createPay("ALIPAY");
        pay.pay(new BigDecimal("99.9"));
    }
}

2. 工厂方法模式

核心原理

工厂方法是简单工厂的迭代升级版,核心设计思想:将对象创建逻辑下放至子类。定义统一的抽象工厂接口,不再通过条件判断创建对象,每一个产品对应一个专属的工厂子类,由子类负责具体产品的实例化。

与简单工厂核心区别

  • 简单工厂:单一统一工厂类 + 条件判断创建对象,新增产品需修改原有工厂代码,违背开闭原则

  • 工厂方法:抽象工厂 + 子类专属工厂,新增产品只需新增「产品类+工厂子类」,原有代码零修改,完全符合开闭原则

生产级实战案例

业务场景:改造支付渠道场景,支持后续无缝拓展云闪付、抖音支付等新渠道,无需改动核心代码。

复制代码
import java.math.BigDecimal;

// 产品抽象接口
public interface Pay {
    void pay(BigDecimal money);
}

// 具体产品实现
public class WechatPay implements Pay {
    @Override
    public void pay(BigDecimal money) {
        System.out.println("微信支付:" + money);
    }
}
public class Alipay implements Pay {
    @Override
    public void pay(BigDecimal money) {
        System.out.println("支付宝支付:" + money);
    }
}

// 抽象工厂接口
public interface PayFactory {
    Pay createPay();
}

// 专属工厂子类
public class WechatPayFactory implements PayFactory {
    @Override
    public Pay createPay() {
        return new WechatPay();
    }
}
public class AlipayFactory implements PayFactory {
    @Override
    public Pay createPay() {
        return new Alipay();
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        PayFactory factory = new WechatPayFactory();
        Pay pay = factory.createPay();
        pay.pay(new BigDecimal("199.9"));
    }
}

3. 抽象工厂模式

核心原理

工厂方法针对单一独立产品 创建,而抽象工厂专注产品族 创建。核心定义:提供一个抽象工厂接口,用于创建一系列相关、相互依赖的产品对象,保证同一品牌、同一系列的产品配套使用。

产品族概念:同一系列下的多个关联产品,例如手机产品族包含:手机、耳机、智能手表三件套。

适用场景

系统存在多个产品系列,每个系列包含多个关联产品,需要强制保证产品配套使用,不出现跨系列混用的场景。

生产级实战案例

业务场景:电商数码产品生产,分为小米、华为两大产品族,每个产品族统一生产手机、耳机两类配套产品。

复制代码
// 产品1:手机抽象接口
public interface Phone {
    void showPhoneInfo();
}
// 产品2:耳机抽象接口
public interface HeadSet {
    void showHeadSetInfo();
}

// 小米产品族具体产品
public class XiaomiPhone implements Phone {
    @Override
    public void showPhoneInfo() {
        System.out.println("小米14 旗舰手机");
    }
}
public class XiaomiHeadSet implements HeadSet {
    @Override
    public void showHeadSetInfo() {
        System.out.println("小米无线蓝牙耳机");
    }
}

// 华为产品族具体产品
public class HuaweiPhone implements Phone {
    @Override
    public void showPhoneInfo() {
        System.out.println("华为Mate60 旗舰手机");
    }
}
public class HuaweiHeadSet implements HeadSet {
    @Override
    public void showHeadSetInfo() {
        System.out.println("华为FreeBuds降噪耳机");
    }
}

// 抽象工厂:定义产品族创建规范
public interface DigitalFactory {
    Phone createPhone();
    HeadSet createHeadSet();
}

// 小米工厂:生产小米全系产品
public class XiaomiFactory implements DigitalFactory {
    @Override
    public Phone createPhone() {
        return new XiaomiPhone();
    }
    @Override
    public HeadSet createHeadSet() {
        return new XiaomiHeadSet();
    }
}

// 华为工厂:生产华为全系产品
public class HuaweiFactory implements DigitalFactory {
    @Override
    public Phone createPhone() {
        return new HuaweiPhone();
    }
    @Override
    public HeadSet createHeadSet() {
        return new HuaweiHeadSet();
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        // 统一获取华为产品族全套配套产品
        DigitalFactory factory = new HuaweiFactory();
        Phone phone = factory.createPhone();
        HeadSet headSet = factory.createHeadSet();
        phone.showPhoneInfo();
        headSet.showHeadSetInfo();
    }
}

4. 建造者模式

核心原理

建造者模式是分步构建复杂对象 的专属创建型模式,核心思想:将复杂对象的构建过程对象的最终表现形态彻底分离,通过固定的构建流程,可生成不同属性、不同形态的对象。

与普通get/set方法核心区别

  • 普通get/set:零散无序赋值,无参数校验、无构建顺序,复杂对象赋值代码臃肿混乱,无法区分必填/选填参数

  • 建造者模式:链式调用、分步构建、强制必填参数、支持参数校验、构建流程统一规范,完美适配多字段复杂对象

生产级实战案例

业务场景:系统用户实体(多字段、区分必填/选填),企业级开发中DTO、VO、配置类高频使用该模式。

复制代码
// 复杂用户实体 + 静态内部建造者
public class User {
    // 必填核心参数
    private String username;
    private String phone;
    // 选填拓展参数
    private String avatar;
    private String gender;
    private Integer age;
    private String sign;

    // 私有构造器,仅建造者可访问
    private User(UserBuilder builder) {
        this.username = builder.username;
        this.phone = builder.phone;
        this.avatar = builder.avatar;
        this.gender = builder.gender;
        this.age = builder.age;
        this.sign = builder.sign;
    }

    // 静态内部建造者
    public static class UserBuilder {
        private String username;
        private String phone;
        private String avatar;
        private String gender;
        private Integer age;
        private String sign;

        // 构造器强制传入必填参数
        public UserBuilder(String username, String phone) {
            this.username = username;
            this.phone = phone;
        }

        // 链式赋值选填参数
        public UserBuilder avatar(String avatar) {
            this.avatar = avatar;
            return this;
        }
        public UserBuilder gender(String gender) {
            this.gender = gender;
            return this;
        }
        public UserBuilder age(Integer age) {
            this.age = age;
            return this;
        }
        public UserBuilder sign(String sign) {
            this.sign = sign;
            return this;
        }

        // 最终构建+参数校验
        public User build() {
            if (username == null || phone == null) {
                throw new RuntimeException("用户名和手机号为必填项,不能为空");
            }
            return new User(this);
        }
    }

    // getter方法省略
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        // 灵活构建不同参数的用户对象
        User user1 = new User.UserBuilder("zhangsan", "13800138000")
                .age(25)
                .gender("男")
                .build();

        User user2 = new User.UserBuilder("lisi", "13900139000")
                .sign("热爱生活,持续精进")
                .build();
    }
}

5. 原型模式

核心原理

原型模式核心是对象克隆复制 ,无需通过 new 关键字实例化对象,通过复制已有原型对象快速生成新对象,大幅提升复杂对象创建效率。Java 中通过实现 Cloneable接口、重写 clone() 方法实现。

核心知识点:浅拷贝 & 深拷贝

  • 浅拷贝:仅复制基本数据类型的值,引用类型只复制内存地址,新旧对象共享同一个引用对象,修改会互相影响

  • 深拷贝:完全复制所有数据,基本类型、引用类型全部新建内存,新旧对象完全独立,互不干扰

生产级实战案例

业务场景:系统全局配置类,配置初始化耗时,通过原型克隆快速复制配置对象,提升系统性能。

java 复制代码
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

// 系统配置原型类
public class SystemConfig implements Cloneable {
    // 基本数据类型
    private String appName;
    private Integer timeout;
    // 引用数据类型
    private List<String> whiteList;

    // 重写浅拷贝方法
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    // 自定义深拷贝方法
    public SystemConfig deepClone() throws CloneNotSupportedException {
        SystemConfig clone = (SystemConfig) super.clone();
        // 手动新建引用类型对象,彻底隔离数据
        clone.whiteList = new ArrayList<>(this.whiteList);
        return clone;
    }

    // getter/setter
    public String getAppName() { return appName; }
    public void setAppName(String appName) { this.appName = appName; }
    public Integer getTimeout() { return timeout; }
    public void setTimeout(Integer timeout) { this.timeout = timeout; }
    public List<String> getWhiteList() { return whiteList; }
    public void setWhiteList(List<String> whiteList) { this.whiteList = whiteList; }
}

// 客户端测试
public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        // 初始化原型对象
        SystemConfig source = new SystemConfig();
        source.setAppName("电商后台系统");
        source.setTimeout(3000);
        source.setWhiteList(Arrays.asList("127.0.0.1","192.168.1.1"));

        // 浅拷贝、深拷贝
        SystemConfig shallowClone = (SystemConfig) source.clone();
        SystemConfig deepClone = source.deepClone();

        // 修改引用类型数据,验证拷贝差异
        shallowClone.getWhiteList().add("10.0.0.1");
        System.out.println("原对象白名单:" + source.getWhiteList());
        System.out.println("深拷贝对象白名单:" + deepClone.getWhiteList());
    }
}

6. 单例模式

核心原理

单例模式是最常用的创建型模式,核心规则:一个类在整个应用全局中仅有且只有一个实例,提供全局统一的访问入口。核心特征:私有构造器、静态全局实例、全局静态获取方法。

核心关键字:volatile

双重检查锁单例中,volatile 关键字两大核心作用:禁止指令重排序、保证线程可见性,彻底解决多线程环境下对象半初始化、实例重复创建的线程安全问题。

生产级实战案例(高性能线程安全双重检查锁)

业务场景:全局日志工具、缓存工具、系统配置工具,全局仅需一个实例,节约内存、保证数据统一。

java 复制代码
public class LogUtil {
    // volatile 禁止指令重排、保证线程可见性
    private static volatile LogUtil instance;

    // 私有构造器:禁止外部new,防止反射破坏单例
    private LogUtil() {
        if (instance != null) {
            throw new RuntimeException("禁止重复创建单例实例");
        }
    }

    // 双重检查锁:兼顾线程安全与高性能
    public static LogUtil getInstance() {
        if (instance == null) {
            synchronized (LogUtil.class) {
                if (instance == null) {
                    instance = new LogUtil();
                }
            }
        }
        return instance;
    }

    // 通用日志业务方法
    public void info(String msg) {
        System.out.println("【INFO】" + System.currentTimeMillis() + ":" + msg);
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        LogUtil log1 = LogUtil.getInstance();
        LogUtil log2 = LogUtil.getInstance();
        // 输出true,证明全局唯一实例
        System.out.println(log1 == log2);
        log1.info("系统启动成功");
    }
}

二、结构型设计模式

结构型模式核心定位:专注类与对象的组合结构、依赖关系优化,不修改原有业务代码的前提下,通过组合、适配、封装等方式,优化系统架构、解耦代码、拓展功能,解决系统臃肿、耦合过高、兼容性差的问题。包含7大核心模式:适配器、桥接、组合、装饰者、外观、享元、代理。

1. 适配器模式

1.1 核心原理

适配器是接口兼容适配专用模式,核心:引入中间适配器层,将客户端需要的目标接口,与服务端不兼容的原有接口做转换,让接口不匹配的类可以协同工作。

1.2 解决核心问题

  • 接口不匹配:新旧系统、第三方SDK接口参数、方法定义不一致

  • 保护现有代码:无法修改第三方、老旧系统的源码,通过适配器间接适配,符合开闭原则

1.3 生产级实战案例

业务场景:新系统统一登录接口规范,适配老旧遗留系统的登录接口,无需改造老系统代码。

java 复制代码
// 客户端目标接口(新系统统一规范)
public interface NewLoginService {
    boolean login(String username, String password);
}

// 服务端原有接口(老旧系统,不可修改)
public class OldLoginService {
    public boolean userLogin(String acc, String pwd, Long type) {
        System.out.println("老旧系统登录校验逻辑");
        return "admin".equals(acc) && "123456".equals(pwd);
    }
}

// 适配器:中间转换层,适配新旧接口
public class LoginAdapter implements NewLoginService {
    private final OldLoginService oldLoginService = new OldLoginService();

    @Override
    public boolean login(String username, String password) {
        // 统一参数适配、接口转换
        return oldLoginService.userLogin(username, password, 1L);
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        NewLoginService loginService = new LoginAdapter();
        boolean result = loginService.login("admin", "123456");
        System.out.println("登录结果:" + result);
    }
}

2. 桥接模式

2.1 核心原理

桥接模式核心:拆分多维变化的类结构,将一个复杂大类拆分为「抽象层」和「实现层」两个独立的层级结构,通过引用建立桥梁关联,让两个层级可以独立拓展,彻底解决继承导致的类爆炸问题。

2.2 适用场景

系统存在两个独立变化的维度,两个维度均需要持续拓展迭代。

2.3 生产级实战案例

业务场景:消息推送系统,包含「消息发送方式(短信/邮件)」「消息级别(普通/紧急)」两个独立变化维度。

java 复制代码
// 实现层接口:消息发送方式(变化维度1)
public interface MessageSender {
    void send(String content);
}
public class SmsSender implements MessageSender {
    @Override
    public void send(String content) {
        System.out.println("短信推送:" + content);
    }
}
public class EmailSender implements MessageSender {
    @Override
    public void send(String content) {
        System.out.println("邮件推送:" + content);
    }
}

// 抽象层:消息级别(变化维度2),持有实现层引用(桥梁)
public abstract class AbstractMessage {
    protected MessageSender sender;
    public AbstractMessage(MessageSender sender) {
        this.sender = sender;
    }
    public abstract void sendMessage(String content);
}

// 抽象层具体实现
public class NormalMessage extends AbstractMessage {
    public NormalMessage(MessageSender sender) {
        super(sender);
    }
    @Override
    public void sendMessage(String content) {
        sender.send("【普通消息】" + content);
    }
}
public class UrgentMessage extends AbstractMessage {
    public UrgentMessage(MessageSender sender) {
        super(sender);
    }
    @Override
    public void sendMessage(String content) {
        sender.send("【紧急消息】" + content);
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        // 紧急短信推送
        AbstractMessage urgentSms = new UrgentMessage(new SmsSender());
        urgentSms.sendMessage("订单超时,请立即处理!");

        // 普通邮件推送
        AbstractMessage normalEmail = new NormalMessage(new EmailSender());
        normalEmail.sendMessage("系统月度维护公告");
    }
}

3. 组合模式

3.1 核心原理

组合模式核心:将对象组装成树形层级结构,统一叶子节点(无下级)和容器节点(有下级)的调用规范,让客户端可以像使用单个独立对象一样,统一操作整个树形结构,实现「部分与整体一致」。

3.2 生产级实战案例

业务场景:后台系统树形菜单结构,顶级菜单、子菜单、功能按钮统一渲染管理。

java 复制代码
import java.util.ArrayList;
import java.util.List;

// 统一组件接口:所有菜单节点通用行为
public interface MenuComponent {
    void show();
}

// 叶子节点:功能按钮、无子菜单
public class MenuItem implements MenuComponent {
    private String name;
    public MenuItem(String name) {
        this.name = name;
    }
    @Override
    public void show() {
        System.out.println("├─ 功能按钮:" + name);
    }
}

// 容器节点:顶级/二级菜单,包含子节点
public class Menu implements MenuComponent {
    private String name;
    private List<MenuComponent> childList = new ArrayList<>();

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

    public void add(MenuComponent component) {
        childList.add(component);
    }

    @Override
    public void show() {
        System.out.println("【顶级菜单】" + name);
        for (MenuComponent component : childList) {
            component.show();
        }
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        // 构建树形菜单
        Menu rootMenu = new Menu("系统管理");
        Menu userMenu = new Menu("用户管理");
        userMenu.add(new MenuItem("新增用户"));
        userMenu.add(new MenuItem("删除用户"));
        rootMenu.add(userMenu);
        rootMenu.add(new MenuItem("系统参数配置"));

        // 统一渲染整个树形结构
        rootMenu.show();
    }
}

4. 装饰者模式

4.1 核心原理

装饰者模式核心:不修改原对象结构、不使用继承,通过特殊封装对象(装饰器)包裹原对象,动态为原对象绑定、拓展新功能,支持多层嵌套装饰,实现灵活的功能增强。

4.2 核心优势

完全遵循开闭原则,功能拓展灵活、轻量化,可动态叠加、撤销功能,解决继承臃肿、固化的问题。

4.3 生产级实战案例

业务场景:订单支付功能,基于基础支付,动态叠加积分抵扣、红包抵扣增值功能。

java 复制代码
import java.math.BigDecimal;

// 抽象组件:订单支付统一接口
public interface OrderPay {
    BigDecimal pay(BigDecimal amount);
}

// 具体基础组件:原生支付功能
public class BaseOrderPay implements OrderPay {
    @Override
    public BigDecimal pay(BigDecimal amount) {
        return amount;
    }
}

// 装饰者抽象类:持有原支付对象
public abstract class PayDecorator implements OrderPay {
    protected OrderPay orderPay;
    public PayDecorator(OrderPay orderPay) {
        this.orderPay = orderPay;
    }
}

// 具体装饰器1:积分抵扣
public class IntegralPayDecorator extends PayDecorator {
    public IntegralPayDecorator(OrderPay orderPay) {
        super(orderPay);
    }
    @Override
    public BigDecimal pay(BigDecimal amount) {
        System.out.println("积分抵扣10元");
        return orderPay.pay(amount).subtract(new BigDecimal("10"));
    }
}

// 具体装饰器2:红包抵扣
public class RedPacketPayDecorator extends PayDecorator {
    public RedPacketPayDecorator(OrderPay orderPay) {
        super(orderPay);
    }
    @Override
    public BigDecimal pay(BigDecimal amount) {
        System.out.println("红包抵扣5元");
        return orderPay.pay(amount).subtract(new BigDecimal("5"));
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        // 基础支付
        OrderPay pay = new BaseOrderPay();
        // 动态嵌套装饰,叠加双重优惠
        pay = new IntegralPayDecorator(pay);
        pay = new RedPacketPayDecorator(pay);

        BigDecimal finalAmount = pay.pay(new BigDecimal("100"));
        System.out.println("订单最终支付金额:" + finalAmount);
    }
}

5. 外观模式

5.1 核心原理

外观模式(门面模式)核心:为复杂的子系统、工具类、框架提供一个统一的高层入口接口,屏蔽子系统的复杂内部逻辑、多依赖调用,让客户端只需调用一个简单接口,即可完成复杂操作,大幅降低使用成本。

5.2 适用场景

子系统逻辑复杂、调用链路繁琐、依赖众多,需要简化客户端调用,统一收口接口。

5.3 生产级实战案例

业务场景:电商订单下单流程,包含参数校验、库存扣减、订单创建、消息通知多个复杂子流程,通过外观类统一封装入口。

java 复制代码
// 子系统1:参数校验
public class OrderValidateService {
    public boolean validate() {
        System.out.println("订单参数校验通过");
        return true;
    }
}

// 子系统2:库存扣减
public class StockService {
    public void deductStock() {
        System.out.println("商品库存扣减成功");
    }
}

// 子系统3:订单创建
public class OrderCreateService {
    public void createOrder() {
        System.out.println("订单创建成功,生成订单号");
    }
}

// 子系统4:消息通知
public class MessageNotifyService {
    public void sendNotify() {
        System.out.println("下单成功,推送短信通知用户");
    }
}

// 外观类:统一封装所有子流程,提供唯一入口
public class OrderFacade {
    private final OrderValidateService validateService = new OrderValidateService();
    private final StockService stockService = new StockService();
    private final OrderCreateService createService = new OrderCreateService();
    private final MessageNotifyService notifyService = new MessageNotifyService();

    // 统一下单入口,客户端无需感知复杂子流程
    public void placeOrder() {
        if (validateService.validate()) {
            stockService.deductStock();
            createService.createOrder();
            notifyService.sendNotify();
            System.out.println("===== 下单流程全部完成 =====");
        }
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        // 仅需调用一个接口,完成完整下单流程
        OrderFacade orderFacade = new OrderFacade();
        orderFacade.placeOrder();
    }
}

6. 享元模式

6.1 核心原理

享元模式是内存优化专用模式 ,核心思想:复用大量重复、细粒度的对象,将对象分为「内部不变状态(共享)」和「外部可变状态(非共享)」,通过工厂缓存共享对象,避免重复创建大量相同对象,节约内存资源。

6.2 适用场景

系统存在大量重复细粒度对象,对象大部分状态固定,仅少量状态变化(如线程池、连接池、字符缓存)。

6.3 生产级实战案例

业务场景:系统日志打印工具,大量重复日志模板对象,通过享元工厂缓存复用模板,减少对象创建。

java 复制代码
import java.util.HashMap;
import java.util.Map;

// 抽象享元角色:日志模板
public interface LogTemplate {
    void printLog(String content);
}

// 具体享元角色:可共享的日志模板(内部状态固定)
public class CommonLogTemplate implements LogTemplate {
    // 内部不变状态:日志模板前缀(全局共享)
    private final String templatePrefix;

    public CommonLogTemplate(String templatePrefix) {
        this.templatePrefix = templatePrefix;
    }

    @Override
    public void printLog(String content) {
        // 外部可变状态:日志内容(每次不同)
        System.out.println(templatePrefix + ":" + content);
    }
}

// 享元工厂:缓存共享对象,统一复用
public class LogTemplateFactory {
    // 缓存池:存储所有可共享的模板对象
    private static final Map<String, LogTemplate> CACHE_POOL = new HashMap<>();

    // 获取共享模板,存在则复用,不存在则创建并缓存
    public static LogTemplate getTemplate(String prefix) {
        if (!CACHE_POOL.containsKey(prefix)) {
            CACHE_POOL.put(prefix, new CommonLogTemplate(prefix));
        }
        return CACHE_POOL.get(prefix);
    }

    // 获取缓存对象数量
    public static int getCacheSize() {
        return CACHE_POOL.size();
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        // 多次获取同一模板,复用同一个对象
        LogTemplate info1 = LogTemplateFactory.getTemplate("【INFO】");
        LogTemplate info2 = LogTemplateFactory.getTemplate("【INFO】");
        LogTemplate error = LogTemplateFactory.getTemplate("【ERROR】");

        info1.printLog("系统加载完成");
        info2.printLog("接口调用成功");
        error.printLog("参数异常");

        // 缓存仅2个对象,实现大量场景复用
        System.out.println("缓存模板数量:" + LogTemplateFactory.getCacheSize());
        System.out.println("INFO模板是否复用:" + (info1 == info2));
    }
}

7. 代理模式

7.1 核心原理

代理模式核心:通过代理对象控制对真实目标对象的访问,在不修改真实对象代码的前提下,通过代理层前置、后置拓展通用逻辑(日志、权限、事务、限流),真实对象专注核心业务。

7.2 适用场景

需要对目标对象的方法进行增强、拦截、权限控制、延迟加载、日志记录等通用切面逻辑。

7.3 生产级实战案例(静态代理)

业务场景:用户查询服务,通过代理类统一添加接口调用日志、耗时统计,不改动核心查询逻辑。

java 复制代码
// 统一业务接口
public interface UserQueryService {
    User getUserInfo(Long userId);
}

// 真实目标对象:核心业务实现
public class UserQueryServiceImpl implements UserQueryService {
    @Override
    public User getUserInfo(Long userId) {
        // 核心业务逻辑
        return new User(userId, "testUser", "13800138000");
    }
}

// 代理对象:增强核心方法
public class UserQueryProxy implements UserQueryService {
    // 持有真实目标对象
    private final UserQueryService target;

    public UserQueryProxy(UserQueryService target) {
        this.target = target;
    }

    @Override
    public User getUserInfo(Long userId) {
        // 前置增强:记录调用日志、开始时间
        System.out.println("开始调用用户查询接口,用户ID:" + userId);
        long startTime = System.currentTimeMillis();

        // 执行核心业务逻辑
        User user = target.getUserInfo(userId);

        // 后置增强:统计耗时、结束日志
        long cost = System.currentTimeMillis() - startTime;
        System.out.println("用户查询接口调用结束,耗时:" + cost + "ms");
        return user;
    }
}

// 实体类
class User {
    private Long userId;
    private String username;
    private String phone;
    // 构造器、getter省略
    public User(Long userId, String username, String phone) {
        this.userId = userId;
        this.username = username;
        this.phone = phone;
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        // 通过代理访问目标对象
        UserQueryService proxy = new UserQueryProxy(new UserQueryServiceImpl());
        User user = proxy.getUserInfo(1001L);
        System.out.println("查询用户信息:" + user.getUsername());
    }
}

三、高频相似设计模式核心区别

3.1 简单工厂 VS 工厂方法 VS 抽象工厂

  • 简单工厂:单一工厂类+条件判断,创建单一产品,不满足开闭,适合简单小项目

  • 工厂方法 :一产品一工厂,专注单一产品拓展,满足开闭,适合单一品类迭代场景

  • 抽象工厂 :一工厂一族产品,专注产品族配套创建,强制关联产品,适合多系列配套场景

3.2 建造者模式 VS 工厂模式

  • 工厂模式 :专注「对象快速创建」,直接返回完整对象,无分步构建过程,适合普通简单对象

  • 建造者模式 :专注「复杂对象分步组装」,可控参数、链式构建、支持参数校验,适合多字段、复杂配置对象

3.3 装饰者模式 VS 代理模式

  • 装饰者 :核心是增强对象功能,动态叠加业务能力(抵扣、权限、校验),可多层嵌套,关注「业务功能拓展」

  • 代理模式 :核心是控制对象访问,做日志、事务、限流、权限拦截,不改变原有业务功能,关注「访问控制与通用增强」

3.4 桥接模式 VS 适配器模式

  • 适配器 :解决现有不兼容接口的适配问题,是事后补救、兼容老代码

  • 桥接 :提前解耦两个变化维度,规避后续拓展的类爆炸问题,是事前架构优化

3.5 外观模式 VS 适配器模式

  • 适配器:1对1适配,解决两个接口不兼容问题

  • 外观模式:多对一收口,封装多个复杂子系统,简化客户端调用,不解决接口兼容问题

相关推荐
_muffinman1 小时前
梁山派学习笔记1
笔记·学习
AI云海10 小时前
利用好手机这个工具-碎片化学习
学习
β添砖java12 小时前
2025最新快速构建企业级虚拟专用网络环境学习笔记
笔记·学习
WZF-Sang17 小时前
网络基础——2
服务器·网络·c++·学习·网络编程·php
心中有国也有家18 小时前
E-Brufen 技术选型全景:Flutter + 鸿蒙 + Hive CE
hive·hadoop·学习·flutter·华为·harmonyos
没头脑的男大19 小时前
CMake学习教学
linux·c++·学习
New农民工19 小时前
射频芯片学习-ExpressLRS 对频流程分析
学习
geovindu19 小时前
java:Abstract Factory Pattern
java·开发语言·后端·设计模式·抽象工厂模式·创建型模式
geovindu19 小时前
java: Factory Method Pattern
java·开发语言·后端·设计模式·工厂方法模式·创建型模式