创建和销毁对象--考虑用静态方法代替构造器
当创建对象时,直接使用构造器是最自然不过的事情,但不妨考虑一下静态工厂方法。
注:区别于设计模式中的工厂方法,它只是一个静态的方法而已;设计模式中的工厂方法通常包括商品和工厂两个组件,没那么复杂。
因为它可以为你带来以下构造器所不能提供的优势:
1. 有名称
场景:构造器的命名都一致
当一个类需要提供多个构造器时,通常只是通过不同的入参加以区分,但其函数名还是相同的,无法提供较高的区分度。
这时,不妨考虑用静态工厂方法代替构造器,并且慎重地选择名称以便突出它们之间的区别。
2. 不必在每一次创建时都提供新对象
场景:调用构造器时每次都创建新对象
这一点很显然,我们知道Singleton其实也提供一个静态工厂方法获取实例。
除此之外,可以用==代替equals()方法,达到性能的提升。
3. 返回子类型
场景:构造器只能返回当前类的实例,无法返回子类的实例。
这个优点的确很有用,能狗充分利用多态,使代码更具有可扩展性。
设计模式中的工厂方法也有体现,可根据入参type返回类型为Types的不同子类实例。
1 public Types getType(String type) {...}
4. 使代码更加简单
场景: Java的泛型类在实例化时,还是需要写两次类型参数,非常冗长
静态工厂方法可以帮你改善这种情况:
举个例子,假设在HashMap类中提供如下静态工厂方法:
1 public static <k, v> HashMap<k, v> getInstance() { 2 return new HashMap<k, v>(); 3 }
那么,调用时应该是这样的:
HashMap<Stirng, List<String>> m = HashMap.newInstance();
但现实确实这样的,非常啰嗦:
HashMap<String, List<String>> m = new HashMap<String, List<String>>();
但是,我们也应该很清楚的认识到使用静态工厂方法带来的隐患:
1. 如果类中没有提供public或protected的构造器,将造成该类不能子类化
不能子类化在某些情况下是无法接受的,但是,这样也有好处:策略模式教导我们应该多用组合而不是继承,当一个类不能子类化后,组合将是你唯一的选择。
2. 静态工厂方法和其他静态方法本质上并没有区别
前已经述及,静态工厂方法本质上就是一个静态方法。这使得使用人员在查阅JavaDoc时,可能将其和一般的静态方法混淆,造成使用上的困扰。
总结:
鉴于构造器有各种各样的不便,可以考虑用静态方法代替。它会给我们带来以下优缺点:
优点:
1) 有名称;
2)不必在每一次创建时都提供新对象;
3) 返回子类型;
4) 使代码更加简单。
缺点:
1)如果类中没有提供public或protected的构造器,将造成该类不能子类化;
2)静态工厂方法和其他静态方法本质上并没有区别。