考虑用静态工厂方法代替构造器 优点 它们有名称
指的是方法的名称,能够准确描述返回的对象,对于多个构造方法的类可以使用不同的名称来描述返回对象
对于构造方法参数的含义需要结合注释才能明白用哪一个构造器,并且多构造器的时候无法确切知道使用哪个构造器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package com.stardust.effective.role1;public class Fruit { private String color; private String size; private Fruit (String color,String size) { this .color=color; this .size=size; } public static Fruit getBigGreenFruit () { return new Fruit("green" ,"big" ); } public static Fruit getSmallRedFruit () { return new Fruit("red" ,"small" ); } public static Fruit getApple () { return new Fruit("red" ,"middle" ); } }
不必每次调用的时候都创建一个新对象 单例模式,对于一些不可变类可以使用这种方式,在上面那个例子中我对构造函数进行了私有化,可以认为是一个简单的单例,但还是需要升级优化,在后面单例的几种写法中展开说。 这种方式的一个优势即不必重复创建对象,在spring中大量使用单例这种设计模式来创建单一不可变对象。 书中还提到一个如果实例受控则可以通过==来判定是否为同一实例,这种写法比equals提升了性能。
术语: 实例受控的类(instance-controlled):在某个时刻只能有某些规定的该类的实例存在。
可以返回原返回类型的任何子类型的对象 文章中是以Collections为例的,一开始没有太理解,Collections是一个工具类,构造私有化的,不能直接实例化,Collection本身是接口,不能有静态工厂方法,所以委托给Collections这个工具类来提供生产构造. 下面贴一段Collection中静态工厂的例子,以List为例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 public static <T> List<T> singletonList (T o) { return new SingletonList<>(o); } private static class SingletonList <E > extends AbstractList <E > implements RandomAccess , Serializable { private static final long serialVersionUID = 3093736618740652951L ; private final E element; SingletonList(E obj) {element = obj;} public Iterator<E> iterator () { return singletonIterator(element); } public int size () {return 1 ;} public boolean contains (Object obj) {return eq(obj, element);} public E get (int index) { if (index != 0 ) throw new IndexOutOfBoundsException("Index: " +index+", Size: 1" ); return element; } @Override public void forEach (Consumer<? super E> action) { action.accept(element); } @Override public boolean removeIf (Predicate<? super E> filter) { throw new UnsupportedOperationException(); } @Override public void replaceAll (UnaryOperator<E> operator) { throw new UnsupportedOperationException(); } @Override public void sort (Comparator<? super E> c) { } @Override public Spliterator<E> spliterator () { return singletonSpliterator(element); } } ``` 术语:基于接口的框架(interface -based framework ):框架的对外访问与接入渠道是基于接口实现的。 #### 在创建参数化类型实例的时候,使代码更加简洁 ``` java // 当前做法 Map <String , List <String >> map = new HashMap<String, List<String>>();Map<String, List<String>> map = HashMap.newInstance(); Map<String, List<String>> map = new HashMap<>();
缺点 类如果不含public或者protected的构造器, 就不能被子类化
例如Collections类,不能被子类化,另一方面就是相当于鼓励复合(Composition),类似于用Collections这类的写法
无法与其他静态方法区分,不像构造方法名称必须为类名,可以使用一些惯用的名称来弥补这一劣势
valueOf() : 类型转换方法, 返回的实例与参数具有相同的值.
of() : valueOf()的一种更简洁的替代.
getInstance(): 返回的实例通过参数来描述, 对于单例来说, 该方法没有参数, 返回唯一的实例.
newInstance(): 像getInstance()一样, 但newInstance()能确保返回的每个实例都与其他实例不同.
getType() : 像getInstance()一样, Type表示返回的对象类型, 在工厂方法处于不同的类中的时候使用.
newType() : 和newInstance()一样, Type表示返回类型, 在工厂方法处于不同的类中的时候使用.