zoukankan      html  css  js  c++  java
  • java的设计模式

    静态工厂方法,也不知道为何叫这个名字。其实也就是一个静态函数,可以替代构造函数用。大名鼎鼎的 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 (逃。
    这样可以强制不使用继承,只能用组合。

    以上

  • 相关阅读:
    數據從一個DB寫入另外一個DB
    js 控制下拉菜單的刷新
    Ajax 加載數據庫中的圖片
    Win7 註冊表 刪除登陸帳號
    產生隨機數
    借助AjaxControlToolkit实现百度搜索时的下拉列表提示
    解决"Windows 安装程序不允许从远程桌面连接安装"
    中文转换成数字金额C#【转】
    让你的Visual Studio 2010自动添加头部注释信息【转】
    C# 图片识别(支持21种语言)【转】
  • 原文地址:https://www.cnblogs.com/jojo-feed/p/10160867.html
Copyright © 2011-2022 走看看