《Effective Java》读书笔记 Item 1:考虑静态工厂方法,而不是构造器
众所周知,要想能获取一个类的实例,该类得要提供一个public的构造器。但是《Effective Java》书中说还有一个方法,那就是提供静态工厂方法(static factory method),该方法时静态,同时可以根据参数返回一个类的实例。这里的静态工厂方法(static factory method)和设计模式里的工厂方法(factory method)是不一样的,我觉得工厂方法注重的是多态。
使用静态工厂方法有利也有弊。
优点:
不像构造器那样,静态工厂方法拥有名字
静态工厂方法是有名称的,这样就有了“可读性”,看到方法的名称就能知道能返回什么样的实例。而对于构造器,通过提供参数,但是有时会让人很迷惑,因为有时是因为传递的参数之不同而返回特定的实例,书中举的例子是BigInteger(int, int, Random)这个构造器,如果想要返回一个素数,那么你就得传入合适的参数进去,但是如果BigInteget中有个静态方法是probablePrime,那么当开发者一看名字就很明白了,明白这个方法返回的是什么实例。有时一个类会有几个构造器,每个构造器的参数个数相差一点点,或者是参数个数相等,但是各个参数的意义不同,有时是参数个数不等,这些情况下,当使用该类的开发人员在用构造器实例化时,会很苦恼,得去看文档,知道每个参数的意义才行。
我觉得这一点是很实用的,在平时写代码时,我觉得得用上。
不像构造器那样,每次调用都要创建对象
Boolean.valueOf(boolean)这个方法正体现了这一点,通过阅读源代码,可以发现在Boolean类里有TRUE和FALSE这两个静态字段。valueOf方法只是判断传来的参数值然后返回合适的对象(TRUE或FALSE),也就是说这两个对象只是在Boolean类加载时创建,以后如果需要用到,就不要再重新创建,直接返回就行了。如果创建某个对象的代价相当可观,那么这个方法的优点就很明显了。不过的确是有不少情况,我们不需要重复地创建对象。
通过静态工厂方法,我们还可以在每次调用时都返回同一个对象。singleton模式就是例子。
不像构造器那样,静态工厂方法可以返回类型的某个子类型
静态工厂方法可以减少冗长的创建参数化类型时的代码
当使用构造器创建参数类型时,我们要这样做:
Map<String, List<String>> m = new HashMap<String, List<String>>();
public static <K, V> HashMap<K, V> newInstance() {
return new HashMap<K, V>();
}
Map<String, List<String>> m = HashMap.newInstance();
缺点
一个类在仅提供静态工厂方法,同时没有公共或受保护的构造器时,此类是没法被子类化的
在Collections Framework里就有这样的例子。不过这也算是因祸得福吧,这样我们可以尽量去通过组合(composition),而不是去通过继承(inheritance)来解决某些问题。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?