Code Smell 23 - Instance Type Checking
Tags: oop, beginners, tutorial
Published: 2020-11-13 14:11:04

*Do you check who are you talking to?*

> TL;DR: Trust your collaborators. Don't check who they are. Ask them to do instead.

# Problems

- [Coupling](https://dev.to/mcsee/coupling-the-one-and-only-software-design-problem-2pd7)

- Metamodel interference

- [IFs](https://dev.to/mcsee/how-to-get-rid-of-annoying-ifs-forever-1jfg)

# Solutions

1. Avoid *kind*, *isKindOf*, *instance*, *getClass()*, *typeOf*, etc..

2. Don't use Reflection and [Metaprogramming](https://dev.to/mcsee/laziness-i-meta-programming-32a9) for Domain Objects.

3. Replace [*IFs*](https://dev.to/mcsee/how-to-get-rid-of-annoying-ifs-forever-1jfg) with polymorphism. 

4. Avoid checking for *'undefined'*. Use [complete objects](https://dev.to/mcsee/nude-models-part-i-setters-5c9i), avoid [nulls](https://dev.to/mcsee/code-smell-12-null-la4) and setters, favor [immutability](https://dev.to/mcsee/the-evil-powers-of-mutants-1noo) and you will never have undefined and ifs.

# Sample Code

## Wrong

[Gist Url]: # (https://gist.github.com/mcsee/a2307973172b62bb9dc7b11ef7450220)
```javascript
if (typeof(x) === 'undefined') {
    console.log('variable x is not defined');   
}

function isNumber(data) {
  return (typeof data === 'number');
}

function move(animal) {
  if (animal instanceof Rabbit) {
      animal.run()
  }
  if (animal instanceof Seagull) {
      animal.fly()
  } 
}
 
class Rabbit {
  run(){
    console.log("I'm running");
  }  
}

class Seagull {
  fly(){
    console.log("I'm flying");
  }  
}

let bunny = new Rabbit();
let livingstone = new Seagull();

move(bunny);
move(livingstone);
```

## Right

[Gist Url]: # (https://gist.github.com/mcsee/5c0218fcf1362228f406e463f79171a9)
```javascript
/*Avoid these methods
if (typeof(x) === 'undefined') {
    console.log('variable x is not defined');   
}

function isNumber(data) {
  return (typeof data === 'number');
}
*/

class Animal {
} 

class Rabbit extends Animal {
  move(){
    console.log("I'm running");
  }  
}

class Seagull extends Animal {
  move(){
    console.log("I'm flying");
  }  
}

let bunny = new Rabbit();
let livingstone = new Seagull();

bunny.move();
livingstone.move();
```

# Detection

Since type checking methods are well known it is very easy to set up a code policy checking the uses.

# Tags

- Metaprogramming

# Conclusion

Testing for a class type [couples](https://dev.to/mcsee/coupling-the-one-and-only-software-design-problem-2pd7) the objects with [accidental decisions](https://dev.to/mcsee/coupling-the-one-and-only-software-design-problem-2pd7) and violates [bijection](https://dev.to/mcsee/the-one-and-only-software-design-principle-3086) since no such control exists on real world. It is a smell our models are not good enough.

# Relations

{% post https://dev.to/mcsee/code-smell-12-null-la4 %}

# More Info

{% post https://dev.to/mcsee/how-to-get-rid-of-annoying-ifs-forever-1jfg %}

{% post https://dev.to/mcsee/laziness-i-meta-programming-32a9 %}

# Credits

Photo by <a href="https://unsplash.com/@gieling">Remy Gieling</a> on <a href="https://unsplash.com/s/photos/assembly-line">Unsplash</a>

* * *

This article is part of the CodeSmell Series.

{% post https://dev.to/mcsee/how-to-find-the-stinky-parts-of-your-code-1dbc %}

*Last update: 2021/07/06*