Effective Java

考虑用静态工厂方法代替构造器

2017-04-25  本文已影响0人  KubiL

所谓构造器即构造函数

公有构造器的方式的缺点

静态工厂方法优点:

解释:
由于构造函数不能修改函数名称,然而函数的名称是对于该函数行为最好的描述,不能修改名称限制了代码的可阅读性。同时如果一个类有需要有两个相同参数的构造函数,则只能通过改变参数的顺序来达到目的。我们通过静态工厂方法都可以解决以上问题。
例如:

public class People {
    private String name;
    private Integer age;
    private String sex;
    public People(String name,Integer age){
        this.name = name;
        this.age = age;
        sex = "男";
    }
    public People(Integer age,String name){
        this.name = name;
        this.age = age;
        sex = "女";
    }
}
public class Test {
    public static void main(String[] args) {
        //问题很明显 得通过记住参数的顺序才可以返回正确的people
        People man = new People("李雷",20);
        People woman = new People(20,"韩梅梅");
    }
}
public class People {
    private String name;
    private Integer age;
    private String sex;
    private People(String name,Integer age,String sex){
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    public static People getMan(String name,Integer age){
        People man = new People(name,age,"男");
        return man;
    }
    public static People getWoman(String name,Integer age){
        People woman = new People(name,age,"女");
        return woman;
    }
}
public class Test {
    public static void main(String[] args) {
        People man =  People.getMan("李雷",20);
        People woman = People.getWoman("韩梅梅",20);
    }
}

解释:
每次使用new去调用构造函数很容易理解,必然产生一个新的对象。
使用静态构造方法即可控制每次都返回相同的对象。

public class Singleton {
    private static Singleton singleton = new Singleton();
    private Singleton(){

    }
    public static Singleton getSingleton(){
        return singleton;
    }
}

解释:
优势1.可以隐藏内部实现,显得相对智能。
例如:java.util.EnumSet
这个类没有public的构造函数,只有静态工厂方法,根据元素个数的多少返回不同的子类。对于客户端,这个是不可见的

public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
        Enum<?>[] universe = getUniverse(elementType);
        if (universe == null)
            throw new ClassCastException(elementType + " not an enum");

        if (universe.length <= 64)
            //对于数量小有性能优势
            return new RegularEnumSet<>(elementType, universe);
        else
            return new JumboEnumSet<>(elementType, universe);
    }

优势2.根据传入参数不同返回不同的子类实例
例如传入案件类别 返回不同的子类案件的实例

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

简单版

//如果我们提供一个静态工厂类
public static <K,V> HashMap<K,V> newInstance(){
  return new HashMap<K,V>();
}
Map<String,List<String>> map = HashMap.newInstance();

缺点:

  1. api中没有不会明确的说明静态代理类是用于实例化的,而构造函数会有明确的标识
    2.由于使用了静态工厂方法来实例化,我们会将类的构造函数私有化,从而导致该类无法被继承。但也不完全是缺点,毕竟组合比继承耦合度更低。
上一篇 下一篇

猜你喜欢

热点阅读