Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
July 11, 2022 04:06 am GMT

Padro de projeto - Iterator

O Iterator um padro de projeto comportamental que permite percorrer em elementos de uma coleo sem precisar saber como isso est acontecendo debaixo dos panos, independente de ser lista, pilha, rvore, etc.

Estrutura de dados

Dentre as estruturas citadas acima, vamos utilizar uma rvore como exemplo:

rvores com setas indicando o tipo de acesso, em profundidade e em largura

Como podemos ver na imagem acima, a rvore pode ser acessada de diferentes maneiras, de acordo com o solicitado pelo cliente, podendo ter acesso em profundidade ou em largura, alm da possibilidade de implementao de outros tipos de acesso aos elementos.

O Iterator um padro que extrai essas diferentes formas de percorrer uma rvore para um objeto chamado itervel, segue a imagem:

Arvores e UML contendo os mtodos de busca em profundidade e em largura

Exemplo simples:
Implementar um mecanismo de busca, onde o cliente vai utilizar o mtodo getBusca() sem saber com qual algoritmo o mtodo foi desenvolvido - Bubble Sort, Merge Sort, Quick Sort...

Quando usar?

Esse padro pode ser utilizado quando a complexidade da estrutura de dados no interessante para o cliente. O acesso aos elementos fornecido atravs de mtodos simples, encapsulando os detalhes do algoritmo, trazendo mais proteo s colees, as quais no sero manipuladas diretamente.

Outra vantagem de definir a responsabilidade de percorrer a estrutura de dados para o iterador, tirando ela de dentro da regra de negcio, se d no tempo que os algoritmos no triviais levam para buscar um elemento. Tambm pelo fato de que o objeto iterador tem seu prprio estado de iterao, sendo possvel mais de um objeto percorrer a mesma coleo em paralelo. Assim o cdigo do cliente se torna mais limpo e focado em seus objetivos.

Iterator no Python

O python possui um mdulo Iterator e Iterable, para criar os iteradores e os objetos iterveis.

from collections.abc import Iterator, Iterable

Este mdulo implementa os mtodos __iter()__ e __next()__, os quais so necessrios para um objeto ser itervel no Python.

import randomclass RandomIterable:def __iter__(self):    return selfdef __next__(self):    if random.choice(["go", "go", "stop"]) == "stop":        raise StopIteration        # Sinaliza o fim da iterao    return 1

Criando o iterator.py

Em um arquivo chamado iterator.py, criamos a classe InsertOrder, a qual vai definir a ordem que os elementos de uma coleo sero percorridos - implementamos a funo __next()__ aqui.

class InsertOrder(Iterator):_position: int = None_reverse: bool = Falsedef __init__(self, collection: Iterable,            reverse: bool = False) -> None:    self._collection = collection    self._reverse = reverse    self._position = -1 if reverse else 0def __next__(self):    try:        value = self._collection[self._position]        self._position += -1 if self._reverse else 1    except IndexError:        raise StopIteration()    return value
  • classe InsertOrder: possui atributos de posio do elemento e indicao se a coleo deve ser iterada na ordem normal ou reversa
  • funo __init__: construtor da classe
  • funo __next__: itera o objeto at no ter mais posies de ndices, caindo na except, onde finaliza a iterao, aqui tambm verificamos se a busca vai ser normal ou reversa

No mesmo arquivo, criamos a classe WordsCollection, essa definir um objeto iteravel, onde ser implementada a segunda funo necessria do Iterator, a __iter()__.

class WordsCollection(Iterable):    def __init__(self, collection: list = []) -> None:        self._collection = collection    def __iter__(self) -> InsertOrder:        return InsertOrder(self._collection)    def get_reverse(self) -> InsertOrder:        return InsertOrder(self._collection, True)    def outras_formas(self) -> InsertOrder:        # desenvolver outras formas de percorrer a coleo        ...        return InsertOrder(self.colletion)    def add_item(self, item):        self._collection.append(item)
  • classe WordsCollection: recebe a estrutura de dados, aqui usamos uma lista para facilitar o entendimento
  • funo __init__: construtor da classe, ele vai receber a coleo para iterar
  • funo __iter__: invoca a classe InsertOrder, passa a coleo como parmetro e retorna um iterador
  • funo get_reverse: invoca a classe InsertOrder, passa a coleo e a sinalizao de ordem reversa como parmetros e retorna um iterador
  • funo outras_formas: um exemplo criado sem implementao, podendo criar diferentes regras de busca na mesma coleo, retornando tambm um iterator
  • funo add_item: adiciona elementos uma coleo

Criando o cliente.py

O cliente quem vai utilizar o iterador, sem precisar saber sobre suas regras de busca, apenas passando a coleo e indicando o mtodo.

def instance_collection(elements: list[str]) -> WordsCollection:    collection = WordsCollection()    for element in elements:        collection.add_item(element)    return collection
  • funo instance_collection: instancia um objeto itervel, nesse caso uma lista de strings e retorna essa coleo

Executando o cliente.py

if __name__ == '__main__':    elements = [        'IFSC',        'Programao',        'Laboratrio',        'Professor',        'Aluno'        ]    collection = instance_collection(elements)
  • varivel elements: definimos uma lista de elementos
  • varivel collection: chama a funo para instanciar um objeto itervel, passando como parametro elements

Iterando pela collection de forma normal:

for e in collection.__iter__():    print(e)

Sada:

IFSCProgramaoLaboratrioProfessorAluno

Iterando pela collection de forma reversa:

for e in collection.get_reverse():    print(e)

Sada:

AlunoProfessorLaboratrioProgramaoIFSC

Consideraes

Com algumas adaptaes no iterator.py, podemos fazer a iterao de diversas colees e estruturas, sem a necessidade de alterar o cdigo cliente.py, pois esse apenas consumir o iterador.

Conhecendo mais sobre o mdulo collections.abc e iterator do Python.

Pessoas que compartilham conhecimentos na comunidade: vcwild

Principal referncia para desenvolvimento deste artigo.

Repositrio com o cdigo completo.

Enjoy!


Original Link: https://dev.to/feministech/padrao-de-projeto-iterator-4a4j

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To