- Publicar em
Decorators
- Autor
- Nome
- Kevin Diego
Observações importantes
Este artigo visa orientar iniciantes como eu a entender alguns conceitos de linguagem de programação usando typescript, no caso o tema abordado sera em como criar Decorators.
Indicações
Introdução
Decorators são uma funcionalidade em linguagens de programação, como Python e TypeScript, que permitem adicionar comportamentos ou funcionalidades extras a funções, métodos, classes ou propriedades de forma declarativa. Eles são usados para modificar o comportamento padrão de elementos do código sem a necessidade de alterar seu código-fonte subjacente. Decorators podem ser usados para adicionar metadados, realizar ações pré/pós-função, extender funcionalidades e muito mais. Eles são amplamente utilizados para criar código modular e reutilizável, especialmente em contextos como frameworks e bibliotecas.
Configuração inicial
Para ativar o suporte experimental para decoradores, você deve ativar a experimentalDecorators opção do compilador na linha de comando ou em tsconfig.json
Para linha de comando
--target ES5 --experimentalDecorators
tsconfig.json
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
O que é um Decorator?
Decorators são funções especiais que podem ser anexadas a classes, métodos, propriedades ou parâmetros no momento da declaração. Eles frequentemente começam com o caractere reservado @
e possuem um método de uso específico. Decorators podem ser aninhados ou usados de forma independente. Eles permitem adicionar funcionalidades extras ou modificar o comportamento do código de forma declarativa.
São uma ferramenta poderosa para simplificar e aprimorar o código, permitindo criar nossos próprios decorators ou usar os disponíveis na linguagem. Neste contexto, vou mostrar como criar um exemplo de decorator personalizado para melhorar a clareza e elegância do código.
Exemplo de Decorator
Para este caso iremos criar um decorator que seja capaz de verificar o tempo de execução de uma determinada função para que saibamos se aquele processo pode ser melhorado sua performace ou não.
export function logarTempoDeExecucao() {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
return descriptor
}
}
target -> Função construtora da classe no caso de que se o decorator esteja em uma classe estática, mas caso não ele retorna o prototype daquela classe.
propertyKey -> Retorna o nome do método como string que foi decorado.
descriptor -> Responsável por modificar tudo do método original.
Esta estrutura é a base para praticamente todos os decorators, o que falta agora é somente modificar o descriptor para que o comportamento seja alterado conforme desejar.
Modificando o descriptor
/**
* Função decorator capaz de retornar o tempo de execução
* em segundos ou em milisegundos
*/
export function logarTempoDeExecucao(emSegundos: boolean = false) {
return function (
target: any,
propertyKey: string,
descriptor: PropertyDescriptor
) {
const metodoOriginal = descriptor.value //Sobrescreve o método original
descriptor.value = function (...args: any[]) /**
* Como não sabemos quantos parametros terão,
* podemos usar uma desestrutução nos argumentos
* para aceitas quantos valores for possivel
* ...args
* */
{
let divisor = 1
let unidade = 'milisegundos'
if (emSegundos) {
divisor = 1000
unidade = 'segundos'
}
const t1 = performance.now()
//Passando o contexto do método original
const retorno = metodoOriginal.apply(this, args)
const t2 = performance.now()
/**
* Atraves do elemento propertyKey criamos uma especie de envelope,
* cercando a função que será decorada para que
*/
console.log(`${propertyKey},
tempo de execução: ${(t2 - t1) / divisor} ${unidade}`)
retorno
}
return descriptor
}
}
Usando o Decorator
Aqui está como você pode usar o decorator logarTempoDeExecucao
em um método:
class ExemploUsoDecorator {
@logarTempoDeExecucao()
// Usando o decorator personalizado
metodoComDemora() {
// Simulando uma operação demorada
for (let i = 0; i < 1000000000; i++) {}
}
}
metodoComDemora, tempo de execução: 1001.2299999975479 milisegundos
Decorator permite o uso do parametro da mesma maneira que as funções basicas, caso tenha voce pode simplemente chama-lo dentro como argumento.
@logarTempoDeExecucao(true)
// Usando o decorator personalizado com argumento de segundos
metodoComDemoraEmSegundos() {
// Simulando uma operação demorada
for (let i = 0; i < 1000000000; i++) {}
}
}
const exemploComSegundos = new ExemploUsoDecorator();
exemploComSegundos.metodoComDemoraEmSegundos(); // Tempo de execução em segundos
Considerações Finais
Decorators são uma ferramenta poderosa para aprimorar a clareza e modularidade do seu código TypeScript. Eles permitem que você adicione funcionalidades adicionais de maneira declarativa, melhorando a reusabilidade do código e facilitando a manutenção.
Espero que este guia tenha ajudado você a entender melhor como criar e usar decorators em TypeScript. Se você quiser se aprofundar mais, as indicações e recursos fornecidos podem ser muito úteis.