Android第六次面试总结(Java设计模式篇一)

news2025/3/28 0:45:17

   单例模式属于创建型设计模式,它保证一个类仅有一个实例,并且提供一个全局访问点来获取该实例。下面为你详细阐述单例模式的好处和坏处。

好处

  1. 资源优化:单例模式能保证一个类只有一个实例,这对于那些创建和销毁开销大的对象(像数据库连接、线程池、缓存等)非常有用。比如,数据库连接频繁创建和销毁会消耗大量资源,使用单例模式可以确保只创建一个数据库连接实例,减少资源浪费。
  2. 全局访问:单例模式提供了一个全局访问点,使得系统中任何地方都可以访问该实例。这在多个模块需要共享同一个资源时非常方便,比如日志记录器,所有模块都可以通过单例日志记录器来记录日志。
  3. 数据一致性:由于只有一个实例存在,所有对该实例的操作都是针对同一个对象,避免了多个实例导致的数据不一致问题。例如,在多线程环境下,单例模式可以确保对共享资源的操作是线程安全的。

坏处

  1. 违反单一职责原则:单例模式的类既负责自身实例的创建和管理,又负责业务逻辑的实现,这违反了单一职责原则,使得类的职责过重,不利于代码的维护和扩展。
  2. 扩展性差:单例模式通常没有抽象层,难以进行扩展和修改。如果需要改变单例类的行为,可能需要直接修改类的代码,这违反了开闭原则。
  3. 多线程问题:虽然单例模式可以在多线程环境下保证只有一个实例,但实现线程安全的单例模式需要额外的同步机制,这会增加系统的复杂性和性能开销。
  4. 单元测试困难:单例模式的全局访问特性使得单元测试变得困难。因为单例类的状态可能会影响其他测试用例的执行结果,而且在测试过程中很难模拟不同的单例实例。

  工厂模式概述

工厂模式是一种创建型设计模式,它提供了一种创建对象的方式,将对象的创建和使用分离。其核心思想是定义一个创建对象的接口,让子类决定实例化哪个类。这样做的好处是提高了代码的可维护性和可扩展性,使得代码更符合开闭原则,即对扩展开放,对修改关闭。

  线程池中的工厂模式

在 Java 里,线程池用到了工厂模式,特别是在创建线程时。java.util.concurrent 包中的 ThreadFactory 接口就是工厂模式的体现。下面详细讲解线程池中的工厂模式:

1. ThreadFactory 接口

ThreadFactory 接口定义了创建线程的方法,代码如下:

public interface ThreadFactory {
    Thread newThread(Runnable r);
}

该接口只有一个方法 newThread,它接收一个 Runnable 对象作为参数,返回一个新的 Thread 对象。通过实现这个接口,我们可以自定义线程的创建逻辑。

2. 线程池使用 ThreadFactory

ThreadPoolExecutor 类在创建线程池时可以传入一个 ThreadFactory 对象,以此来指定线程的创建方式。以下是 ThreadPoolExecutor 的构造函数:

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         threadFactory, defaultHandler);
}

这里的 threadFactory 参数就是用来创建线程的工厂。

3. 示例代码

下面是一个使用自定义 ThreadFactory 的线程池示例:

import java.util.concurrent.*;

// 自定义 ThreadFactory
class CustomThreadFactory implements ThreadFactory {
    private final String namePrefix;
    private int counter = 0;

    public CustomThreadFactory(String namePrefix) {
        this.namePrefix = namePrefix;
    }

    @Override
    public Thread newThread(Runnable r) {
        Thread thread = new Thread(r, namePrefix + "-" + counter++);
        // 可以在这里设置线程的其他属性,如优先级、是否为守护线程等
        thread.setPriority(Thread.NORM_PRIORITY);
        return thread;
    }
}

public class ThreadPoolFactoryExample {
    public static void main(String[] args) {
        // 创建自定义 ThreadFactory
        ThreadFactory customFactory = new CustomThreadFactory("CustomThread");

        // 创建线程池
        ExecutorService executorService = new ThreadPoolExecutor(
                2,
                5,
                60L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(),
                customFactory
        );

        // 提交任务
        for (int i = 0; i < 5; i++) {
            final int taskId = i;
            executorService.submit(() -> {
                System.out.println("Task " + taskId + " is running on thread: " + Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Task " + taskId + " is completed.");
            });
        }

        // 关闭线程池
        executorService.shutdown();
    }
}
代码解释
  1. 自定义 ThreadFactoryCustomThreadFactory 类实现了 ThreadFactory 接口,在 newThread 方法中创建了一个新的线程,并为线程设置了自定义的名称和优先级。
  2. 创建线程池:在 main 方法中,我们创建了一个 ThreadPoolExecutor 线程池,并传入了自定义的 ThreadFactory
  3. 提交任务:通过 executorService.submit 方法提交了 5 个任务,每个任务会打印当前运行的线程名称和任务完成信息。
  4. 关闭线程池:使用 executorService.shutdown 方法关闭线程池。

工厂模式在线程池中的优势

  • 可定制性:能够自定义线程的创建逻辑,例如设置线程的名称、优先级、是否为守护线程等。
  • 代码复用:可以在多个线程池中复用同一个 ThreadFactory,提高代码的复用性。
  • 可维护性:将线程的创建和使用分离,使得代码更易于维护和扩展。

   建造者模式的核心思想是将复杂对象的构建和表示分离,让相同的构建过程能创建出不同的表示。在 Android 和 Java 开发中,OkHttp 和 Retrofit 这两个网络请求库就很好地运用了建造者模式。下面将结合它们详细讲解。

OkHttp 中的建造者模式

OkHttp 是一个高效的 HTTP 客户端,它使用建造者模式来配置 OkHttpClient 实例。OkHttpClient 有很多可配置的属性,例如连接超时时间、读取超时时间、拦截器等。通过建造者模式,你可以逐步设置这些属性,最后构建出一个符合需求的 OkHttpClient 实例。

示例代码
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class OkHttpBuilderExample {
    public static void main(String[] args) {
        // 使用建造者模式构建 OkHttpClient
        OkHttpClient client = new OkHttpClient.Builder()
               .connectTimeout(10, TimeUnit.SECONDS)
               .readTimeout(30, TimeUnit.SECONDS)
               .writeTimeout(30, TimeUnit.SECONDS)
               .build();

        // 创建请求
        Request request = new Request.Builder()
               .url("https://www.example.com")
               .build();

        try {
            // 发起请求
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                System.out.println(response.body().string());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
代码解释
  • OkHttpClient.Builder:这是 OkHttpClient 的建造者类,通过它可以逐步设置 OkHttpClient 的各种属性,比如连接超时时间、读取超时时间等。
  • .build() 方法:调用此方法后,会根据之前设置的属性构建出一个 OkHttpClient 实例。

Retrofit 中的建造者模式

Retrofit 是一个类型安全的 HTTP 客户端,它基于 OkHttp 构建。Retrofit 同样使用建造者模式来配置 Retrofit 实例。

示例代码
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.GET;

interface ApiService {
    @GET("users")
    Call<String> getUsers();
}

public class RetrofitBuilderExample {
    public static void main(String[] args) {
        // 使用建造者模式构建 Retrofit 实例
        Retrofit retrofit = new Retrofit.Builder()
               .baseUrl("https://api.example.com/")
               .addConverterFactory(GsonConverterFactory.create())
               .client(new OkHttpClient())
               .build();

        // 创建 API 服务实例
        ApiService apiService = retrofit.create(ApiService.class);

        // 发起请求
        Call<String> call = apiService.getUsers();
        call.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {
                if (response.isSuccessful()) {
                    System.out.println(response.body());
                }
            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {
                t.printStackTrace();
            }
        });
    }
}
代码解释
  • Retrofit.Builder:这是 Retrofit 的建造者类,通过它可以设置 Retrofit 的各种属性,例如基础 URL、数据转换器工厂、使用的 OkHttpClient 等。
  • .build() 方法:调用此方法后,会根据之前设置的属性构建出一个 Retrofit 实例。

建造者模式在 OkHttp 和 Retrofit 中的优势

  • 可配置性强:可以根据具体需求灵活配置 OkHttpClient 和 Retrofit 的各种属性,而不需要一次性传入所有参数。
  • 代码可读性高:通过链式调用的方式设置属性,使代码更易读和维护。
  • 构建过程清晰:将复杂对象的构建过程分解为多个步骤,使得构建过程更加清晰明了。

感谢观看!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2321147.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

六十天前端强化训练之第三十天之深入解析Vue3电商项目:TechStore全栈实践(文结尾附有源代码)

欢迎来到编程星辰海的博客讲解 看完可以给一个免费的三连吗&#xff0c;谢谢大佬&#xff01; 目录 深入解析Vue3电商项目&#xff1a;TechStore全栈实践 一、项目架构设计 二、核心功能实现 三、组合式API深度实践 四、性能优化实践 五、项目扩展方向 六、开发经验总结…

类与对象(中)(详解)

【本节目标】 1. 类的6个默认成员函数 2. 构造函数 3. 析构函数 4. 拷贝构造函数 5. 赋值运算符重载 6. const成员函数 7. 取地址及const取地址操作符重载 1.类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&…

ResNet与注意力机制:深度学习中的强强联合

引言 在深度学习领域&#xff0c;卷积神经网络&#xff08;CNN&#xff09;一直是图像处理任务的主流架构。然而&#xff0c;随着网络深度的增加&#xff0c;梯度消失和梯度爆炸问题逐渐显现&#xff0c;限制了网络的性能。为了解决这一问题&#xff0c;ResNet&#xff08;残差…

Flutter项目之页面实现以及路由fluro

目录&#xff1a; 1、项目代码结构2、页面编写以及路由配置main.dart(入口文件)page_content.dartindex.dartapplication.dartpubspec.yamllogin.dartdio_http.dart 3、Fluro路由routes.dartnot_found_page.dart(路由优化&#xff0c;找不到页面时展示此页面) 4、注册页面 1、项…

《Python实战进阶》第31集:特征工程:特征选择与降维技术

第31集&#xff1a;特征工程&#xff1a;特征选择与降维技术 摘要 特征工程是机器学习和数据科学中不可或缺的一环&#xff0c;其核心目标是通过选择重要特征和降低维度来提升模型性能并减少计算复杂度。本集聚焦于特征选择与降维技术&#xff0c;涵盖过滤法、包裹法、嵌入法等…

C++类与对象的第二个简单的实战练习-3.24笔记

哔哩哔哩C面向对象高级语言程序设计教程&#xff08;118集全&#xff09; 实战二 Cube.h #pragma once class Cube { private:double length;double width;double height; public:double area(void);double Volume(void);//bool judgement(double L1, double W1, double H1);…

Rk3568驱动开发_设备树点亮LED_10

设备树中添加节点 在设备树文件中添加led节点&#xff0c;添加完后需要重新编译内核&#xff0c;因为单独编译这个设备树文件生成的dtb文件目前不能直接做替换&#xff0c;所以要编译内核将编译好的boot.img文件烧录到设备里&#xff0c;boot.img里包含新添加的设备树节点&…

Unity学习之Shader(Phong与Blinn-Phong)

三、Lesson3 1、关键名称 向量 • nDir&#xff1a;法线方向&#xff0c;点乘操作时简称n&#xff1b; • lDir&#xff1a;光照方向&#xff0c;点乘操作时简称l&#xff1b; • vDir&#xff1a;观察方向&#xff0c;点乘操作时简称v&#xff1b; • rDir&#xff1a;光反…

uniapp笔记-swiper组件实现轮播图

思路 主要就是参考 swiper | uni-app官网 实现轮播图。 实例 新建一个banner.vue通用组件。 代码如下&#xff1a; <template><view>轮播图</view> </template><script> </script><style> </style> 随后在index.vue中导…

【C++ 继承】—— 青花分水、和而不同,继承中的“明明德”与“止于至善”

欢迎来到ZyyOvO的博客✨&#xff0c;一个关于探索技术的角落&#xff0c;记录学习的点滴&#x1f4d6;&#xff0c;分享实用的技巧&#x1f6e0;️&#xff0c;偶尔还有一些奇思妙想&#x1f4a1; 本文由ZyyOvO原创✍️&#xff0c;感谢支持❤️&#xff01;请尊重原创&#x1…

FPGA_YOLO(二)

上述对cnn卷积神经网络进行介绍,接下来对YOLO进行总结,并研究下怎么在FPGA怎么实现的方案。 对于一个7*7*30的输出 拥有49个cell 每一个cell都有两个bbox两个框,并且两个框所包含的信息拥有30个 4个坐标信息和一个置信度5个,剩下就是20个类别。 FPGA关于YOLO的部署 1…

蓝桥杯学习-14子集枚举,二进制枚举

子集枚举 一、回溯3-子集枚举&#xff08;递归实现指数型枚举&#xff09; 一旦涉及选与不选&#xff0c;删和不删&#xff0c;留和不留-->两种状态-->就要想到子集枚举例题1–递归实现指数型枚举19685 其实看不懂这个题目&#xff0c;好奇怪的题目。根据老师的解析来写…

人工智能时代大学教育范式重构:基于AI编程思维的能力培养路径研究

人工智能技术的快速发展正在重塑高等教育的内容与方法。本文以AI编程教育为切入点&#xff0c;通过文献分析与案例研究&#xff0c;探讨AI时代大学教育的核心能力需求与教学范式转型路径。研究发现&#xff0c;AI编程中蕴含的系统性思维训练、项目架构能力和元认知能力培养机制…

<数据集>轨道异物识别数据集<目标检测>

数据集下载链接&#xff1a;https://download.csdn.net/download/qq_53332949/90527370 数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;1659张 标注数量(xml文件个数)&#xff1a;1659 标注数量(txt文件个数)&#xff1a;1659 标注类别数&#xff1a;6 标注类别…

Pyecharts功能详解与实战示例

一、Pyecharts简介 Pyecharts是一个基于Python的开源数据可视化库&#xff0c;它基于百度的Echarts库&#xff0c;提供了丰富的图表类型和强大的交互功能。通过Pyecharts&#xff0c;你可以轻松创建各种精美的图表&#xff0c;如折线图、柱状图、饼图、散点图、地图等&#xf…

EasyUI数据表格中嵌入下拉框

效果 代码 $(function () {// 标记当前正在编辑的行var editorIndex -1;var data [{code: 1,name: 1,price: 1,status: 0},{code: 2,name: 2,price: 2,status: 1}]$(#dg).datagrid({data: data,onDblClickCell:function (index, field, value) {var dg $(this);if(field ! …

C语言:扫雷

在编程的世界里&#xff0c;扫雷游戏是一个经典的实践项目。它不仅能帮助我们巩固编程知识&#xff0c;还能锻炼逻辑思维和解决问题的能力。今天&#xff0c;就让我们一起用 C 语言来实现这个有趣的游戏&#xff0c;并且通过图文并茂的方式&#xff0c;让每一步都清晰易懂 1. 游…

操作系统必知的面试题

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…

清华大学.智灵动力-《DeepSeek行业应用实践报告》附PPT下载方法

导 读INTRODUCTION 今天分享是由清华大学.智灵动力&#xff1a;《DeepSeek行业应用实践报告》&#xff0c;主要介绍了DeepSeek模型的概述、优势、使用技巧、与其他模型的对比&#xff0c;以及在多个行业中的应用和未来发展趋势。为理解DeepSeek模型的应用和未来发展提供了深入的…

可视化图解算法:链表的奇偶重排(排序链表)

1. 题目 描述 给定一个单链表&#xff0c;请设定一个函数&#xff0c;将链表的奇数位节点和偶数位节点分别放在一起&#xff0c;重排后输出。 注意是节点的编号而非节点的数值。 数据范围&#xff1a;节点数量满足 0≤n≤105&#xff0c;节点中的值都满足 0≤val≤10000 要…