Funções mais legíveis em Javascript com options object
Tags: javascript, cleancode, programming
Published: 2021-09-19 22:22:24

Escrever funções legíveis, fáceis de entender, reutilizáveis e simples de se usar é uma ótima prática em qualquer linguagem de programação. Em Javascript  uma das estratégias pra se fazer isso é usar o  design pattern objeto de opções ou options object. 

Usando options object, funções tem como parâmetro apenas um objeto que possui todos os argumentos, isso traz algumas vantagens sobre o modo padrão e mais comumente usado, os parâmetros tem os nomes mais visíveis para outras pessoas lendo o código, facilita o uso de argumentos padrão e a função fica mais resiliente à mudanças.

## Usando options object na prática

Como exemplo, vamos declarar uma função de criação de um usuário. Ela não precisa receber a data de nascimento ou CPF e tem por padrão o envio de materiais de marketing como verdadeiro.

```jsx
function addUser(
	name, 
	email, 
	password,
	birth_date = null, 
	username, 
	cpf = null, 
	receive_marketing = true
) { ... }
```

Ao chamar essa função, alguns problemas são muito aparentes, os primeiros argumentos são fáceis de se identificar, porém, passar `undefined` como argumento é péssimo para a legibilidade, incoveniente, além de abrir uma porta para comportamentos inesperados e o `false` não diz muito sobre seu significado sem documentação, ou uma análise da declaração da função, qualquer pessoa lendo isso pela primeira vez vai ter dificuldade de entender o que cada parâmetro é

```jsx
addUser(
	'Jolyne Kujo', 
	'jolyne@example.com', 
	'0930ce1c372fda803f16af5553096fda744f19ca',
	undefined,
	'jojolyne',
	undefined,
	false
)
```

Redeclarando essa função usando um option object, conseguimos resolver esses problemas

```jsx
function addUser({
	name, 
	email, 
	password, 
	birth_date = null, 
	username, 
	cpf = null, 
	receive_marketing = true
}) { ... }
```

Agora, quando esperamos usar os argumentos padrão, não é necessário colocar `undefined` em nenhuma posição, o booleano sobre recebimento de marketing é claro sem necessidade de mais nenhuma informação e caso seja necessário adicionar mais parâmetros, não há preocupação em precisar alterar todas as outras chamadas para ela (por esse mesmo motivo, alterações devem ser feitas com precaução)

```jsx
addUser({
	username: 'jojolyne',
	name: 'Jolyne Kujo', 
	email: 'jolyne@example.com', 
	password: '0930ce1c372fda803f16af5553096fda744f19ca',
	receive_marketing: false
})
```

Como um exemplo do mundo real, a biblioteca axios utiliza esse design pattern extensivamente, uma implementação que mostra o tamanho do impacto de uma mudança simples 

```jsx
// Send a POST request
axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});
```

## Onde não usar

Assim como qualquer outro design pattern, options object não é uma bala de prata e apesar de ser muito útil, deve ser usado com precaução e onde sua aplicação faz sentido, funções que tem um nome expressivo e recebem apenas um argumento, sem expectativa de mudança são um exemplo onde esse pattern mais atrapalha que ajuda.  

Nessa função é muito claro que o único argumento passado deve ser o `id` de um usuário, usar um options object apenas deixaria ela mais verbosa

```jsx
function getUserById(id) { ... }
```

## Conclusão

Escrever boas funções é um grande desafio, e conhecer novas ferramentas pra isso é sempre útil espero ter te ajudado com um novo conhecimento, Aproveito para recomendar mais textos em meu blog, como este sobre funções de ordem superior em Javascript. [Vale a pena conferir!](https://dev.to/tashima42/o-que-sao-funcoes-de-ordem-superior-em-javascript-27ac)

## Referências

[https://www.freecodecamp.org/news/elegant-patterns-in-modern-javascript-roro-be01e7669cbd/](https://www.freecodecamp.org/news/elegant-patterns-in-modern-javascript-roro-be01e7669cbd/)

[https://www.codereadability.querycom/what-are-javascript-options-objects/#:~:text=An options object is a,all of which are optional](https://www.codereadability.com/what-are-javascript-options-objects/#:~:text=An%20options%20object%20is%20a,all%20of%20which%20are%20optional).

[https://www.tinyblog.dev/blog/2020-07-13-javascript-roro-pattern/](https://www.tinyblog.dev/blog/2020-07-13-javascript-roro-pattern/)

[https://github.com/axios/axios#axios-api](https://github.com/axios/axios#axios-api)