Está na hora de parar de usar Switch em JavaScript

O método Switch está implementando em muitas linguagens de programação. Mas se você alguma vez já precisou de fato utiliza-lo para resolver algum problema com certeza viu que não é fácil debugar, testar e até mesmo manter o código.

Uma solução fácil para resolver esse problema é utilizar os objetos literais do JavaScript para criar uma estrutura mais simples, organizada e testável. Se você está habituado com JavaScript, sabe como seus objetos são flexíveis e fáceis de manipular. Com um pouco de criatividade, podemos realizar quase tudo com eles.

Nos exemplos que veremos, vamos supor que precisamos saber o nome de algum carro com base no seu tipo. O código abaixo ilustra essa lógica utilizando o Switch.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Versão com Switch
var getCar = function(type) {
  var carType = type,
      prefix  = 'NOME DO CARRO: ',
      name;

  switch(carType) {
    case 'SUV':
      name = prefix + 'Nissan Kicks';
      break;
    case 'Hatch':
      name = prefix + 'Fiat Punto';
      break;
    case 'Cupê':
      name = prefix + 'Hyundai Veloster';
      break;
    default:
      name = 'Nenhum carro desse tipo cadastrado.';
  }

  return name;
};
getCar('SUV');

Se você não está habituado a utilizar o Switch, o trecho acima representa exatamente o que o código abaixo ilustra (anti-padrão):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Anti padrão
var getCar = function(type) {
  var carType = type,
      prefix  = 'NOME DO CARRO: ',
      name;

  if (carType === 'SUV') {
    name = prefix + 'Nissan Kicks';
  }
  else if (carType === 'Hatch') {
    name = prefix + 'Fiat Punto';
  }
  else if (carType === 'Cupê') {
    name = prefix + 'Hyundai Veloster';
  }
  else {
    name = 'Nenhum carro desse tipo cadastrado.';
  }

  return name;
};
getCar('SUV');

O código possui uma lógica bem simples, mas imagine se a lista de cases fosse muito maior, seria um pesadelo para ler, debugar, testar ou realizar qualquer manutenção simples. Qualquer lista com mais de 10 cases não está longe da realidade dos problemas do mundo real.

Agora vemos reescrever a lógica que vimos no exemplo anterior utilizando um objeto literal. Veja abaixo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Versão com Objeto
var getCar = function(type) {
  var carType = type,
      prefix  = 'NOME DO CARRO: ',
      name;

  var cases = {
    'SUV'      : 'Nissan Kicks'  ,
    'Hatch'    : 'Fiat Punto' ,
    'Cupê'     : 'Hyundai Veloster',
    'Default'  : 'Nenhum carro desse tipo cadastrado.'
  };

  return prefix + ( cases[carType] || cases['Default'] );
};
getCar('SUV');

Agora temos muito mais controle sobre o que está acontecendo. Além da redução notável de caracteres, podemos observar que o código se apresenta de uma maneira muito mais fácil de ler e entender. Mesmo que a lista de tipos cresça exponencialmente, o código ainda continuará organizado, bem estruturado – e a manutenção será muito menos custosa.

O mais interessante é que, novamente, podemos melhorar o código acima e reduzir ainda mais o número de caracteres sem deixar nosso código confuso e mal estruturado. Veja abaixo.

1
2
3
4
5
6
7
8
9
10
// Versão reduzida
var getCar = function(carType) {
  return 'NOME DO CARRO: ' + {
    'SUV'       : 'Nissan Kicks'  ,
    'Hatch'     : 'Fiat Punto' ,
    'Cupê'      : 'Hyundai Veloster',
    'Default'   : 'Nenhum carro desse tipo cadastrado.'
  }[carType ? carType : 'Default'];
};
getCar('SUV');

Mesmo reduzindo o número de linhas de código consideravelmente, podemos notar que não perdemos a legibilidade e estrutura do código e não precisamos mais nos preocupar com o break ao final de todos os cases.

Existe também uma maneira bem simples de fazer com que nosso objeto literal retorne o mesmo resultado para múltiplos cases, como podemos fazer com Switch, o que é chamado de “fall through”.

Para esse exemplo vamos supor que conhecemos o nome do carro e, ao chamar a função, ela deve responder qual é o tipo. Veja como isso pode ser feito com Switch.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// versão Switch fall through
var getCarType = function(name) {
  var carName  = name,
      prefix   = 'TIPO DO CARRO: ',
      type;

  switch(carName) {
    case 'Nissan Kicks':
    case 'BMW X1':
      type = prefix + 'SUV';
      break;
    case 'Fiat Punto':
    case 'Volkswagen Gol':
      type = prefix + 'Hatch';
      break;
    default:
      type = 'Carro não cadastrado.';
  }

  return type;
};
getCarType('Nissan Kicks');

Agora, a mesma lógica utilizando um objeto literal.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Versão Objeto fall through
function getCarType (name) {
  var carName = name,
      prefix  = 'TIPO DO CARRO: ';

  function isSUV () {
    return prefix + 'SUV';
  }

  function isHatch () {
    return prefix + 'Hatch';
  }

  var cases = {
    'Nissan Kicks'    : isSUV,
    'BMW X1'          : isSUV,

    'Fiat Punto'      : isHatch,
    'Volkswagen Gol'  : isHatch,
  };

  return cases[carName]();
}
getCarType('Nissan Kicks');

Conclusão

Ao compararmos os Objetos literais com as declarações ultrapassadas do método Switch, é fácil perceber as vantagens dos Objetos literais. O código fica muito mais previsível, estruturado, de fácil manutenção, testabilidade e entendimento. Mesmo que a aplicação cresça ele sempre irá se manter “igual”.

Se você tem algo interessante para compartilhar, alguma experiência, dica ou dúvida sobre o tema poste ai nos comentários!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>