《Effective Java》考虑用静态工厂方法代替构造器

第一条,考虑用静态工厂方法代替构造器

优点一:静态工厂可以很好的理解名称

《Effective Java》考虑用静态工厂方法代替构造器

四个构造方法,面对这样的构造方法,三个、四个是可以接受的,那如果是七个八个甚至是十几个呢?这个时候有一个好的名字就是十分重要,比如书上提到的返回素数的方法名称:BigInteger.probablePrime(),这样的名称就可以很好地区分构建实例的用途,可读性也更强。

优点二:不必每次调用它们的时候都创建一个新的对象

《Effective Java》考虑用静态工厂方法代替构造器

类StaticFactoryDemo在初始化的时候会缓存10个对象到ArrayList中,可以实习对象的复用,这里只说大概意思,具体对象池、对象工厂实现可以参考Integer、Spring的IOC。

优点三:它们可以返回原返回类型的任何子类型的对象

《Effective Java》考虑用静态工厂方法代替构造器

《Effective Java》考虑用静态工厂方法代替构造器

为了方便阅读,不添加多余实现,在StaticFactoryDemo中创建的newInstance()方法用于创建实例,这个方法的实现中返回了子类的实例,使我们的代码更灵活。

优点四:在创建参数化类型实例的时候,他们使代码变得更加简洁。(已被优化)

作者的观点是过多参数会使代码看起来不是很简洁,如下代码。

《Effective Java》考虑用静态工厂方法代替构造器

作者提供的解决办法是在HashMap中提供newIntance()方法,方法中返回复杂的泛型实例。

我的jdk版本为1.8,现在已经采取参数推断,做了优化,如下

《Effective Java》考虑用静态工厂方法代替构造器

静态工厂方法也是有缺点的

缺点一:类中如果不含有public或者protected修饰的构造方法,是无法拥有子类的。

《Effective Java》考虑用静态工厂方法代替构造器

缺点二:如果没有一个漂亮的名字和注释,其他人是很难分清这个方法是不是用来构建实例的,静态工厂方法和普通静态方法实际上没有任何区别。

作者提供了一些名字供参考,valueOf、of、getInstance、newInstance、getType、newType。

总结:静态工厂方法可以提供给我们漂亮的可供区分的名字,可以提供缓存使对象复用,可以灵活的返回子类实例。同时要注意,如果没有提供公有或者受保护的构造方法时,是无法被继承的,起一个漂亮的易于理解的名称同样也很重要,注意要与设计模式中的工厂方法区分开。在需要创建对象时,要先考虑静态工厂方法,不要直接就选公有的构造方法。