JavaScript Refactoring — Class Refactoring
Tags: webdev, programming, javascript, codequality
Published: 2021-01-25 03:22:45

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

We can clean up our JavaScript code so that we can work with them more easily.

In this article, we’ll look at some refactoring ideas that are relevant for cleaning up JavaScript conditionals.

### Pull Up Constructor Body

If we have multiple constructor bodies in our subclasses with overlapping code, we can move them to the superclass.

For instance, if we have the following code:

```
class Employee {

}

class Cook extends Employee {
  constructor(name, level) {
    this.name = name;
    this.level = level;
  }
}

class Manager extends Employee {
  constructor(name) {
    this.name = name;
  }
}
```

We can move the common code in both constructors to the superclass as follows:

```
class Employee {
  constructor(name) {
    this.name = name;
  }
}

class Cook extends Employee {
  constructor(name, level) {
    super(name)
    this.level = level;
  }
}

class Manager extends Employee {

}
```

In the code above, we move the code for setting the `name` field to the `Employee` class to avoiding duplicating that in the `Cook` and `Manager` classes.

### Push Down Method

If we have superclass methods that are only used by an instance of one subclass, then we should move it to the subclass.

For instance, if we have the following code:

```
class Employee {
  speak() {
    //...
  }
}

class Cook extends Employee {

}

class Manager extends Employee {

}

const cook = new Cook();
cook.speak();
```

Since `speak` is only called by a `Cook` instance, we can move it to the `Cook` class:

```
class Employee {

}

class Cook extends Employee {
  speak() {
    //...
  }
}

class Manager extends Employee {

}

const cook = new Cook();
cook.speak();
```

This way, we can reduce the clutter of our superclass.

### Push Down Field

We push down a field that’s only used in one or a few subclasses to the subclass itself.

For instance, instead of writing the following code:

```
class Employee {
  constructor(subordinates) {
    this.subordinates = subordinates;
  }
}

class Cook extends Employee {

}

class Manager extends Employee {

}
```

We can put the `subordinates` field to the `Manager` class as follows:

```
class Employee {
  //...
}

class Cook extends Employee {
  //...
}

class Manager extends Employee {
  constructor(subordinates) {
    this.subordinates = subordinates;
  }
}
```

The `subordinates` field only applies to `Manager` so it should be there.

### Extract Subclass

If we have a class that has features that are only used by some instances, then it should be extracted to its own subclass.

For instance, if we have the following code:

```
class Employee {
  //...
  getSubordinates() {
    //...
  }
}
```

Then since `getSubordinates` isn’t used by all `Employee` instances, we can extract it as follows:

```
class Employee {
  //...
}

class Manager extends Employee {
  //...
  getSubordinates() {
    //...
  }
}
```

This way, we don’t have to clutter up the `Employee` class with methods that not all instances need.

### Extract Superclass

If we have 2 or more classes with similar features, then we should move the shared members to a superclass.

Then the existing classes can be subclasses of the superclass.

For instance, if we have the following code:

```
class Cat {
  //...
  speak() {
    //...
  }
}

class Dog {
  //...
  speak() {
    //...
  }
}
```

Then we can create a new class with the `speak` method and make `Cat` and `Dog` subclasses of that class as follows:

```
class Animal {
  //...
  speak() {
    //...
  }
}

class Cat extends Animal {

}

class Dog extends Animal {

}
```

Now we don’t have any more duplication.

![](https://cdn-images-1.medium.com/max/800/0*icW8JAI_2RVBUxNu)Photo by [NeONBRAND](https://unsplash.com/@neonbrand?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)

### Collapse Hierarchy

If the subclass and superclass aren’t too different, then we can combine them into one.

For instance, if we have the following:

```
class Animal {
  //...
  speak() {
    //...
  }
}

class Cat extends Animal {
  //...
}
```

We can combine them as follows:

```
class Animal {
  //...
  speak() {
    //...
  }
}
```

Since the `Cat` class didn’t have many extra things we need, we can just remove it.

Any overly complex class hierarchy isn’t good.

### Conclusion

We can remove duplicate from multiple classes by moving common code to a superclass.

If we don’t need much in a subclass, then we can remove it and combine all the members into one class.