以工厂函数取代构造函数
Employee (int type) {
_type = type;
}
=======================>
static Employee create (int type) {
return new Employee(type);
}
动机
你可能常常需要根据type code 创建相应的对象, 现在, 创建名单中还得加上subclasses, 那些subclasses 也是根据type code 来创建。你也可以令你的factory method 根据参数的个数和型别, 选择不同的创建行为。
做法
- 新建一个factory method , 让它调用现有的构造函数
- 将「 对构造函数的调用」 替换为「 对factory method 的调用」
- 每次替换后, 编译并测试
- 将
构造函数
声明为private
- 编译
范例
class Employee {
private int _type;
static final int ENGINEER = 0;
static final int SALESMAN = 1;
static final int MANAGER = 2;
Employee (int type) {
_type = type;
}
}
==========================>
// 有一个switch 语句。 如果添加一个新的subclass, 就必须记得更新这里的switch 语句, 而我又偏偏很健忘。
static Employee create(int type) {
switch (type) {
case ENGINEER:
return new Engineer();
case SALESMAN:
return new Salesman();
case MANAGER:
return new Manager();
default:
throw new IllegalArgumentExcption("Incorrect type code value");
}
}
==========================>
// 绕过这个switch语句最好的办法是使用Class.frName()。
static Employee create (String name) {
try {
return (Employee) Class.forName(name).newInstance();
} catch (Exception e) {
throw new IllegalArgumentException ("Unable to instantiate" + name);
}
}
// 让create (int type) 调用create(String name)
class Employee {
static Employee create (int type) {
swtich (type) {
case ENGINEER:
return create("Enginerr");
case SALESMAN:
return create("Salesman");
case MANAGER:
return create("Manager");
default:
throw new IllegalArgumentException("Incorrect type code value");
}
}
}
================================>
// 移除int版本
// 另一个「必须谨慎使用(Class.forName() 」 的原因是: 它向用户暴露了subclass 名称。
Employee.create("Engineer");
范例2: 以明确函数创建subclass
如果你只有少数几个subclasses, 而且它们都不再变化, 这条途径是很有用的。
class Person...
static Person createMale(){
return new Male();
}
static Person createFemale(){
return new Female();
}
// 然后可以把这个调用
Person kent = new Male();
// 替换为
Person kent = Person.createMale();