说实话,毕竟半路出家,虽然工作这么久,对基础和原理的东西没有多少了解和研究,导致不管是工作还是技术都有瓶颈,于是现在想回过头,结合工作经验来巩固下基础,深入学习和研究下一些原理。最近刚好在看《Effective Java》,顺便做下学习札记。
下面进入正题,说说书中 第一条:考虑用静态工厂方法代替构造器。
先说说优缺点,
优点:
1.可以用方法名来标识,提高程序可读性;
2.不必每次调用方法的时候都创建一个对象;
3.可以返回原类型的子类型;
4.使代码变得简洁。
缺点:
1.如果没有提供public或protected的构造器,则不能子类化,即不能被继承;
2.与其他的静态方法没有什么明显的区别。
我们创建一个实例通常的做法是通过构造器new一个出来,现在书中的启示提供了另一种可能,就是用静态工厂方法,这里的静态工厂方法与设计模式中的工厂方法模式不是一个概念。通过构造器new一个实例出来并没有什么问题,而且我们大多数时候都是这么做的,但是如果重载了多个构造器的话,如果不提供API文档,那么使用者将很难使用,而静态工厂方法可以任意起名,这样就很方便知道这个方法是干什么的了,这个就是上述优点1 。
下面请看一个例子。
这个例子提现静态方法的几个优点和缺点,通过getApple()和getPear()可以创建苹果和梨的实例,并且返回的是已经创建好的实例,不用每次创建对象,通过方法名也能知道创建的是哪一种对象(水果)。例子里提供了一个public构造器,这样桃子就能继承水果类了,如果没有这个构造器那么将无法继承,getPeach()方法返回的就是Fruits类的子类了,构造器则做不到这一点,这就很灵活了,当然此例中不是很好的提现,只是做个说明罢了。public class Fruits { private String info; private static final Fruits APPLE = new Fruits("苹果"); private static final Fruits PEAR = new Fruits("梨"); private static final Peach PEACH = new Peach(); public Fruits() { } private Fruits(String info) { this.info = info; } @Override public String toString() { return "水果-->" + info; } public static Fruits getApple() { return APPLE; } public static Fruits getPear() { return PEAR; } public static Fruits getPeach() { return PEACH; } } class Peach extends Fruits{ @Override public String toString() { return "水果-->桃"; } }
从例子中也可以看出静态工厂方法只是一个普通的静态方法,与其他静态方法没有什么区别(这就是缺点2),但是我们可以通过约定或者说命名规范来标识,例如用valueOf、getInstance等方法名来作为静态工厂方法的方法名,这样容易使人知道这就是静态工厂方法,他将返回一个实例。