背景

很早之前就已经自己翻译了,先简单的贴出来,并做一下回顾。

条款1 优先使用静态工厂方法而非构造函数来创建对象

允许客户端创建一个实例的传统方法是:提供一个公共构造函数;有另外一个必须成为每个程序员的编程技巧:优先使用类提供的只简单返回实例的公共静态工厂方法来创建对象。这有一个简单的Boolean类的例子:这个方法转换一个原生的boolean类型的值为一个Boolean的实例。

public static Boolean valueOf(boolean b){
return b?Boolean.TRUE:Boolean.FALSE;
}
注意这一点:类的静态工厂方法不同于设计模式的工厂设计模式。本条规约跟设计模式没有关联。

一个类可以通过静态工厂方法也可以使用公共构造函数提供给自己的客户端调用来创建实例,使用静态工厂方法而不是公共构造函数有优点也有缺点。

** 优点1:它有名字,可读性更好;**

构造函数的参数跟自己无关,没有描述返回对象;而良好命名的静态工厂方法客户端代码可读性更好,所以更容易使用;
//使用构造方法,返回一个BigInteger随机素数;
BigInteger(int , int , Random)
//更好的表达方式
public static BigInteger probablePrime();

一个类构造函数的签名格式是唯一的,程序员围绕这个限制提供了两个构造函数,他们区分的标准是不一样参数的类型组成的参数列表,这真的是一个糟糕的设计,使用这种API的人从来就没办法记住哪个构造函数对应哪个功能,并且容易误用导致调用错误;使用这些构造函数的人只能阅读代码,类文档没法区分。

因为静态工厂方法有名字,所以不存在区分的限制,在一个类有多个签名的构造函数的场景中,应该使用静态工厂方法替代构造函数,并且小心选择名字来区别;

优点2:不需要每次被调用的时候都创建一个新的对象;

这允许构造完毕的不可变类使用提前构建或者缓存的实例,避免创建不必要的重复的对象(分配重复的实例); Boolean.valueOf(boolean) 方法展示了这个技巧,它从来不创建对象,这个技巧类似于享元模式;如果创建代价昂贵的对象被频繁获取,它可以显著的提高性能;这个能力可以让类在任何时刻严格控制实例,这样的类叫做实例可控类,有几个理由应该编写实例可控类:

  1. 实例可控使类需要保证它是单例的实例数量可控;
  2. 需要保证没有两个相同的实例存在;如果a.equls(b) ; 有且只有a == b. 这是基本的享元模式。枚举类型提供了这个保证;

优点3:可以返回子类型,面向抽象编程或者说是接口编程,更灵活;

一个灵活的应用API可以返回非公开的对象,隐藏实现类从而形成契约API,这个技巧使得它可以成为基于接口的框架,接口提供自然的返回类型,(在java8之前,接口没有静态的方法,按照惯例,接口Type静态工厂方法被放到了一个不可实例化的指南类Types中;)

举个例子:java的Collections接口框架有45个种不同的应用实现,提供不可修改集合,同步集合等,几乎所有的这些实现通过一个不可实例化的类Collections的静态工厂方法来对外暴露;所有的返回对象都是非公开的的(即实际返回的是接口实现类或者返回类的子类)。这个集合框架的API比定义45个分开独立的公共类规模要小很多(它减少了集合类的数量负担,也减少了程序员必须掌握使用的API的类数量),程序员知道返回的对象精确的指出了它的接口,所以没有必要去阅读更多的实现类的文档。更进一步,使用这样一个静态工厂方法的客户端只需要参照接口而不用考虑实现类去使用,这是一个最佳实践。

在java8中,接口已经可以添加静态方法了,所以接口可以提供一个不可实例的有常规名字的指南类;接口的很多的公共静态成员放应该替代成接口本身。然而,仍然有必要把这样一个静态工厂方法实现代码放到分开的private 包下的类中;这是因为java8要求接口的静态成员必须是public,java9允许私有的静态方法,但是静态成员和静态内部类任然需要是public的;

原创不易,转载请注明出处。

ej3-1优先使用静态工厂方法而非构造函数来创建对象的更多相关文章

  1. <创建和销毁对象>经验法则——考虑用静态工厂方法代替公有构造方法

    一.引出静态工厂方法 对于java类而言,为了让使用者获取它自身的一个实例化对象,会有以下方法: 1.该类提供一个公有的构造方法.在这种情况下,程序可以通过多个“new 构造方法”语句来创建类的任意多 ...

  2. Effective Java 读书笔记(一):使用静态工厂方法代替构造器

    这是Effective Java第2章提出的第一条建议: 考虑用静态工厂方法代替构造器 此处的静态工厂方法并不是设计模式,主要指static修饰的静态方法,关于static的说明可以参考之前的博文&l ...

  3. 创建对象_工厂方法(Factory Method)模式 与 静态工厂方法

      工厂方法模式:   定义:为创建对象定义一个接口,让子类决定实例化哪个类.工厂方法让一个类的实例化延迟至子类.   应用场景: 客户类不关心使用哪个具体类,只关心该接口所提供的功能: 创建过程比较 ...

  4. Effective Java 第三版——1. 考虑使用静态工厂方法替代构造方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  5. Java 的静态工厂方法

    本文转载自:https://www.jianshu.com/p/ceb5ec8f1174 序:什么是静态工厂方法 Effective Java 2.1 静态工厂方法与构造器不同的第一优势在于,它们有名 ...

  6. 静态工厂方法VS构造器

    我之前已经介绍过关于构建者模式(Builder Pattern)的一些内容,它是一种很有用的模式用于实例化包含几个属性(可选的)的类,带来的好处是更容易读.写及维护客户端代码.今天,我将继续介绍对象创 ...

  7. 比较 Java 静态工厂方法与构造函数

    1 什么是静态工厂方法 Java 静态工厂方法是在方法前加上 public static,让这个方法变为公开.静态的方法.该方法返回该类的一个实例,就好像一个工厂生产出一个产品.所以称之为静态工厂方法 ...

  8. [原创]java WEB学习笔记102:Spring学习---Spring Bean配置:bean配置方式(工厂方法(静态工厂方法 & 实例工厂方法)、FactoryBean) 全类名

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  9. HttpSolrServer-采用静态工厂方法,创建HttpSolrServer单实例

    HttpSolrServer线程安全,如果使用下面构造器,必须对所有的请求重用相同的实例.如果实例在运行中创建的,它可能会导致连接泄漏.推荐的做法就是保持每个solr服务url的HttpSolrSer ...

随机推荐

  1. 笔记-pymysq-exception

    笔记-pymysq-exception 1.  exception DB API中定义了一些数据库操作的错误及异常,下表列出了这些错误和异常: 基本上是继承了Exception基类,没有添加额外功能. ...

  2. 汇编语言从入门到精通-5微机CPU的指令系统2

    微机CPU的指令系统 5.2.2 标志位操作指令 标志位操作指令是一组对标志位置位.复位.保存和恢复等操作的指令. 1.进位CF操作指令 a.清进位指令CLC(Clear Carry Flag):CF ...

  3. Python流程控制-3 循环控制

    循环控制,就是让程序循环运行某一段代码直到满足退出的条件,才退出循环. Python用关键字for和while来进行循环控制,但是没有其它语言的do...while语句(在Java和PHP中都有do ...

  4. 含有namespace的类型如何访问

    下图中包含的String类型,如果想要在别的文件中去访问的话: 1)需要include"ApiClient.hpp" 2)需要使用oatpp::web::client::ApiCl ...

  5. Lora笔记

    Lora笔记 2016-03-26 [概述] LPWAN技术 无线跳频技术简介 https://bitbucket.org/ [节点] SX1278测试 SX1278测试 SX1276调试总结 LoR ...

  6. Graphviz 使用笔记

    官网:Graphviz 最近一直在找如何用写代码的方式就可以实现数据结构可视化.流程图等等,于是发现了她,上手也比较简单,但正当我仅觉得不错的时候,我发现竟然还可以用python来写,瞬间好感度爆满啊 ...

  7. 2 (mysql实战) 日志系统

    前面我们系统了解了一个查询语句的执行流程,并介绍了执行过程中涉及的处理模块.相信你还记得,一条查询语句的执行过程一般是经过连接器.分析器.优化器.执行器等功能模块,最后到达存储引擎. 那么,一条更新语 ...

  8. Vue 路由组件

    目录 组件数据局部化处理 路由逻辑跳转 组件传参 父传子 子传父 组件的生命周期钩子 路由传参 全家配置自定义 CSS 与 js 总结: 组件数据局部化处理 不管页面组件还是小组件,都可能会被多次复用 ...

  9. Windows Server 2008 R2 SP1 中IIS7.5 和 TOMCAT7 整合笔记

    Windows Server 2008 R2 SP1 中IIS7.5 和 TOMCAT7 整合笔记 来源:www.roak.com 整合文件在百度网盘或博客盘 配置了N次,64位操作系统真坑爹~~~下 ...

  10. JDBC--处理事务

    1.事务是指一组逻辑操作单元,使数据从一种状态转换到另一种状态. 2.事务的四个属性: --1)原子性:事务是一个不可分割的工作单位,事务中的操作要么都发生要么都不发生: --2)一致性:事务必须是数 ...