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

news/2025/3/31 21:48:39/

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

好处

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

坏处

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

  工厂模式概述

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

  线程池中的工厂模式

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

1. ThreadFactory 接口

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

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

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

2. 线程池使用 ThreadFactory

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

java">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 的线程池示例:

java">import java.util.concurrent.*;// 自定义 ThreadFactory
class CustomThreadFactory implements ThreadFactory {private final String namePrefix;private int counter = 0;public CustomThreadFactory(String namePrefix) {this.namePrefix = namePrefix;}@Overridepublic 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) {// 创建自定义 ThreadFactoryThreadFactory 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 实例。

示例代码
java">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) {// 使用建造者模式构建 OkHttpClientOkHttpClient 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 实例。

示例代码
java">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>() {@Overridepublic void onResponse(Call<String> call, Response<String> response) {if (response.isSuccessful()) {System.out.println(response.body());}}@Overridepublic void onFailure(Call<String> call, Throwable t) {t.printStackTrace();}});}
}
代码解释
  • Retrofit.Builder:这是 Retrofit 的建造者类,通过它可以设置 Retrofit 的各种属性,例如基础 URL、数据转换器工厂、使用的 OkHttpClient 等。
  • .build() 方法:调用此方法后,会根据之前设置的属性构建出一个 Retrofit 实例。

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

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

感谢观看!!!


http://www.ppmy.cn/news/1583924.html

相关文章

修改git在提交代码时的名称

在git中&#xff0c;如果想修改提交代码作者的名字&#xff0c;可以进行以下操作&#xff1a; 1.在桌面或者文件夹内右击鼠标&#xff0c;点开Git Bash here。 2.进入后&#xff0c;通过git config user.name 回车查看当前名称。 3.通过git config --global user.name "…

【Kafka】Kafka可靠的数据传递

可靠性的保证 分区数据有序性 Kafka可以保证分区中的消息时有序的&#xff0c;如果同一个生产者向同一个分区写入消息&#xff0c;消息B在消息A 之后写入&#xff0c;那么Kafka可以保证消息B的偏移量比消息A的大&#xff0c;并且消费者会先读取消息A再读取消息B一条消息只有在…

单片机串口打印调试信息①

在单片机开发中&#xff0c;通过串口&#xff08;UART&#xff09;输出调试信息是最常用的调试方法之一。以下是详细的操作指南&#xff0c;包括硬件连接、代码实现和调试信息规划策略&#xff1a; 一、硬件连接与配置 硬件准备&#xff1a; USB转TTL模块&#xff1a;连接单片机…

清晰易懂的 Node.js 彻底卸载与清理教程

一、通用步骤&#xff1a;确认 Node.js 安装方式 Node.js 通常通过以下方式安装&#xff1a; 官方安装包&#xff08;.msi/.pkg/.tar.gz&#xff09;包管理器&#xff08;Homebrew/APT/YUM&#xff09;版本管理工具&#xff08;nvm、n&#xff09; 二、Windows 系统卸载 Node…

第二届边缘计算与并行、分布式计算国际学术会议(ECPDC 2025)

重要信息 时间&#xff1a;2025年4月11-13日 地点&#xff1a;武汉 官网&#xff1a;www.ic-ecpdc.org&#xff08;点击了解参会投稿等&#xff09; 简介 第二届边缘计算与并行、分布式计算国际学术会议&#xff08;ECPDC 2025&#xff09;将于2025年4月11日至13日在中国武…

Pytorch学习笔记(十二)Learning PyTorch - NLP from Scratch

这篇博客瞄准的是 pytorch 官方教程中 Learning PyTorch 章节的 NLP from Scratch 部分。 官网链接&#xff1a;https://pytorch.org/tutorials/intermediate/nlp_from_scratch_index.html 完整网盘链接: https://pan.baidu.com/s/1L9PVZ-KRDGVER-AJnXOvlQ?pwdaa2m 提取码: …

Ubuntu 优化启动时间优化

优化 Ubuntu 20.04 的启动时间可以从多个方面入手&#xff0c;以下是详细的步骤和建议&#xff1a; 一、分析启动耗时 首先检查系统启动各阶段的耗时&#xff1a; systemd-analyze time # 查看整体启动时间 systemd-analyze blame # 列出各服务/进程的启动耗时 …

React 18 核心技术深度解析:从并发渲染到异步数据流优化

文章目录 一、并发渲染架构升级二、Suspense 异步数据流管理三、自动批处理机制增强四、状态管理新范式五、服务端渲染优化六、构建与兼容性优化 一、并发渲染架构升级 React 18 通过引入并发模式&#xff08;Concurrent Mode&#xff09;重构了渲染机制&#xff0c;将单次渲染…