Algumas coisas que podem te tornar um melhor dev Flutter!
Published: 2021-11-22 22:10:00

Decidi escrever isso aqui pra mostrar a minha opinião referente a alguns métodos que podem melhorar a vida dos Devs Flutter, geralmente são coisas que o pessoal esquece, mas bora lá ver isso!

###Widgets!

Você já deve ter ouvido falar, ou se já trabalha com Flutter sabe que ele tem um ecossistema todo envolto em Widgets, então tenho uma dica pra você: 

*Reduza seus elementos das telas para a menor quantidade de Widgets possível!*

Deixe-me explicar. Os dois cenários comuns que gostaríamos de evitar são os seguintes:
1. Uma classe de widget enorme com um método de construção enorme (também conhecido como o pior caso imaginável).

2. Uma enorme classe de widget com muitos métodos de construção (melhor do que a opção anterior, mas ainda não é ideal).

####As razões pelas quais esses casos causam problemas durante o desenvolvimento são:

- Classes longas significam uma maior sobrecarga cognitiva ao trabalhar nelas, o que significa que os desenvolvedores se cansam mais rapidamente e a possibilidade de erro ao tentar modificar o código é maior.
- Geralmente, a criação de mais widgets está associada ao conceito de aumentar a capacidade de reutilização de seu código. Dessa forma, você pode facilmente alterar um aspecto comum de seu aplicativo simplesmente modificando um widget em vez de precisar alterar centenas de métodos cada um em classes separadas.

Se você é um programador iniciante, esteja ciente de que widgets genéricos e abstratos serão cruciais ao tentar dividir seus elementos de UI em classes de widget reutilizáveis.

###Condicionais IF

Outra pequena otimização diz respeito às instruções if em seu código. Você sabia que pode usá-los em seus métodos de construção, colocando-os diretamente em seus children?

```
Column(
   children: [
     _buildCancelButton(),
     _buildTitle(),
     if (dataCorrect) _buildSubmitButton(),
   ],
)
```

Isso prova ser uma forma limpa e inteligente de código para construir condicionalmente a lógica da interface do usuário. Você também pode combiná-lo com o Spread Operator para anexar condicionalmente listas de widgets a uma lista especificada. Aqui está um exemplo:

```
Column(
   children: [
     _buildTitle(),
     if (showButtons) ..._buildButtons(),
   ],
)
 
List<Widget> _buildButtons() {
   // ...
}
```

###Erros!!!!

Ao desenvolver seu aplicativo, você às vezes encontrará problemas. Nesse caso, você deve lançar um erro como UnimplementedError no caso de um recurso ainda não ter sido implementado ou um UnsupportedError se a operação fornecida for inválida.
Além disso, você deve fornecer uma explicação para o erro fornecido no construtor. Aqui está um exemplo de lançamento de um erro em uma instrução switch usada para mapear uma string para um enum:

```
switch (status) {
  case 'AVAILABLE':
    return PromotionStatus.available;
  case 'ACTIVE':
    return PromotionStatus.active;
  case 'EXPIRED':
    return PromotionStatus.expired;
  default:
    throw UnsupportedError('Promotion status $status is not supported!');
}
```

###Construtores Const

Você deve usar construtores const sempre que possível. Mas Porque? Para simplificar, ajuda a aumentar o desempenho do Flutter ao dizer quais elementos não mudarão, o que significa que o Flutter não precisa reconstruí-los.
Aqui está um exemplo fácil para ilustrar o procedimento. Digamos que queremos construir um ícone que não muda e tem uma margem superior de 20 que também é estática. Nós definiríamos o método para construir o widget assim:

```
Widget _buildIcon() {
   return Container(
     margin: const EdgeInsets.only(top: 20),
     child: const Icon(Icons.home),
   );
}
```

Você não quer saber quando adicionar a palavra-chave const? Você tem sorte porque não precisa! Basta olhar para a próxima dica!

###Usando o Lint!

Outra ferramenta útil é usar o pacote lint para o seu projeto. Se você não está familiarizado com o lint, é apenas uma ferramenta automática que analisa o código-fonte para sinalizar erros comuns de programação, bugs ou erros estilísticos. Para incluí-lo em nosso projeto flutter, começamos adicionando dois pacotes ao nosso arquivo pubspec.yaml:

- [Linter](https://pub.dev/packages/linter)
- [Lint](https://pub.dev/packages/lint)

E então, criamos um arquivo *analysys_options.yaml* no mesmo nível da lib, com isso podemos customizar as regras para o nosso código!

```
include: package:lint/analysis_options.yaml
 
analyzer:
 exclude:
   - "lib/presentation/localization/**"
 errors:
   missing_required_param: error
```

Podemos excluir certos diretórios da análise como, por exemplo, nossos diretórios de arquivos de localização gerados. Aqui, também podemos afirmar que queremos que nossos parâmetros obrigatórios ausentes sejam relatados como erro, impedindo-nos de executar o código.


###Required e Assert

Vamos começar com um exemplo de construtor para uma classe Product que ilustrará o que você deve evitar ao definir construtores e métodos:

```
const Product(
   this.id,
   this.name,
   this.description,
   this.category,
);
```

Em primeiro lugar, se você tiver vários parâmetros em seus métodos ou construtores e alguns deles podem ser opcionais, você deve usar principalmente parâmetros nomeados em vez de posicionais. Dessa forma, o código fica mais legível e é mais fácil detectar um erro ao fazer uma revisão do código.
Além disso, você deve sempre anotar corretamente seus parâmetros usando a palavra-chave *@required* se eles não puderem ser omitidos. Então... vamos fazer isso. Aqui está o efeito:

```
const Product({
   @required this.id,
   @required this.name,
   this.description,
   this.category,
});
```

Se você usar essas regras de lint que compartilhei com você, o compilador irá notificá-lo com um erro se você esquecer de especificar um parâmetro obrigatório, o que é muito útil.
Uma asserção é outro elemento que podemos usar para melhorar este código. Ao especificar que nossos parâmetros obrigatórios não podem ter o valor nulo, seremos notificados com mais rapidez sobre um possível bug no aplicativo.

```
const Product({
   @required this.id,
   @required this.name,
   this.description,
   this.category,
}): assert(id != null),
    assert(name != null);
```

###Conclusão!

Espero que você tenha encontrado pelo menos uma das coisas que compartilhamos como valiosa. Algumas das dicas podem parecer mesquinhas, mas, na realidade, o conjunto de habilidades de um desenvolvedor é uma combinação de diferentes pequenos detalhes que se juntam para formar seu nível de competência geral.