Swift Protocols — Associated types

Pedro Cacique
Apple Developer Academy | Mackenzie
3 min readJun 5, 2019
Crédito: Joey Nicotra

Protocolos

Em Swift, protocolos são como contratos, em que classes ou estruturas se comprometem a apresentar alguns atributos e implementar alguns métodos. É uma forma interessante de garantir que, mesmo que sejam de tipos diferentes, as instâncias criadas sempre terão características semelhantes.

Para entendermos melhor os protocolos em Swift, vamos fazer um exemplo claro, com um assunto bastante comum: Super Heróis!

O que é preciso para ser um super herói? Neste nosso exemplo, vamos pensar em alguns atributos bem básicos. Primeiro: ele precisa ter um nome forte, marcante (mesmo que seja ridículo como "Lanterna Verde"). Segundo: ele pode ter uma série de super poderes.

Para garantir que qualquer estrutura ou classe tenha no mínimo estas duas características, podemos criar um protocolo mais ou menos assim:

Veja que, ao criar um protocolo, precisamos determinar: quais os atributos, seus tipos e formas de acesso.

Uma estrutura que poderia representar um Heroi da DC, por exemplo, seria algo assim:

Neste caso, a estrutura implementa exatamente o mínimo estipulado pelo protocolo. Um herói da DC, então, poderia ser criado assim:

Veja que temos uma variável que atende os requisitos do protocolo Heroi, pois é uma instância da estrutura do tipo HeroiDC.

Muito bom!

Agora, se a Marvel quer usar o mesmo protocolo, mas além do mínimo, ela quer dizer se um de seus heróis é ou não uma divindade, poderíamos criar a seguinte estrutura:

Veja que o básico (nome e poderes) é garantido pelo protocolo, e ainda acrescentamos o atributo sobre a divindade. O Thor, por exemplo, seria representado mais ou menos assim:

A grande vantagem deste protocolo aqui seria a possibilidade de ter uma lista com todos os heróis, independente do seu universo. Mais ou menos assim:

Isso nos permite realizar operações básicas entre eles, como comparar os seus poderes, por exemplo (obviamente a Marvel ganharia, não é mesmo?)

Associated types

Bom, agora que relembramos o conceito de protocolos, vamos ao que interessa: tipos associados!

Os protocolos nos trazem a grande vantagem de podermos trabalhar com tipos diferentes que possuem atributos e funções semelhantes. Mas digamos que nós queremos ainda padronizar as características dos times de heróis.

Como criaríamos um protocolo em que temos personagens de diferentes universos? Poderíamos criar um protocolo que tem outro tipo associado a ele. Não faria sentido termos uma definição de time, se não tivermos a definição de herói. Assim, o protocolo Time é dependente (associado) do protocolo Herói. Veja:

O Time tem, então, nome, lista de heróis e uma função básica para adicionar novos heróis ao time. Como imaginamos que a função de adicionar é comum para os times (apenas acrescenta à lista), criamos uma extensão simples aqui para implementar a função de uma vez.

Uma liga da DC teria, além do nome e a lista de heróis, a identificação de qual das terras paralelas este time faz parte. Então, poderíamos definir sua estrutura como:

A instância da liga da justiça seria assim:

De forma análoga é possível criar os times da Marvel, como os Avengers por exemplo. Fica aqui uma sugestão de atividade: crie um playground para testar este código e acrescente os Avengers para teste.

Perceberam a vantagem de se usar um tipo associado? Não? Veja bem: se você resolver criar um universo novo para os quadrinhos, você pode simplesmente usar o protocolo Heroi, assim, estará dentro dos padrões estabelecidos pela indústria. E se você quiser criar um time de heróis, basta usar o protocolo Time.

E se a indústria mudar os requisitos para um herói (ou seja, mudar os atributos e métodos do protocolo Heroi)? Todos os que assinaram o protocolo terão que mudar as suas implementações para se adequarem.

E se quisermos fazer um crossover? Precisamos criar um novo universo? Não, podemos simplesmente criar um novo time, uma vez que ele aceita um Heroi como tipo associado. Poderíamos ter todas as características dos heróis da DC, da Marvel e do seu novo universo, juntas na mesma liga. Tipos associados!

--

--