处理概括关系之三 :Pull Up Constructor Body(构造函数本体上移)

来源:互联网 发布:闪电抢购软件使用方法 编辑:程序博客网 时间:2024/05/01 07:31

你在各个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();

   }

原创粉丝点击