关于静态工厂方法,最开始在lab2中遇到,其中的interface的实例化采用了静态工厂方法,但是对于此一直很不清晰,到后期的”设计模式“中又提及,于是专门查资料,稍稍明白一些。
首先最大的误区就是,静态工厂方法绝不仅仅是interface或者abstract class才可以使用(这一误解可能来源于第一次见到静态工厂方法就是在接口中的使用,所以误会它仅能在接口中使用),普通类也可以使用,只是上述两种使用更为常见。而至于为什么使用静态工厂方法,课内所讲的最重要一点是减少暴露给客户端的信息。“暴露得越多,出错误的概率就越大”,所以,为了不让客户端知道我们实现类是怎样的就干脆把他隐藏起来。这一点感觉在接口和抽象类上使用体现更明显。
而在查资料过程中发现,静态工厂方法的优点绝不仅于此。这涉及到overload。
例如下面这个例子,构造方法虽然也可以有多个,但是由于函数名已经被固定,所以就要求参数必须有差异时(类型、数量或者顺序)才能够重载了。当我想要Child( int age)和Child(int weight)的时候,就不允许了(因为java只会看参数的类型,静态检查类型,发现两个参数类型都是int,就认为他们是一个),但是其实按照参数含义来讲,是两个不同的构造函数。
class Child{
int age = 10;
int weight = 30;
public Child(int age, int weight) {
this.age = age;
this.weight = weight;
}
public Child(int age) {
this.age = age;
}
//不允许 public Child( int weight) {
// this.weight = weight;
// }
}
这时候,就可以用静态工厂方法了,因为静态工厂方法对于方法命名没有要求。
class Child{
int age = 10;
int weight = 30;
public static Child newChild(int age, int weight) {
Child child = new Child();
child.weight = weight;
child.age = age;
return child;
}
public static Child newChildWithWeight(int weight) {
Child child = new Child();
child.weight = weight;
return child;
}
public static Child newChildWithAge(int age) {
Child child = new Child();
child.age = age;
return child;
}
}
从这也看出,普通类也可以使用静态工厂方法。
还查到一个优点,是我在lab3中深有体会的, 多了一层控制,方便统一修改。
在lab3中,编写PollTest的代码的时候,那还不是很完全领会静态工厂方法,在Test里需要一个Poll实例,但是此时实现类都还没有写,该怎么办?也正是这个时候,我开始不断查找资料、理解静态工厂方法的使用。