8、(结构型设计模式)Java 适配器模式深度学习指南

用Omniverse Kit开发第一个USD插件:从环境配置到实战案例(Python 3.7版) 本文详细介绍了如何使用NVIDIA Omniverse Kit和Python 3.7开发第一个USD插件,涵盖从环境配置到实战案例的全过程。通过创建可实时同步材质属性的USD插件,开发者可以快速掌握Omniverse开发框架,提升3D内容创作效率。 阅读详情

以下是为你精心撰写的 《Java 适配器模式深度学习指南》,专为 Java 后端开发者打造,内容涵盖:定义、作用、与桥接模式的深度对比、真实业务场景、实现方式(类适配器、对象适配器)、Spring 集成、避坑指南、最佳实践、面试高频题,所有示例均含中文注释,可直接用于项目重构、第三方 SDK 接入、遗留系统兼容、微服务网关等实战场景。


📘 Java 适配器模式深度学习指南

—— 从“接口不兼容”到“无缝衔接”的架构桥梁

作者:Java 后端架构实战导师
适用对象:Java 后端开发者(Spring Boot / 微服务 / 第三方 SDK / 遗留系统 / API 网关)
目标:彻底掌握“让不兼容的接口协同工作”的核心设计模式,告别“改旧代码、写胶水代码”的痛苦
核心原则:“我不是改你,我是帮你穿上新衣服”


✅ 一、什么是适配器模式?

📌 定义:

适配器模式(Adapter Pattern) 是一种结构型设计模式,它将一个类的接口转换成客户端期望的另一个接口,使原本因接口不兼容而无法一起工作的类可以协同工作。

🔍 核心思想:

  • 你有一个老系统(或第三方库),它的接口是 OldInterface
  • 你的新系统需要调用 NewInterface
  • 你不能修改老系统(因为是第三方、遗留代码、不可控)
  • 你写一个适配器类,实现 NewInterface,内部调用 OldInterface
  • 客户端只看到 NewInterface,完全感知不到老系统的存在

💡 一句话记忆:
“你用的是 USB-C,我只有 USB-A,我给你一个转换头,你照样能充电。”

🆚 适配器模式 vs 桥接模式(易混淆点)

维度适配器模式桥接模式
目的兼容已有接口(解决不兼容)解耦抽象与实现(让两者独立变化)
出发点“我需要调用旧系统,但接口不匹配”“我想让抽象和实现都能自由扩展”
结构适配器包装一个现有类抽象类持有一个实现接口
是否改变原系统❌ 不修改原系统,只包装✅ 原系统需拆分为抽象和实现两部分
典型场景第三方 SDK、遗留系统兼容JDBC 驱动 + 连接池、UI 主题 + 控件
类比电源转换插头可插拔的灯泡 + 灯座

✅ 关键区别:

  • 适配器:接口不兼容 → 我来适配
  • 桥接:抽象和实现都可能变 → 我来解耦

✅ 二、适配器模式有什么作用?(Why Use Adapter Pattern?)

作用说明
✅ 兼容第三方库无缝接入微信、支付宝、阿里云、腾讯云等 SDK,无需改业务代码
✅ 兼容遗留系统老系统用 XML 接口,新系统用 JSON,写适配器过渡
✅ 统一接口风格多个外部服务接口不一致,统一为内部标准接口
✅ 避免修改源码对第三方库、开源组件、遗留代码,不能改源码时的唯一选择
✅ 支持渐进式重构新旧系统并行运行,逐步迁移,降低风险
✅ 提高可测试性可 Mock 适配器,测试新系统无需依赖真实第三方
✅ 降低耦合度客户端只依赖统一接口,不依赖具体实现

💡 经典名言:
“When you have an existing class with an incompatible interface, use the Adapter pattern to make it usable.”
——《Design Patterns: Elements of Reusable Object-Oriented Software》


✅ 三、适配器模式的典型使用场景(Java 后端真实案例)

场景说明是否推荐使用适配器模式
✅ 接入第三方支付 SDK微信支付接口 vs 支付宝接口 vs 银联接口,统一为 PaymentService✅ 强烈推荐
✅ 短信服务商切换阿里云短信、腾讯云短信、自建短信平台,统一为 SmsSender✅ 推荐
✅ 日志系统迁移旧系统用 Log4j,新系统用 SLF4J,写适配器兼容✅ 推荐
✅ 数据库驱动兼容旧代码用 java.sql.Connection,新框架用 javax.sql.DataSource✅ 推荐
✅ API 网关请求转换外部请求是 REST,内部服务是 gRPC,写适配器转换✅ 推荐
✅ 消息队列适配Kafka、RabbitMQ、RocketMQ 统一为 MessageBroker 接口✅ 推荐
✅ 缓存系统切换Redis、Memcached、Caffeine 统一为 CacheProvider✅ 推荐
✅ 文件格式转换读取 .xls 文件,但内部用 CSVParser 接口✅ 推荐
❌ 简单工具类封装StringUtils 封装 String 方法❌ 用静态方法即可
❌ 接口设计不规范自己写的接口不一致,应统一设计❌ 应重构,而非适配

✅ 判断标准:
“我必须调用一个外部系统,但它的接口和我系统要求的不一致,且我不能改它?”
→ 是 → 用适配器模式!


✅ 四、适配器模式的两种实现方式详解(含中文注释)

我们从对象适配器(推荐)到类适配器(少用),逐步深入。


🔹 1. 对象适配器(Object Adapter)—— 最常用、最推荐

原理:通过组合(Has-A)方式,适配器持有一个被适配对象的引用。

/**
 * 【1】我们系统期望的统一支付接口(新接口)
 */
interface PaymentService {
    boolean pay(double amount); // 支付金额,返回成功与否
    String getPaymentMethod(); // 获取支付方式名称
}

/**
 * 【2】微信支付 SDK(第三方旧接口,我们不能修改)
 */
class WeChatPaySDK {
    // 微信 SDK 的原始方法(与我们期望的接口不一致)
    public void wechatPay(double amount) {
        System.out.println("📱 微信支付 SDK:支付 " + amount + " 元");
    }

    public String getWechatName() {
        return "微信支付";
    }
}

/**
 * 【3】支付宝 SDK(第三方旧接口,我们不能修改)
 */
class AlipaySDK {
    // 支付宝 SDK 的原始方法
    public void alipay(double amount) {
        System.out.println("💳 支付宝 SDK:支付 " + amount + " 元");
    }

    public String getAlipayName() {
        return "支付宝";
    }
}

/**
 * 【4】微信支付适配器:实现我们的 PaymentService 接口,内部调用 WeChatPaySDK
 */
class WeChatPayAdapter implements PaymentService {
    private WeChatPaySDK wechatSDK; // 组合:持有被适配对象

    public WeChatPayAdapter(WeChatPaySDK wechatSDK) {
        this.wechatSDK = wechatSDK;
    }

    @Override
    public boolean pay(double amount) {
        // 调用第三方 SDK 的方法,适配为我们的接口
        wechatSDK.wechatPay(amount);
        return true; // 假设总是成功
    }

    @Override
    public String getPaymentMethod() {
        // 调用第三方方法,转换为我们的接口返回
        return wechatSDK.getWechatName();
    }
}

/**
 * 【5】支付宝支付适配器
 */
class AlipayAdapter implements PaymentService {
    private AlipaySDK alipaySDK;

    public AlipayAdapter(AlipaySDK alipaySDK) {
        this.alipaySDK = alipaySDK;
    }

    @Override
    public boolean pay(double amount) {
        alipaySDK.alipay(amount);
        return true;
    }

    @Override
    public String getPaymentMethod() {
        return alipaySDK.getAlipayName();
    }
}

/**
 * 【6】客户端:只依赖统一接口 PaymentService,完全不知道底层是微信还是支付宝
 */
public class ObjectAdapterDemo {
    public static void main(String[] args) {
        // 创建第三方 SDK 实例
        WeChatPaySDK wechatSDK = new WeChatPaySDK();
        AlipaySDK alipaySDK = new AlipaySDK();

        // 创建适配器,将旧接口转换为新接口
        PaymentService wechatService = new WeChatPayAdapter(wechatSDK);
        PaymentService alipayService = new AlipayAdapter(alipaySDK);

        // ✅ 客户端只使用统一接口,完全解耦
        System.out.println("=== 微信支付 ===");
        wechatService.pay(199.9);
        System.out.println("支付方式:" + wechatService.getPaymentMethod());

        System.out.println("\n=== 支付宝支付 ===");
        alipayService.pay(299.9);
        System.out.println("支付方式:" + alipayService.getPaymentMethod());

        // 输出:
        // === 微信支付 ===
        // 📱 微信支付 SDK:支付 199.9 元
        // 支付方式:微信支付
        //
        // === 支付宝支付 ===
        // 💳 支付宝 SDK:支付 299.9 元
        // 支付方式:支付宝
    }
}
✅ 优点:
  • 符合组合优于继承原则
  • 支持动态切换:可运行时注入不同适配器
  • 灵活:一个适配器可包装多个对象
  • 易于测试:可 Mock WeChatPaySDK 进行单元测试
  • 推荐用于生产环境
⚠️ 缺点:
  • 每个适配器都要写一个包装类(代码量略多)

🔹 2. 类适配器(Class Adapter)—— 继承方式(不推荐)

原理:通过继承(Is-A)方式,适配器继承被适配类,同时实现目标接口。

/**
 * 【1】目标接口(同上)
 */
interface PaymentService {
    boolean pay(double amount);
    String getPaymentMethod();
}

/**
 * 【2】微信 SDK(同上)
 */
class WeChatPaySDK {
    public void wechatPay(double amount) {
        System.out.println("📱 微信支付 SDK:支付 " + amount + " 元");
    }

    public String getWechatName() {
        return "微信支付";
    }
}

/**
 * 【3】类适配器:继承 WeChatPaySDK,实现 PaymentService 接口
 * 注意:Java 不支持多重继承,只能继承一个类
 */
class WeChatPayClassAdapter extends WeChatPaySDK implements PaymentService {

    @Override
    public boolean pay(double amount) {
        // 调用父类方法
        wechatPay(amount);
        return true;
    }

    @Override
    public String getPaymentMethod() {
        // 调用父类方法
        return getWechatName();
    }
}

/**
 * 【4】客户端使用(与对象适配器相同)
 */
public class ClassAdapterDemo {
    public static void main(String[] args) {
        PaymentService adapter = new WeChatPayClassAdapter(); // 直接创建
        adapter.pay(150.0);
        System.out.println("支付方式:" + adapter.getPaymentMethod());

        // 输出:
        // 📱 微信支付 SDK:支付 150.0 元
        // 支付方式:微信支付
    }
}
✅ 优点:
  • 代码更简洁(一个类搞定)
  • 调用父类方法直接
❌ 缺点:
  • 违反组合优于继承原则
  • 只能适配一个类(Java 单继承限制)
  • 耦合度高:适配器与被适配类强绑定
  • 难以测试:无法 Mock 父类行为
  • 不推荐在生产中使用

✅ 结论:优先使用对象适配器,除非你有特殊理由必须用继承


🔹 3. 适配器模式 + Spring(企业级实战)

在 Spring 中,适配器模式无处不在!我们用 @Bean + 接口统一管理。

/**
 * 【1】统一支付接口(我们的标准)
 */
public interface PaymentService {
    boolean pay(double amount);
    String getPaymentMethod();
}

/**
 * 【2】微信 SDK(第三方,我们不能改)
 */
class WeChatPaySDK {
    public void wechatPay(double amount) {
        System.out.println("📱 微信支付 SDK:支付 " + amount + " 元");
    }

    public String getWechatName() {
        return "微信支付";
    }
}

/**
 * 【3】支付宝 SDK(第三方,我们不能改)
 */
class AlipaySDK {
    public void alipay(double amount) {
        System.out.println("💳 支付宝 SDK:支付 " + amount + " 元");
    }

    public String getAlipayName() {
        return "支付宝";
    }
}

/**
 * 【4】微信支付适配器(Spring Bean)
 */
@Component
@Primary // 默认实现
@Qualifier("wechat")
public class WeChatPayAdapter implements PaymentService {

    private final WeChatPaySDK wechatSDK;

    public WeChatPayAdapter() {
        this.wechatSDK = new WeChatPaySDK(); // 或者通过 @Autowired 注入
    }

    @Override
    public boolean pay(double amount) {
        wechatSDK.wechatPay(amount);
        return true;
    }

    @Override
    public String getPaymentMethod() {
        return wechatSDK.getWechatName();
    }
}

/**
 * 【5】支付宝支付适配器(Spring Bean)
 */
@Component
@Qualifier("alipay")
public class AlipayAdapter implements PaymentService {

    private final AlipaySDK alipaySDK;

    public AlipayAdapter() {
        this.alipaySDK = new AlipaySDK();
    }

    @Override
    public boolean pay(double amount) {
        alipaySDK.alipay(amount);
        return true;
    }

    @Override
    public String getPaymentMethod() {
        return alipaySDK.getAlipayName();
    }
}

/**
 * 【6】支付服务(业务层)
 */
@Service
public class OrderService {

    @Autowired
    @Qualifier("wechat") // 根据配置动态注入
    private PaymentService paymentService; // ✅ 客户端只依赖统一接口

    public void processPayment(double amount) {
        System.out.println("🛒 开始支付 " + amount + " 元");
        boolean success = paymentService.pay(amount);
        if (success) {
            System.out.println("✅ 支付成功,方式:" + paymentService.getPaymentMethod());
        }
    }
}

/**
 * 【7】配置类:根据配置文件动态选择支付方式
 */
@Configuration
public class PaymentConfig {

    @Value("${payment.type:wechat}") // 默认用微信
    private String paymentType;

    @Bean
    @Primary
    public PaymentService paymentService() {
        return switch (paymentType.toLowerCase()) {
            case "alipay" -> new AlipayAdapter();
            case "wechat" -> new WeChatPayAdapter();
            default -> throw new IllegalArgumentException("不支持的支付类型:" + paymentType);
        };
    }
}

/**
 * 【8】配置文件:application.yml
 */
/*
payment:
  type: alipay  # 切换为 wechat 或 alipay,无需改代码!
*/

/**
 * 【9】启动类测试
 */
@SpringBootApplication
public class SpringAdapterDemo {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(SpringAdapterDemo.class, args);
        OrderService service = context.getBean(OrderService.class);
        service.processPayment(99.9);
        // 输出:
        // 🛒 开始支付 99.9 元
        // 💳 支付宝 SDK:支付 99.9 元
        // ✅ 支付成功,方式:支付宝
    }
}
✅ 优点:
  • 零耦合:业务层完全不知道底层是微信还是支付宝
  • 配置驱动:通过 application.yml 动态切换支付方式
  • 可测试:可 Mock PaymentService 进行单元测试
  • 真正企业级:Spring Boot 中的 RestTemplate、MessageConverter、DataSource 都是适配器模式!

🔹 4. 适配器模式 + 日志系统(真实历史案例)

Java 日志系统迁移:从 Log4j 到 SLF4J

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 【1】我们系统期望的日志接口(标准)
 */
interface LoggerService {
    void info(String message);
    void error(String message);
}

/**
 * 【2】旧系统:Log4j 日志(第三方,我们不能改)
 */
import org.apache.log4j.Logger as Log4jLogger;

class Log4jWrapper implements LoggerService {
    private org.apache.log4j.Logger log4jLogger;

    public Log4jWrapper(String name) {
        this.log4jLogger = org.apache.log4j.Logger.getLogger(name);
    }

    @Override
    public void info(String message) {
        log4jLogger.info(message); // 适配
    }

    @Override
    public void error(String message) {
        log4jLogger.error(message); // 适配
    }
}

/**
 * 【3】新系统:SLF4J(标准)
 */
class Slf4jWrapper implements LoggerService {
    private org.slf4j.Logger slf4jLogger;

    public Slf4jWrapper(String name) {
        this.slf4jLogger = LoggerFactory.getLogger(name);
    }

    @Override
    public void info(String message) {
        slf4jLogger.info(message); // 适配
    }

    @Override
    public void error(String message) {
        slf4jLogger.error(message); // 适配
    }
}

/**
 * 【4】客户端统一使用 LoggerService
 */
public class LoggingDemo {
    public static void main(String[] args) {
        LoggerService logger = new Slf4jWrapper("OrderService"); // 切换为 Log4jWrapper 也行

        logger.info("用户登录成功");
        logger.error("支付失败,余额不足");
    }
}

✅ 现实世界:SLF4J 本身就是一个门面模式 + 适配器模式的结合体!
它提供统一接口,内部适配 Log4j、Logback、JUL 等实现。


✅ 五、适配器模式的避坑指南(Java 后端高频踩坑)

问题原因解决方案
❌ 用适配器模式解决“自己设计的接口不一致”应该统一设计,而非适配✅ 重构接口,不要用适配器掩盖设计缺陷
❌ 适配器中包含业务逻辑适配器只做“转换”,不做“处理”✅ 业务逻辑放在服务层,适配器只转发
❌ 忘记封装第三方异常客户端收到原始异常,无法统一处理✅ 在适配器中捕获异常,转换为统一业务异常
❌ 适配器类命名混乱WeChatPayAdapterImpl 太长✅ 命名:WeChatPayAdapter 即可,清晰即可
❌ 用类适配器导致继承链过深多层继承,难以维护✅ 优先用对象适配器
❌ 没有单元测试依赖真实第三方,测试慢✅ 用 Mockito Mock 适配器中的 SDK

✅ 六、适配器模式 vs 桥接模式 对比总结表

维度适配器模式桥接模式
目的解决接口不兼容解耦抽象与实现
关系包装(Wrapper)组合(Has-A)
改变对象不改原对象拆分原对象
扩展方向扩展适配器扩展抽象和实现
典型场景第三方 SDK、遗留系统JDBC、UI 主题、消息队列
类比电源转换插头可插拔灯泡 + 灯座

✅ 一句话区分:

  • 适配器:“你和我接口不一样,我来帮你穿新鞋”
  • 桥接:“你和我本来是一体的,现在我们分开,各自进化”

✅ 七、学习建议与进阶路径

阶段建议
📚 第一周在你的项目中,为微信/支付宝 SDK 写一个适配器,统一为 PaymentService
📚 第二周用 Spring @Bean + @Qualifier 实现支付方式动态切换
📚 第三周为你的项目中一个遗留系统(如 XML 接口)写一个适配器,转换为 JSON
📚 第四周阅读 Spring 源码:RestTemplate 如何适配不同 HttpMessageConverter?
📚 面试准备准备回答:

“你项目中哪里用了适配器模式?”
“对象适配器和类适配器区别?”
“适配器模式和桥接模式区别?”
“Spring 中的 @Bean 是适配器吗?” |


✅ 八、适配器模式面试高频题(附答案)

Q1:适配器模式解决了什么问题?

A:解决两个不兼容接口之间的协作问题,让它们无需修改源码就能协同工作。

Q2:对象适配器和类适配器的区别?

A:

  • 对象适配器:组合(Has-A),通过持有被适配对象实现
  • 类适配器:继承(Is-A),通过继承被适配类实现
    → 推荐使用对象适配器,更灵活、安全。

Q3:适配器模式和桥接模式的区别?

A:

  • 适配器:接口不兼容 → 我来适配
  • 桥接:抽象和实现都可能变 → 我来解耦
    → 一个解决“兼容性”,一个解决“扩展性”

Q4:Spring 中哪些地方用了适配器模式?

A:

  • RestTemplate → 适配 HttpMessageConverter
  • MessageConverter → 适配 JSON、XML、Protobuf
  • HandlerAdapter → 适配不同 Controller 类型
  • DataSource → 适配不同数据库驱动
    → Spring 的核心思想就是“适配一切”!

Q5:什么时候不该用适配器模式?

A:

  • 你可以修改源码,应直接统一接口
  • 你只是想封装工具类,应使用静态方法
  • 你想让抽象和实现独立演化,应使用桥接模式

✅ 九、总结:适配器模式选型决策树

graph TD
    A[是否需要接入第三方或遗留系统?] --> B{接口不兼容?}
    B -->|是| C[使用对象适配器 + 组合]
    B -->|否| D[不需要适配器]
    C --> E[是否在 Spring 项目中?]
    E -->|是| F[用 @Bean + @Qualifier + 配置文件动态注入]
    E -->|否| G[手动创建适配器实例]

✅ 最终推荐:

  • Spring 项目 → ✅ 对象适配器 + @Bean + 配置驱动(最优雅)
  • 非 Spring 项目 → ✅ 对象适配器(最安全)
  • 绝对不要:类适配器、在适配器中写业务逻辑、用适配器掩盖设计缺陷

✅ 十、结语:真正的高手,不改别人,只做转换

你不是在学“适配器模式”,你是在学“如何在不破坏世界的情况下,让世界为你所用”。

✅ 当你看到 @Bean PaymentService 由 WeChatPayAdapter 实现,而业务层完全不知道时,你已经掌握了企业级架构的精髓。
✅ 当你用 application.yml 切换支付方式,而不用重启服务时,你已经是架构师了。

不要为了“用模式”而用模式,
要为了“系统可集成、可演进、可维护”而选择它。


因果表示学习 (Causal Representation Learning, CRL) 传统的机器学习,尤其是深度学习,非常擅长学习数据中的相关性 (Correlation)。但它常常会走“捷径”,学到一些虚假的、不稳定的“表面联系”。一个AI模型在学习识别“牛”时,如果训练数据里所有的牛都在绿色的草地上,模型很可能会学到一个错误的规则:“牛 = 四条腿的生物 + 绿色背景”。你给它一张牛在海滩上的照片,它就可能不认识了。因果表示学习的目标,就是让模型超越这种表面相关性,去学习数据背后。 阅读详情

相关推荐

用blender为模型贴图并在gazebo中显示

用blender为模型贴图并在gazebo中显示 首先我用的是最新的blender2.92版本,附上链接https://www.blender.org/download/。并设置好简体中文。语言可以在编辑->偏好设置->界面里面设置。 首先界面右上角的摄像头,方块,灯光三个场景全都删除。 接着导入stl格式的模型文件,下面以tianbot_mini上面的激光雷达的模型为例。 导入激光雷达模型后,点击进入上方的UV Editing按钮进入UV编辑界面 此时我面看见网格化的激光雷达模型

qq_48427527的博客 7999

9、(结构型设计模式)Java 装饰器模式深度学习指南

《Java 装饰器模式深度学习指南》摘要 装饰器模式是一种动态扩展对象功能的结构型设计模式,通过组合而非继承实现功能叠加,符合开闭原则。核心思想是包装原始对象,在方法调用前后添加增强逻辑(如日志、缓存、加密等)。 ✅ 优势: 避免继承导致的类爆炸 支持运行时动态组合功能 每个装饰器专注单一职责 🔥 典型场景:日志增强、缓存注入、权限校验等。实现时需定义统一接口,装饰器持有被装饰对象引用,通过嵌套调用实现功能叠加。文中提供完整代码示例(含中文注释),展示如何组合日志、缓存、加密装饰器。 🌟 核心价值:用&

python15397的博客 797

VLSI数字信号处理系统——第九章滤波器和变换中的算法强度缩减

[课程学习] VLSI数字信号处理系统——第九章滤波器和变换中的算法强度缩减

夏风喃喃的博客 1603

java设计模式深度理解分析

java23种设计模式 创建型模式 单例模式 抽象工厂模式 原型模式 建造者模式 工厂模式 结构性模式 结构性模式 适配器模式 桥接模式 装饰模式 组合模式 外观模式 享元模式 代理模式 行为型模式 模板方法模式 命令模式 访问者模式 迭代器模式 观察者模式 中介者模式 备忘录模式 解释器模式 状态模式 10.策略模式 11.责任链模式 ...

qq_43917601的博客 1275

从零开始掌握RDMA拥塞控制:原理、算法与实战解析

本文深入解析了RDMA拥塞控制的核心原理与实战配置。RDMA依赖无损网络保障高性能,其关键在于PFC与ECN两大技术协同防止丢包。文章重点剖析了主流算法DCQCN的工作机制与参数调优,并简要介绍了HPCC与TIMELY等前沿算法。最后提供了在Linux上配置RoCEv2与DCQCN的详细步骤及性能调试方法,帮助读者从零构建稳定的RDMA网络环境。

weixin_28452161的博客 135

【uniapp踩坑记】App Store上传失败:Invalid Swift Support错误怎么解决?

作为一个前端出身的开发者,用 uniapp 开发原生 App 已经够挑战了,打包 iOS 上传 App Store 更是处处暗雷。这次的坑虽然小,但确实容易忽略。如果你也遇到了类似的报错,希望这篇文章能帮你少踩一次坑!

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1142

JAVA设计模式类第一博主,用这份文档覆盖GOF研磨这23种设计模式(2)

由于关于设计的知识过于博大精深,因此本书“集中火力”,重点讲述GoF著作中涉及的23个设计模式本身,以及和这些设计模式相关的应用内容。本书的示例虽然大都来自实际应用,但是经过相当的删除简化和重新组合:另外一点,为了突出设计模式这个主题,因此代码并不是按照实际应用那样来严格要求,很多例外处理、数据检测等都没有做,逻辑也未见得那么严密:还有一点, 在实际的开发中,很可能是多个模式组合来实现某个功能,但是本书为了示例某个模式,让重点突出而避免读者迷惑,会选择重点示例某个模式的用法,而简化或去掉其他模式。

2401_84910888的博客 900

如何解决群晖Docker注册表查询失败/无法拉取镜像等问题

如何解决群晖Docker注册表查询失败/无法拉取镜像等问题

XiaoqiangClub的博客 1万+

视频教程-轻松搞懂设计模式-Java

轻松搞懂设计模式 计算机软件理论硕士毕业,有十几年企业研发经验和教育行业培训...

weixin_33231032的博客 335

STM32F4 Flash数据的保存和读取。

STM32F4 Flash数据的保存和读取。

张一西的博客 9216

chembl_webresource_client 包数据接口下载chembl数据库;ZINC数据库下载、simles获取

点击进去https://zinc.docking.org/subclasses/kinase/predictions/,然后下载sdf模式,这里可以转化simles格式,如果下载csv里面没有包含simles。参考:https://github.com/chembl/chembl_webresource_client/blob/master/demo_wrc.ipynb。参考:https://zinc.docking.org/这是网页搜索查看,16条数据。这个数据这下载特别慢。

weixin_42357472的博客 3046

2024年Android面试题之Java基础篇(2),如何才能通过一线互联网公司面试

现在随着短视频,抖音,快手的流行NDK模块开发也显得越发重要,需要这块人才的企业也越来越多,随之学习这块的人也变多了,音视频的开发,往往是比较难的,而这个比较难的技术就是NDK里面的技术。音视频/高清大图片/人工智能/直播/抖音等等这年与用户最紧密,与我们生活最相关的技术一直都在寻找最终的技术落地平台,以前是windows系统,而现在则是移动系统了,移动系统中又是以Android占比绝大部分为前提,所以AndroidNDK技术已经是我们必备技能了。

2401_84538544的博客 798

13、Java 中 MQTT 异步通知与回调的使用及传感器命令处理

本文详细介绍了在 Java 中使用 MQTT 的异步通知与回调机制,并展示了如何通过 Paho Java 客户端处理与传感器交互的命令。文章包含代码示例,讲解了 MQTT 客户端的连接、订阅、消息处理以及模拟传感器数据发布的过程,适用于希望在 Java 应用中实现 MQTT 通信与设备控制的开发者。

eee77的博客 159

那些年Java面试官常问的知识点,全网最细节的sds讲解

你是java开发你就用java代码去实现书籍参考:(0)《图解算法》入门(1)《剑指offer》 剑指Offer_编程题_牛客网(2)《程序员代码面试指南 IT名企算法与数据结构题目最优解》参考左神视频(3)leetcode LeetCode - The World’s Leading Online Programming Learning Platform(4)数据结构(严蔚敏)/大话数据结构 //如果觉得教材无聊就可以看大话系列。

2401_83641533的博客 477

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Java开发除了框架还能学什么?

学习Docker容器化技术,了解容器的原理、使用和管理。学习Java的高级特性,如Java 8及以上版本的Stream API、Lambda表达式、函数式接口、Optional类、模块系统等。掌握常见的数据结构(如数组、链表、栈、队列、树、图等)和算法(如排序、搜索、递归、动态规划等)。学习并应用常见的设计模式,如工厂模式、单例模式、观察者模式、适配器模式等,以改善代码的可读性、可维护性和可扩展性。深入理解Java编程语言的核心特性,如面向对象编程、异常处理、集合框架、泛型、多线程、并发编程等。

怀揣梦想,一颗执着于技术的心从未磨灭,内心住着一颗顽强的小强时刻提醒自己层层突破自我,同时也成就他人 649

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

java人脸识别登录_【秋招总结】渣本Java应届生如愿以偿拿到阿里跟腾讯offer(双offer面经)...

【秋招总结】渣本Java应届生如愿以偿拿到阿里跟腾讯offer(双offer面经)今年9月10月份,每天苦逼的刷着群里更新的面试题,逛着群文件里面的大厂面试,每天的心情就像一个一首歌,“山路十八弯”。点击此处免费进群,暗号:知乎看过别人发的腾讯大厦,幻想过腾讯大厦向外看的感觉。大一暑假去过阿里杭州园区,担忧自己有没有机会再去。真的没想到迷茫中的自己等来了腾讯,又迎来了阿里。终有一天,梦想实现,想起...

weixin_39865952的博客 118

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

java面试资料推荐,上岸蚂蚁金服!

正文 下文中截图来源于朋友一个pdf版本的面经,把所以知识点的答案整理了下来,耗费他至少1个月时间,在本文最后部分把这个pdf分享给大家,觉得有用的麻烦点赞关注走一波,谢谢!!!面经中有他的知识点的答案,如下图示例,非常详细(文末有领取方式)!!! 1.数据结构与算法篇 你是java开发你就用java代码去实现 书籍参考: (0)《图解算法》入门(1)《剑指offer》 剑指Offer_编程题_牛客网(2)《程序员代码面试指南 IT名企算法与数据结构题目最优解》参考左神视频(3)leetcode Lee

m0_58269520的博客 180

被面试官问的Android-Framework难倒了?建议收藏

经历 坐标湖南,双非一本毕业。毕业后跟发小一起到深圳找工作。发小国防科大软件工程毕业。几乎没有太多周折,轻松入职了中国平安。像我这种双非渣本,随便在深圳拉一个外卖小哥出来学历可能都比我高。 前期找工作的过程是比较痛苦的,两个星期后我终于找到了我的第一份offer,一家刚起步的互联网小公司,Android开发岗。公司很小,开发团队实际上就4个人。APP从框架搭建到项目开发,版本发布更新后期运维,都是自己做。 之后就是各种跳槽,辗转过很多公司,积累了一些项目经验,走走停停都是些小公司。随着时间的推移,感觉自己的

fanzhang_vip0723的博客 188

python工厂模式 简书_工厂

思考题 public void printMenu() { PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu(); ArrayList breakfastItems = pancakeHouseMenu.getMenuItems(); ...»有时候,越是基础的东西,越是有人不明白。 前几天Review一个项目的代码,发现非常基础的...

weixin_35705784的博客 253

【秋招总结】渣本Java应届生如愿以偿拿到阿里跟腾讯offer(双offer面经)

前言 今年9月10月份,每天苦逼的刷着群里更新的面试题,逛着群文件里面的大厂面试,每天的心情就像一个一首歌,“山路十八弯”。点击此处免费进群,暗号:优快云 看过别人发的腾讯大厦,幻想过腾讯大厦向外看的感觉。 大一暑假去过阿里杭州园区,担忧自己有没有机会再去。 真的没想到迷茫中的自己等来了腾讯,又迎来了阿里。 终有一天,梦想实现,想起阿里园区中的一句话,“谢谢那个曾经努力的自己”。 面试情况 腾讯(WXG微信支付) 投的是CSIG云产业群,意外的被WXG微信组捞起,感谢机缘巧合吧。 腾讯简历面(编程

Javayinlei的博客 4648

鼓掌!阿里再次定义互联网实战案例,直线提高设计思想,架构思维(1)

针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。下面的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题(都整理成文档,小部分截图)最新整理电子书本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录需要这份系统化的资料的朋友,可以点击这里获取57acb)收录**需要这份系统化的资料的朋友,可以点击这里获取。

2401_84692299的博客 487

上海大厂Java面试经历:docker查看镜像文件

一、先来解读:23种设计模式要点 1.单例模式(Singleton Pattern) 2.工厂模式 3.抽象工厂模式(Abstract Factory Pattern) 4.模板方法模式(Template Method Pattern) 5.建造者模式(Builder Pattern) 6.代理模式(Proxy Pattern) 7.原型模式(Prototype Pattern) 8.中介者模式 9.命令模式 10.责任链模式 11.装饰模式(Decorator Pattern) 12.策略模式

m0_57205780的博客 98

2024年4月份我成功收获蚂蚁金服、阿里、拼多多等Offer 多亏这份“Java程序员P5—P8学习路线”

======服务注册发现API 网关配置中心事件调度(kafka)服务跟踪(starter-sleuth)服务熔断(Hystrix)Hystrix断路器机制API管理。

2401_84557547的博客 310

艰辛挺过字节Android研发岗4轮面试,收到sp offer(月薪45k)!揭秘字节面试流程及考点

以前一直是自己在网上东平西凑的找,找到的东西也是零零散散,很多时候都是看着看着就没了,时间浪费了,问题却还没得到解决,很让人抓狂。后面我就自己整理了一套资料,还别说,真香!资料有条理,有系统,还很全面,我不方便直接放出来,大家可以先看看有没有用得到的地方吧。网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。需要这份系统化学习资料的朋友,可以戳这里获取一个人可以走的很快,但一群人才能走的更远!

2301_82242351的博客 773

2024年安卓最全全面!2024华为Android岗面试真题(已解析含答案),2024年最新Android面试相关文章及Github学习资料

愿你有一天,真爱自己,善待自己。网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。需要这份系统化学习资料的朋友,可以戳这里获取一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!2.10网络上优秀容器面试题 903 Java并发一 924 Java并发进阶知识上 154。

2401_84561461的博客 540

Android 那些你不可错过的好书

《第一行代码》 如果你初窥Android,或者觉得你的基础还不够牢固,推荐你这本由 郭霖 大神著作的 《第一行代码》。 全书由浅入深、系统全面地讲解了Android软件开发的方方面面。第1章带领你搭建Android开发环境,完成你的第一个Android程序。第2章至第13章完整地讲解了Android开发中的各种基本知识和关键技术,包括四大组件、UI、碎片、广播机制、数据存储

u012426327的专栏 837
上一篇: 6、(创建型设计模式)Java 抽象工厂模式深度学习指南
下一篇: 9、(结构型设计模式)Java 装饰器模式深度学习指南
龙茶清欢
博客等级 码龄7年 3720粉丝 375原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值