< Insights

Padrões de Projeto em Swift — Strategy

  • Desenvolvimento de Software

Iniciando uma série de artigos sobre padrões de projeto (Design Patterns), hoje vamos falar especificamente do padrão Strategy. Além disso, vamos aplicar este padrão na linguagem Swift, que atualmente é utilizada para desenvolvimento iOS, mas que tem projeções futuras de uso como server side. Antes de mais nada, precisamos entender o que é um design pattern e como ele pode ser utilizado.

O QUE É UM PADRÃO DE PROJETO OU DESIGN PATTERN?  

Em linhas gerais, design pattern é uma abordagem arquitetural no desenvolvimento de software para que um problema que se repete possa ser resolvido dentro de um determinado padrão, ao invés de simplesmente copiarmos o código e colocá-lo em outro ponto onde este problema ocorre. A vantagem de utilizar design patterns está em ter um código limpo e mais enxuto, portanto menos propenso a produzir bugs. Não significa que eles não existirão, mas serão encontrados mais facilmente quando ocorrerem. Além disso, a tendência à padronização do desenvolvimento torna mais fácil a manutenção do código, seja por desenvolvedores que já estão há mais tempo no projeto, quanto por desenvolvedores recém-chegados.

No livro “Design Patterns: Elements of Reusable Object-Oriented Software”, os autores dividem os Design Patterns em três tipos diferentes: Creational (Criação), Structural (Estrutural) e Behavioural (Comportamental). No decorrer desta série de artigos, vamos passar por todos os padrões de projeto aplicados ao desenvolvimento em Swift. O padrão strategy, assunto deste artigo, é um padrão do grupo Behavioural.

O padrão Strategy tem como meta definir uma família de algoritmos, encapsular cada uma delas e torná-las intercambiáveis. O strategy permite que o algoritmo varie independentemente dos clientes que o utilizam. Esta variação é feita em tempo de execução.

Entendendo o problema

No desenvolvimento mobile, eventualmente nos deparamos com a necessidade de validar o conteúdo de um ou mais campos UITextField (se estão preenchidos ou não ou se possuem um número mínimo de caracteres). Imagine, então, que vamos implementar uma solução para esta validação:

exemplo de programação para solução para esta validação

Essa solução certamente funcionará se tivermos apenas estes três tipos de validações possíveis para um campo de texto. Se eventualmente precisarmos adicionar mais um tempo de validação (se o campo tem regra para senha, por exemplo), poderíamos apenas adicionar mais um tipo no enum e adicionar mais uma cláusula no switch. Mas e se nossa gama de validações aumentar, e chegarmos em um ponto em que temos 20, 30 validações diferentes? Temos aqui um cenário em que o padrão strategy se encaixa perfeitamente.

Para explicar como utilizar este padrão, vamos responder a três perguntas e usar o diagrama abaixo, extraído do livro Design Patterns by tutorials:

imagem do livro Design Patterns by tutorials:

Who (Quem): um objeto que está em conformidade com a validação que precisamos fazer. Em nosso exemplo, um objeto usando a Strategy para validar o campo.

What (O quê): um protocolo que define a ação que queremos encapsular. No caso, nossa ação será validar determinada regra de um campo.

How (Como): implementações específicas da estratégia. Teremos, então, três estratégias de validação de campos.

Neste mesmo exemplo, nossa implementação ficaria assim:

Por que usar strategy?

Este padrão é um dos mais simples de implementar, talvez um dos mais fáceis, e também segue algumas regras do SOLID, por exemplo.

  • Single Responsibility: quando criamos uma estratégia, cada classe fica responsável apenas por um tipo de ação;
  • Open/Closed Principle: se usarmos strategy, não precisamos modificar o comportamento do objeto original. Ao invés disso, criamos uma nova estratégia.

Mas quando identificar quando usar este padrão? Existem alguns indícios que podem ajudar nessa decisão:

  • Uso de if’s e switches com muitas validações ou possibilidades;
  • Ao identificarmos que é possível fazer uma mesma ação de várias formas;
  • Se você precisa, com frequência, estender alguma funcionalidade de uma classe para implementar um novo comportamento.
É preciso, no entanto, tomar cuidado com o uso desse padrão de projeto. Sempre que aprendemos um novo padrão, ficamos tentados a utilizá-lo o tempo todo. A melhor abordagem é analisar o problema e verificar se não existem outras soluções melhores para ele para que não se use uma arquitetura muito complexa para resolver um problema simples.
Nos próximos artigos, abordaremos outros design patterns, mostrando sua aplicação prática em Swift. Se achou este artigo útil, compartilhe e ajude outros desenvolvedores a entender um pouco mais sobre strategy!

Insights do nosso time

Obtenha insights do nosso time de especialistas sobre metodologias de desenvolvimento de software, linguagens, tecnologia e muito mais para apoiar o seu time na operação e estratégia de negócio.