Mohan Ram Blocked Desbloquear Seguir Seguindo 26 de dezembro de 2018 Foto de Alex Loup no Unsplash
Decoradores introduz programadores para escrever a anotação de metadados que o ajudará a examinar seu código. Melhor caso de uso que você encontrar para decoradores, serão as preocupações transversais – Programação Orientada a Aspectos.
Na computação, a programação orientada a aspectos ( AOP ) é um paradigma de programação que visa aumentar a modularidade, permitindo a separação de interesses transversais . Isso é feito adicionando comportamento adicional ao código existente (um conselho) sem modificar o próprio código.
Amostras de decoradores – uso do decorador de nível de classe e método
Acima do código – ilustra como os decoradores são declarativos. Vamos cobrir os decoradores em detalhes como abaixo
- O que é decorador? e sua finalidade, tipos
- Assinaturas dos decoradores
- Decorador de Método
- Decorador de propriedades
- Decorador de Parâmetros
- Decorador Accessor
- Decorador de Classes
- Generalize decoradores com Factory Decorator
- API de reflexão de metadados
- Conclusão
O que é decorador e sua finalidade, tipos
Um decorador é um tipo especial de declaração que pode ser anexado a uma declaração de classe, método, acessador, propriedade ou parâmetro.
Os decoradores usam o formato @expression
expression
, em que a expression
deve ser avaliada para uma função que será chamada em tempo de execução com informações sobre a declaração de decoração.
Ele serve ao propósito de adicionar metadados ao código existente de maneira declarativa.
Tipos de decoradores e sua prioridade de execução são
- Decorador de classes – Prioridade 4 (Instância de objeto, estática)
- Decorador de Método – Prioridade 2 (Instância de Objeto, Estática)
- Acessor ou Decorador de Propriedade – Prioridade 3 (Instância de Objeto, Estática)
- Parâmetro Decorador – Prioridade 1 (Instância do Objeto, Estático)
Nota – Se um decorador é aplicado para os parâmetros do construtor de classe, então a prioridade para esses será 1. parâmetro, 2. método, 3. acessador ou decorador de propriedade – então 4. Construtor de parâmetro de construtor será executado seguido por 5. decorador de classe.
Ordem de avaliação e execução do decorador
No código acima, vemos que um decorador f
e g
retorna uma outra função que é uma função decorador. f
e g
são chamados de fábricas de decoradores
As fábricas de decoradores ajudam o consumidor a passar os argumentos para que o decorador possa fazer uso.
A ordem de avaliação é de cima para baixo e a execução é de baixo para cima.
Assinaturas dos decoradores
Assinaturas dos decoradores
Decorador de Método
Da assinatura acima, a função de decorador de método espera três argumentos:
- target – protótipo do objeto atual ie – se Employee é um objeto,
Employee.prototype
- propertyKey – nome do método
- descritor – descritor de propriedade do método ie –
Object.getOwnPropertyDescriptor(Employee.prototype, propertyKey)
exemplo de decorador de método
o código acima deve ser auto-explicativo – Vamos ver como o código JavaScript compilado se parece
resultado compilado
Vamos começar a analisar a função Employee – os parâmetros de name
inicialização do construtor e o método de greet
anexado ao protótipo
__decorate([logMethod],Employee.prototype,”greet”)
Este é o método genérico gerado pelo TypeScript para lidar com a chamada de função do decorador com o respectivo argumento baseado no tipo de decorador.
Essa função ajuda a introspectar a chamada do método e preparar o caminho para o desenvolvedor lidar com as questões de corte transversal, como registro, memorização e aplicação de configurações, como enumeráveis, etc.
No exemplo – nós apenas imprimimos a função chamada com seu argumento + resposta.
Nota – leia os comentários detalhados no método
__decorate
para entender os internos
Decorador de propriedades
A função de decorador de propriedade espera dois argumentos:
- target – protótipo do objeto atual ie – se Employee é um objeto,
Employee.prototype
- propertyKey – nome da propriedade
exemplo de decorador de propriedade
No código acima, introspectamos a acessibilidade da propriedade no decorador e o código compilado como abaixo.
resultado compilado
Decorador de Parâmetros
A função de decorador de parâmetros espera três argumentos:
- target – protótipo do objeto atual ie – se Employee é um objeto,
Employee.prototype
- propertyKey – nome do método
- índice – posição do parâmetro no array de argumentos
exemplo de decorador de parâmetros
No código acima, coletamos todo o índice ou posição dos parâmetros decorados dos métodos como metadados e anexados ao protótipo do objeto. O código compilado está abaixo.
resultado compilado
Como vimos anteriormente, a função __decorate
, A função __param
, retorna um decorador que envolve o decorador de parâmetros.
Como podemos ver quando o decorador de parâmetros é chamado, seu retorno é ignorado. Isto significa que quando a função __decorate
é chamada, seu retorno não será usado para sobrescrever o parâmetro.
Esta é a razão pela qual os decoradores de parâmetros não retornam.
Decorador Accessor
Acessor não é nada, mas a parte getter e setter da propriedade na declaração de classe.
Um Decorador Accessor é declarado imediatamente antes de uma declaração de acessador. O decorador de acessador é aplicado ao Descritor de Propriedade para o acessador e pode ser usado para observar, modificar ou substituir as definições de um acessador.
exemplo de decorador de acessor
No código acima, nós definimos dois name
acessor e salary
uma vez que configuramos a parte de enumeração via decorator. Objeto age de acordo. Saída é o name
fará parte da enumeração e o salary
não é.
Nota: O TypeScript não permite a decoração do acessador
get
eset
para um único membro. Em vez disso, todos os decoradores do membro devem ser aplicados ao primeiro acessador especificado na ordem do documento. Isso ocorre porque os decoradores aplicam-se a um Descritor de propriedades , que combina o acessadorget
eset
, não cada declaração separadamente.
O código de compilação está abaixo
resultado compilado
Decorador de Classes
O decorador de classes é aplicado ao construtor da classe e pode ser usado para observar, modificar ou substituir uma definição de classe.
exemplo de decorador de classe
O decorador acima declara uma variável chamada original
e define seu valor para o construtor da classe que está sendo decorada.
Então, uma função de utilidade chamada construct
é declarada. Esta função nos permite criar instâncias de uma classe.
Em seguida, criamos uma variável chamada f
que será usada como o novo construtor. Essa função invoca o construtor original e também registra no console o nome da classe que está sendo instanciada. Aqui é onde vamos adicionar algum comportamento extra ao construtor original .
O protótipo do construtor original é copiado para o protótipo de f
para garantir que o operador instanceof
funcione como esperado quando criamos uma nova instância de um Employee.
Quando o novo construtor estiver pronto, precisamos apenas retorná-lo para concluir a implementação do decorador de classes.
Agora que o decorador está pronto, ele registrará no console o nome de uma classe toda vez que for instanciado
Código compilado é.
resultado compilado
Na versão compilada, notamos duas coisas diferentes,
- Se você ver os argumentos passados para __decorate seus dois – matriz de decoradores e a função de construtor
- O compilador TypeScript está usando o retorno de
__decorate
para substituir o construtor original.
Esta é a razão pela qual os decoradores de classes devem retornar uma função de construtor .
Generalize decoradores com Factory Decorator
Já que cada tipo de decorador tem sua própria assinatura para invocar. Podemos usar a fábrica decoradora para generalizar a invocação da chamada do decorador
decorador de log genérico usando fábrica decorador
API de reflexão de metadados
Para organizar os metadados de maneira padrão, a API de reflexão de metadados pode ser usada [ie – Reflect
– builtin object]
O reflexo do nome é usado para descrever o código que é capaz de inspecionar outro código no mesmo sistema (ou em si).
A reflexão é útil para vários casos de uso (Composição / Injeção de Dependência, Asserções de Tipo de Tempo de Execução, Teste).
amostras de APIs de reflexão de metadados [ a biblioteca reflect-metadata é usada para reflexão]
No exemplo acima, usamos a chave de design de metadados [ex: design:type
] . Por enquanto – existem apenas três disponíveis:
- Metadados de tipo usam o
design:type
chave de metadadosdesign:type
. - Metadados de tipo de parâmetro usam o
design:paramtypes
chave de metadadosdesign:paramtypes
. - Metadados de tipo de retorno usam o
design:returntype
chave de metadadosdesign:returntype
.
Com a ajuda da reflexão, poderíamos encontrar as seguintes coisas em tempo de execução.
- O nome da entidade.
- O tipo da entidade.
- Quais interfaces são implementadas pela entidade.
- O nome e os tipos das propriedades da entidade.
- O nome e os tipos dos argumentos do construtor da entidade.
Conclusão
- Decoradores são apenas funções que ajudam a examinar o código, anotar e modificar classes e propriedades em tempo de design.
- Decoradores são um padrão proposto para ECMAScript 2016 por Yehuda Katz.
- Podemos passar argumentos do usuário para o decorador através de fábricas de decoradores .
- Existem 4 tipos de decoradores. Eles são – Class, Method, Property ou Accessor, Parameter Decorators .
- A API de Reflexão de Metadados ajuda a adicionar as informações de metadados de maneira padrão a um objeto e ajuda a obter as informações de tipo de design no tempo de execução .
Você pode encontrar todas as amostras neste Repositório Git . Obrigado pela leitura!