重构改善既有代码设计--以工厂函数取代构造函数

以工厂函数取代构造函数

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();
经验分享 程序员 微信小程序 职场和发展