静态工厂方法,也不知道为何叫这个名字。其实也就是一个静态函数,可以替代构造函数用。大名鼎鼎的 guava 就大量使用这种模式,这是非常有用的模式。

比如是

Integer i = Integer.valueOf(123);
Boolean bool = Boolean.valueOf(true);
//guava 的方法
ConcurrentMap<String,Integer> concurrentMap = Maps.newConcurrentMap();
ArrayList<Integer> array = Lists.newArrayList(1,2,3,4,5);

那么为什么要用静态工厂方法呢?

《effective java》解释得挺好的,下面我就进行“人类的本质”,并加点个人的见解。

静态工厂方法,可以不用创建新的对象

可以去看下 Integer.valueOf 函数

public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

如果是 -128 到 127,通过 valueOf 构造对象能从对象池中直接获取,避免了对象重复构建!

如果是 Boolean 对象,只有 True 和 False 效果就更明显了。

有名字就是好

比如有个 User 类,有 Name,Address,Email等字段。有些数据只需 Name、和 Email 字段就可以了,有些字段只需 Name 和 Address 字段就可以了。但这确实不能创建两个相同类型的构造器!但你可以创建newNameWithEmail 或者 newNameWithAddress 的静态工厂函数。方便!

免去繁琐,不用写太多的通配符

这个也是被 guava 发扬广大,

比如:正常构造一个 HashMap

Map<String,List<String>> map = new HashMap<String,List<String>>();

前面类型都定义好了,为毛还要写 new HashMap<String,List<String>>();这样的一大串东西;

guava中只要这样就可以了,而且还是类型安全的!

Map<String,List<String>> map = Maps.newHashMap();

怎样做到的呢?看下以前版本的实现。

public static <K, V> HashMap<K, V> newHashMap() {
return new HashMap<K,V>();
}

其实 ,java 官方也发现这个问题的 java 7 在这样一种语法糖

Map<String,List<String>> map = new HashMap<>();

java 9 后 有了 var 语法糖。可以写成

var map = new HashMap<String,List<String>>();

静态工厂函数的这个优势可有可无了

可以返回原返回类型的任何子类型

比如 EnumSet 根据 universe 数组的长度可以返回不同类型的 EnumSet

public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
implements Cloneable, java.io.Serializable { EnumSet(Class<E>elementType, Enum[] universe) {
} public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
if (universe.length <= 64)
return new RegularEnumSet<>(elementType, universe);
else
return new JumboEnumSet<>(elementType, universe);
}
}

确实是有点用,这种用法我是用得比较少。不喜欢用这样方式。觉得还不如不封装(逃

静态工厂方法的缺点

个人觉得,没啥缺点,甚至觉得每个类最好用静态工厂函数替代构造函数!最好还是把构造函数变成 private (逃。

这样可以强制不使用继承,只能用组合。

以上

java的设计模式 - 静态工厂方法的更多相关文章

  1. EFFECTIVE JAVA 第一天 静态工厂方法

    静态工厂方法:(这里指的是就是普通static方法),类可以通过静态工厂方法提供给它的客户端,而不是通过构造器.提供静态工厂方法而不是公有构造器,这样做有几大优势. 在类的实现中使用了API的类被称为 ...

  2. 高效JAVA之用静态工厂方法代替构造器

    程序员这行干的久了,总会染上一些恶习,我就染上一个让人深恶痛绝,自己却津津乐道的习惯,还不想改的那种,它可以叫做强迫症,也可以叫做洁癖.那就是我不允许我的IDEA出现一点点警告,什么黄色背景,绿色波浪 ...

  3. Java 的静态工厂方法

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

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

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

  5. 静态工厂方法和实例工厂方法及普通的bean

    容纳你的bean  bean工厂:最简单的容器,提供了基础的依赖注入支持.创建各种类型的Bean.  应用上下文(ApplicationContext):建立在bean工厂基础之上,提供系统架构服务. ...

  6. Spring学习--静态工厂方法、实例工厂方法创建 Bean

    通过调用静态工厂方法创建 bean: 调用静态工厂方法创建 bean 是将对象创建的过程封装到静态方法中 , 当客户端需要对象时 , 只需要简单地调用静态方法 , 而不需要关心创建对象的细节. 要声明 ...

  7. Java 设计模式之 简单工厂模式(静态工厂方法模式)

    简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的 ...

  8. Java设计模式———静态工厂

    上课时yqj2065要求:除了JDK等框架或工具中的类,自己编写的类不得使用new创建对象(Test除外). 据说是因为使用new会涉及到硬编码.(不是很懂) 所以要求用God类利用反射+配置文件来创 ...

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

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

随机推荐

  1. djiango的模板语言(template)

    老师的博客:http://www.cnblogs.com/liwenzhou/p/7931828.html 官方文档:https://docs.djangoproject.com/en/1.11/re ...

  2. ASP.NET Core实现 随处可见的基本身份认证

    概览 在HTTP中,基本认证(Basic access authentication,简称BA认证)是一种用来允许网页浏览器或其他客户端程序在请求资源时提供用户名和口令形式的身份凭证的一种登录验证方式 ...

  3. react源码总览(翻译)

    用react也有段时间了, 是时候看看人家源码了. 看源码之前看到官方文档 有这么篇文章介绍其代码结构了, 为了看源码能顺利些, 遂决定将其翻译来看看, 小弟英语也是半瓢水, 好多单词得查词典, 不当 ...

  4. Docker 快速开始

    1.  概念 对于开发人员和系统管理员来说,Docker是一个使用容器开发.部署和运行应用程序的平台.使用Linux容器部署应用程序称为容器化.容器并不新鲜,但是将它们用于轻松部署应用程序却很新鲜. ...

  5. 基于 HTTP 请求拦截,快速解决跨域和代理 Mock

    近几年,随着 Web 开发逐渐成熟,前后端分离的架构设计越来越被众多开发者认可,使得前端和后端可以专注各自的职能,降低沟通成本,提高开发效率. 在前后端分离的开发模式下,前端和后端工程师得以并行工作. ...

  6. 讲解:为什么重写equals时必须重写hashCode方法

    一 :string类型的==和equals的区别: 结论:"=="是判断两个字符串的内存地址是否相等,equals是比较两个字符串的值是否相等,具体就不做扩展了,有兴趣的同学可以去 ...

  7. 设计模式 | 建造者模式/生成器模式(builder)

    定义: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 结构:(书中图,侵删) 一个产品类 一个指定产品各个部件的抽象创建接口 若干个实现了各个部件的具体实现的创建类 一个 ...

  8. 2019-01-20 JavaScript实现ZLOGO: 界面改进与速度可调

    续前文JavaScript实现ZLOGO: 前进方向和速度 在线演示地址: http://codeinchinese.com/%E5%9C%883/%E5%9C%883.html 源码仍在: prog ...

  9. openlayers4 入门开发系列之聚合图篇(附源码下载)

    前言 openlayers4 官网的 api 文档介绍地址 openlayers4 api,里面详细的介绍 openlayers4 各个类的介绍,还有就是在线例子:openlayers4 官网在线例子 ...

  10. openlayers一:显示地图与鼠标地理坐标

    openlayers两个好用的开源JS互动地图库之一,另一个是leaflet. openlayers的特点是是大而全,自身包含绝大多数功能,文档好看. leaflet是小而美,自身小,但支持扩展,好用 ...