Padrões de software – o iterador

Desenhar software reutilizável é uma tarefa árdua. Tal desenho deve ser específico ao problema corrente mas também geral o suficiente para ser aplicável em futuras situações. O objectivo prende-se com a minimização da remodelação que se tem de aplicar num determinado desenho no futuro. Sempre que se desenha um software, este sistema é testado diversas vezes por forma a modificá-lo sempre que seja necessário.
No caso da arquitectura orientada a objectos, é premente a identificação dos objectos envolvidos, factorizá-los em classes com a granularidade adequada, definir as interfaces e relações de herança e estabelecer relações fulcrais entre eles. Além disso, será útil identificar as características fundamentais da estrutura que podem ser implementadas com o recurso directo a técnicas de programação genérica ou uma técnica promíscua. Uma boa pragmática em engenharia de software consiste em reutilizar soluções já conhecidas para o problema em questão ao invés de resolvê-lo de raiz.
Um padrão é uma técnica de esboço de sistemas de software que permite facilitar a reutilização do código de uma forma padronizada, tornando o desenvolvimento mais acessível a novos programadores. Permite aos arquitectos obter um bom esquema em menor tempo. Associados ao padrão estão quatro características fundamentais:

  • Nome: o nome serve para identificar a solução proposta para um determinado tipo de problemas. Identifica o padrão.
  • Problema: descreve quando e como deve ser aplicado o padrão.
  • Solução: descreve os elementos que constitui o esquema referido, as suas relações, responsabilidades e colaborações.
  • Consequências: são os resultados e benefícios da aplicação de um padrão.

No livro do Gang of Four, "Design Patterns, Elements of Reusable Object Oriented Software" existem três tipos de padrões a ter em conta (apesar dos padrões apresentados não abrangerem áreas tais como a computação distribuída):

  • Padrões criativos: estes padrões permitem abstrair a criação de objectos, tornando o sistema independente desta particularidade. Entre estes, contam-se o AbstractFactory, Builder, Factory Method, Prototype e Singleton.
  • Padrões estruturais: são orientados para a forma como as classes são compostas, formando estruturas maiores. Nestes padrões contam-se o Adapter, Bridge, Composite, Decorator, Facade, Flyweight e Proxy.
  • Padrões comportamentais: estes padrões relacionam-se com os algoritmos em si bem como a atribuição de responsabilidades entre objectos. Entre este tipo contam-se os padrões Chain of Responsability (usado com frequência no sistema axis), Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method e Visitor.

O Iterador

O iterador consiste num padrão que providencia uma forma de aceder sequencialmente aos elementos de um agregado sem expor a respectiva implementação. Esta ideia permite generalizar a noção de apontadores para um vector vulgar. A figura seguinte permite descrever de uma forma esquemática o funcionamento de um iterador muito simples.

iterator

O iterador implementa os operadores de comparação, atribuição, de inicialização, de avanço e de obtenção do elemento do agregado ou a sua substituição (dependendo da forma como o operador * é implementado).

No sítio http://algorexamples.googlecode.com/svn/trunk/, pode-se encontrar o exemplo de dois iteradores da minha autoria, nomeadamente um para as permutações de elementos e outro para as combinações. Os ficheiros são:
GenericPermutation.h
GenericPermutation.cpp
GenericCombination.h
GenericCombination.cpp
Como exemplo de utilização dos iteradores, considere-se o código:

#include <iostream>
#include<vector>

using namespace std;
#include "GenericPermutation.cpp"

template<typename T>
void print_vector(vector<T>& v){
     if(!v.empty()){
         typename vector<T>::iterator iter = v.begin();
         if(iter!=v.end()) cout<<*iter;
         ++iter;  
         for(; iter != v.end(); iter++){
               cout<<", "<<*iter;
         }
    }
}

int main(int argc, char *argv[])
{
    vector<int> v;
    v.push_back(1);
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    int numbPerm = 3;
    GenericPermutation<int> gp(v,numbPerm);
    GenericPermutation<int>::iterator it = gp.begin();
    for(GenericPermutation<int>::iterator it = gp.begin(); it != gp.end(); ++it){
        vector<int> vec = *it;
        print_vector(vec);
        cout<<endl;
    }
    system("PAUSE");
    return EXIT_SUCCESS;
}

Este código permite escrever todas as permutações de três elementos relativas ao vector [1,1,2,3]. Este programa irá resultar em:
1, 1, 2
1, 1, 3
1, 2, 1
1, 2, 3
1, 3, 1
1, 3, 2
2, 1, 1
2, 1, 3
2, 3, 1
3, 1, 1
3, 1, 2
3, 2, 1

O iterador e a classe que representa a lista de todas as combinações funciona da mesma maneira onde apenas se têm de substituir as classes intervenientes.

Apesar do iterador estar a funcionar convenientemente na situação exemplificada, ainda carece de uma função de comparação entre dois iteradores para a mesma representação de todas as permutações. Devido ao seu conceito, trata-se de um iterador apenas de saída.

O iterador para as permutações pode ser utilizado num algoritmo que efectue multiplicações em polinómios simétricos de uma forma rápida. Entre as aplicações do iterador para as combinações pode-se especificar a construção do conjunto potência de um determinado conjunto dado ou a aplicação da expansão de Laplace geral para o cálculo de determinantes.

Sobre Sérgio O. Marques

Licenciado em Física/Matemática Aplicada (Astronomia) pela Faculdade de Ciências da Universidade do Porto e Mestre em Matemática Aplicada pela mesma instituição, desenvolvo trabalho no PTC (Porto Technical Centre) - Yazaki como Administrador de bases-de-dados. Dentro o meu leque de interesses encontram-se todos os temas afins às disciplinas de Matemática, Física e Astronomia. Porém, como entusiasta, interesso-me por temas relacionados com electrónica, poesia, música e fotografia.
Esta entrada foi publicada em Computadores e Internet. ligação permanente.

Deixe uma Resposta

Preencha os seus detalhes abaixo ou clique num ícone para iniciar sessão:

Logótipo da WordPress.com

Está a comentar usando a sua conta WordPress.com Terminar Sessão / Alterar )

Imagem do Twitter

Está a comentar usando a sua conta Twitter Terminar Sessão / Alterar )

Facebook photo

Está a comentar usando a sua conta Facebook Terminar Sessão / Alterar )

Google+ photo

Está a comentar usando a sua conta Google+ Terminar Sessão / Alterar )

Connecting to %s