企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
### Pull Up Constructor Body(构造函数本体上移) 你在各个subclass 中拥有一些构造函数,它们的本体(代码)几乎完全一致。 在superclass 中新建一个构造函数,并在subclass 构造函数中调用它。 ~~~ class Manager extends Employee... public Manager (String name, String id, int grade) { _name = name; _id = id; _grade = grade; } ~~~ => ~~~ public Manager (String name, String id, int grade) { super (name, id); _grade = grade; } ~~~ **动机(Motivation)** 构造函数(constructors )是很奇妙的东西。它们不是普通函数,使用它们比使用普通函数受到更多的限制。 如果你看见各个subclass 中的函数有共同行为,你的第一个念头应该是将共同行为提炼到一个独立函数中,然后将这个函数提升到superclass 。对构造函数而言,它们彼此的共同行为往往就是「对象的建构」。这时候你需要在superclass 中提供一个构造函数,然后让subclass 都来调用它。很多时候,「调用superclass 构造函数」就是subclass 构造函数的惟一动作。这里不能运用Pull Up Method,因为你无法在subclass 中继承superclass 构造函数(你可曾痛恨过这个规定?)。 如果重构过程过于复杂,你可以考虑转而使用Replace Constructor with Factory Method。 **作法(Mechanics)** - 在superclass 中定义一个构造函数。 - 将subclass 构造函数中的共同代码搬移到superclass 构造函数中。 - 被搬移的可能是subclass 构造函数的全部内容。 - 首先设法将共同代码搬移到subclass 构造函数起始处,然后再拷贝到superclass构造函数中。 - 将subclass 构造函数中的共同代码删掉,改而调用新建的superclass 构造函数。 - 如果subclass 构造函数中的所有代码都是共同码,那么对superclass 构造函数的调用将是subclass 构造函数的惟一动作。 - 编译,测试。 - 如果日后subclass 构造函数再出现共同代码,你可以首先使用 Extract Method 将那一部分提炼到一个独立函数,然后使用Pull Up Method 将该函数上移到superclass。 **范例:(Example)** 下面是一个表示「雇员」的Employee class 禾11 一个表示「经理」的Manager class: ~~~ class Employee... protected String _name; protected String _id; class Manager extends Employee... public Manager (String name, String id, int grade) { _name = name; _id = id; _grade = grade; } private int _grade; ~~~ Employee 的值域应该在Employee 构造函数中被设妥初值。因此我定义了一个Employee 构造函数,并将它声明为protected,表示subclass 应该调用它: ~~~ class Employee protected Employee (String name, String id) { _name = name; _id = id; } ~~~ 然后,我从中调用它: ~~~ public Manager (String name, String id, int grade) { super (name, id); _grade = grade; } ~~~ 后来情况又有些变化,构造函数中出现了共同代码。假如我有以下代码: ~~~ class Employee... boolean isPriviliged() {..} void assignCar() {..} class Manager... public Manager (String name, String id, int grade) { super (name, id); _grade = grade; if (isPriviliged()) assignCar(); //every subclass does this } boolean isPriviliged() { return _grade > 4; } ~~~ 我不能把调用assignCar() 的行为移到superclass 构造函数中,因为惟有把合适的值赋给_grade 值域后才能执行assignCar() 。此时我需要Extract Method 和 Pull Up Method。 ~~~ class Employee... void initialize() { if (isPriviliged()) assignCar(); } class Manager... public Manager (String name, String id, int grade) { super (name, id); _grade = grade; initialize(); } ~~~