Blog

Como Aplicar o Design Pattern Strategy Com Typescript

A imagem mostra um desenvolvedor codificando um sistema com Design Patter Strategy com Typescript
Desenvolvimento / Desenvolvimento de Software / Front-End / Programação

Como Aplicar o Design Pattern Strategy Com Typescript

No artigo de hoje, vamos saber como aplicar o Design Pattern Strategy com Typescript em sua aplicação.

Com o crescimento do número de aplicações desenvolvidas, alguns desafios foram detectados de forma recorrente e as suas soluções eram semelhantes. Dessa forma, foram criados os Design Patterns, padrões e modelos de código que são capazes de resolver os problemas que aparecem de forma rotineira no desenvolvimento de sistemas. Um desses modelos de projeto é o Strategy.

O que é o Strategy e para que serve?

O Strategy é um Design Pattern listado pela GoF (Gang of Four) do tipo comportamental. Ou seja, ele descreve como classes e objetos dividem as responsabilidades entre si. Além disso, ele consegue mudar o comportamento de um objeto de forma indireta através de outros objetos.

Com essas responsabilidades separadas, o Strategy consegue lidar de formas diferentes os dados que são recebidos por ele. Portanto, nesse padrão de projeto, é possível solucionar casos que é necessário a criação de uma família de algoritmos, dividir esses algoritmos em classes separadas e trocar os objetos dessas classes em tempo de execução, quando for necessário.

Exemplos de situações que uma empresa pode usar o Strategy para facilitar a implementação de uma tarefa:

  • Calcular o custo do frete de diferentes serviços de empresas;
  • Uso de diferentes serviços, como provedor de e-mails, serviços de nuvem e armazenamentos de dados;
  • Cálculo do tempo de um trajeto com diferentes meios de locomoção.

Componentes do Strategy

O padrão do Strategy é ter 3 componentes principais:

  1. A interface Strategy é responsável por estabelecer um tipo de contrato que contém a funcionalidade que o desenvolvedor quer abstrair do seu código. Logo, todas as classes que derivam dela devem implementar essa funcionalidade.
  2. O ConcretStrategy é a classe concreta que irá implementar a interface Strategy. Nesta classe, o desenvolvedor irá construir a regra de negócio que precisa para lidar com os dados que foram recebidos.
  3. A classe Context tem como responsabilidade armazenar uma instância do tipo Strategy, chamar a função abstrata da interface e conseguir trocar objetos do tipo Strategy, se requisitado. Dessa forma, o Context não fica limitado apenas a um tipo de implementação.

Exemplo de um diagrama implementado o Strategy:

A interface Strategy define o que as classes que a implementarem devem possuir um método chamado algorithm. As classes do ConcretStrategy implementam a interface e possuem suas próprias regras de negócio para o método algorithm.

Por fim, na classe de Context, existe o método operation, que é responsável por chamar o método algorithm do objeto Strategy.

Utilizando o Typescript

O Typescript é uma linguagem baseada no Javascript que possui um superconjunto de funcionalidades adicionais. Com esses novos recursos, é possível utilizar variáveis com uma tipagem estática opcional, os conceitos da orientação a objetos e outras coisas.

Implementação Abstrata do Design Pattern Strategy com Typescript

Abaixo temos um exemplo genérico aplicando os conceitos do strategy.

Interface Strategy

Como aplicar o Design Pattern Strategy com Typescript - Passo 2

Classes concretas que implementam a interface

Como aplicar o Design Pattern Strategy com Typescript - Passo 3

Como aplicar o Design Pattern Strategy com Typescript - Passo 4

Definindo o Context

Como aplicar o Design Pattern Strategy com Typescript - Passo 5

Utilizando o contexto para poder usar os diferentes casos de usos

Como aplicar o Design Pattern Strategy com Typescript - Passo 6

Como aplicar o Design Pattern Strategy com Typescript - Passo 7

Implementação Real do Design Pattern Strategy Com Typescript

Criamos um exemplo mais concreto que pode ser utilizado no mundo real. Utilizando os conceitos vistos anteriormente, fizemos um projeto simples para enviar e-mails que é capaz de usar diferentes implementações.

Para a interface Strategy, temos a interface IMailSender, responsável por definir o método que as classes concretas devem implementar e o IMessageProps para definir o que a mensagem deve possuir:

Como aplicar o Design Pattern Strategy com Typescript - Passo 8

Classes concretas que implementam o IMailSender, neste exemplo, temos o MailTrapMailSenderImplementaion, que é responsável por criar a regra de negócio necessária para ser capaz de enviar e-mails para mailtrap. Ademais, para termos outra implementação, criamos a classe FakeMailSenderImplementaion, que também implementa o IMailSender, mas apenas mostra a mensagem no console:

Como aplicar o Design Pattern Strategy com Typescript - Passo 9

Como aplicar o Design Pattern Strategy com Typescript - Passo 10

Como aplicar o Design Pattern Strategy com Typescript - Passo 11

Por último, temos a classe de contexto chamada MailSender. Nela temos uma referência do tipo IMailSender mailProvider, um método que chama a função sendEmail do mailProvider e outro método que é capaz de trocar a referência do mailProvider, se necessário.

Como aplicar o Design Pattern Strategy com Typescript - Passo 12

Como aplicar o Design Pattern Strategy com Typescript - Passo 13

Para executar esse exemplo, temos também um index.ts.

Dessa forma, conseguimos fazer um sistema, utilizando o Typescript, que não dependa exclusivamente de uma implementação para o envio de e-mails. Se quisermos adicionar um outro serviço de e-mails, apenas seria necessário criar uma nova classe, criar a implementação com o IMailSender e construir a regra de negócio no método sendEmail.

Relação do SOLID com o Strategy

Seguindo os conceitos utilizado no Strategy, é possível notar que os princípios do SOLID são respeitados:

  • Single Responsibility Principle – princípio da responsabilidade única: cada classe possui uma única função clara e objetiva;
  • Open Closed Principle – princípio do aberto-fechado: a classe de contexto não é alterada caso uma nova funcionalidade seja necessária, mas uma nova implementação pode ser feita seguindo os padrões da interface Strategy;
  • Liskov Substitution Principle – princípio da substituição de Liskov: o objeto Strategy da classe de contexto é capaz de trocar entre diferentes implementações da interface Strategy;
  • Interface Segregation Principle – princípio da segregação de interface: a interface Strategy tem uma responsabilidade bem definida e não implementa métodos desnecessários;
  • Dependency Inversion Principle – princípio da inversão de dependência: a classe de contexto recebe uma propriedade abstrata pelo seu construtor e não uma implementação concreta da interface Strategy.

Design Pattern Strategy com Typescript vai facilitar suas aplicações!

Com isso, vimos o que é o Design Pattern Strategy, como ele pode ajudar a resolver alguns desafios na construção de um sistema, em que casos ele pode ser útil, seus principais componentes e como aplicar o Design Pattern Strategy com Typescript. Além disso, vimos uma implementação usando o Typescript para o caso de envio de e-mails e como o Strategy consegue seguir todos os princípios do SOLID.

Link do repositório com os exemplos: https://github.com/albertojcvs/Strategy-Example

Veja também:

Construção de Formik Field Array com React js

Comments (2)

  1. […] necessidade para quem é, principalmente, desenvolvedor front-end, pois gera trechos de JavaScript, TypeScript, Vue, React e […]

    25 de maio de 2022 at 11:37
  2. […] o Typescript é um superset criado para a linguagem JavaScript pela Microsoft. Com o Typescript, podemos […]

    26 de maio de 2022 at 16:31

Comments are closed.

Select the fields to be shown. Others will be hidden. Drag and drop to rearrange the order.
  • Image
  • SKU
  • Rating
  • Price
  • Stock
  • Availability
  • Add to cart
  • Description
  • Content
  • Weight
  • Dimensions
  • Additional information
  • Attributes
  • Custom attributes
  • Custom fields
Click outside to hide the comparison bar
Compare