Algum humor e C++ Design Patterns (parte 2)

Continuamos a discussão a respeito de Singletons, iniciada na primeira parte desse artigo até chegarmos à Injeção de Dependência. As coisas agora se tornam profundamente C++. Transformamos os Singletons em contêineres, para torná-los efetivamente reutilizáveis e discutimos a teoria que existe por trás dos Templates do C++ e de como a metaprogramação é feita nessa linguagem.

[ Hits: 27.370 ]

Por: Paulo Silva Filho em 25/10/2010 | Blog: http://psfdeveloper.blogspot.com


A implementação de Templeton



Typleton é completamente auto-suficiente. Essa classe é autocontida e não precisa de nenhuma outra classe. Por outro lado, Templeton precisa de algumas classes de apoio.

Por causa disso, e para organizar o código e a proliferação de classes, eu criei um namespace chamado featherns que irá conter todas as classes apresentadas nesse tutorial, de todos os Design Patterns que eu lhes mostrar. Featherns é o nome do projeto que eu criei para hospedar o código deste tutorial. Trata-se de uma combinação das palavras Feather (pena) e Patterns, resultando em Featherns.

O nome significa que este projeto, como uma biblioteca, é leve como uma pena e lida com Design Patterns. Featherns será uma biblioteca composta somente por arquivos de cabeçalho, assim como algumas bibliotecas do Boost. E eu pretendo que ela seja completamente portátil, sem dependências externas. Essas dependências externas, por ironia, podem ser usada em Featherns através de Injeção de Dependência (como veremos mais tarde nesse mesmo post).

Acompanhando a classe parental de Templeton, cujo nome é SingletonController, precisamos definir uma exceção que será lançada se Templeton for instanciada mais de uma vez. Chamei essa classe de MultiSingletonException e ela é uma classe derivada da classe std::exception fornecida pela Biblioteca Padrão C++. Mas isso não é suficiente, precisamos vincular Templeton corretamente a SingletonController, e essa vinculação correta é através de herança privativa, não através da herança pública, que é muito mais comum. Vamos ao código fonte:

Figura 4
Como pode ser visto, depois de todas as explicações dadas acima, a codificação de Templeton é bastante simples. Templeton usa uma funcão de controle externa, chamada SingletonController::initialize, como pode ser visto na linha 30 da Figura 4; no lugar de uma função local, como ocorre em Typleton. Uma vez que SingletonController não é um template, ele não é instanciável para diversos tipos, e a sua função de controle é sempre a mesma em todo o programa, não importando que classe foi usada para instanciar Templeton.

Templeton é realmente um Singleton de verdade. E um daqueles bastante restritivos. Ele só pode ser instanciado uma única vez em todo o programa, incluindo as suas bibliotecas compartilhadas e em qualquer biblioteca de componentes que o programa utilize. É uma força, mas, também, uma fraqueza. Templeton é tão restritiva que nós precisaremos relaxá-lo um pouquinho para deixá-lo efetivamente útil para o uso em Inversão de Controle. Mas esse post é a respeito de Singletons, não de Inversões de Controle. Portanto deixaremos para resolver esse problema mais tarde, no momento adequado.

Agora que tempos uma codificação real de um Singleton, é chegado o momento de mostrar alguns exemplos. Mas não vou fazê-lo. Irei, de forma sádica, ainda mais fundo dentro de Typleton e de Templeton. Essas duas classes são contêineres de ponteiros. Isso é bom. Gerenciamento de ponteiros, em C++, nos dá completo poder sobre o polimorfismo existente nas funções virtuais.

Atribuição de ponteiros é completamente segura em multithreading porque esses comandos são traduzidos pelo C++ (e também pelo C) em instruções de processamento atômicas. Mas o uso de Templeton e de Typleton é seguro em multithreading apenas se as suas classes parâmetro também forem seguras. Isso significa que todo controle de acesso a threads precisa ser feito pelos usuários dessas classes.

Isso é ruim, mas em Featherns não poderia ser diferente. Controle de acesso a threads é código dependente de plataforma e Featherns tem como objetivo ser autocontida e independente de plataforma. Mas eu posso dar uma pequena ajuda, oferecendo na biblioteca classes que definam um padrão de implementação de segurança em multithreading nos Singletons. Featherns não oferecerá controle de acesso a threads, mas irá oferecer como e onde colocar o controle de acesso.

Agora chegamos em um ponto de inflexão. Explicar em mínimos detalhes como implementar segurança em multithreading em Typleton e Templeton seria cansativo, e não adicionaria nenhum valor informacional a esse tutorial. Então ofereço a vocês o link para a primeira versão liberada do arquivo de cabeçalho que contém Typleton e Templeton. Obtenha tal arquivo neste link.

Dê uma parada para descansar. Leia o arquivo Singleton.h com cuidado. Agora é o momento de partirmos para as Injeções de Dependência.

Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. Qual é essa dos Templates, no final das contas?
   3. Uma reimplementação muito mais sofisticada do Singleton
   4. Erros na Implementação de Typleton?
   5. De Typleton para Templeton
   6. A implementação de Templeton
   7. Injeções de Dependência em Singletons
Outros artigos deste autor

Algum humor e C++ Design Patterns (parte 1)

Leitura recomendada

Tutorial OpenGL v3.0

Como funcionam os alocadores de memória do STD C?

A duplicação do buffer de saída na chamada de sistema fork() do Linux

Utilizando técnicas recursivas em C e C++

Alocação dinâmica

  
Comentários
[1] Comentário enviado por julio_hoffimann em 25/10/2010 - 23:36h

Oi Paulo,

Estou impressionado com a sua destreza no assunto! Há tempos que não aprendia coisas tão interessantes assim em POO. O artigo está incrível, conceitos de alto nível explicados de uma forma simples, sem deixar de ser filosófica.

O Templeton foi algo esplendoroso, quase cai da cadeira quando você o manifestou. Com esta série, começo a ver que metaprogramação vale muito a pena e que apesar de ser um investimento árduo, não hesitarei em aprendê-la.

Obrigado por compartilhar tanto conhecimento, desejo sucesso e boa sorte com a Featherns.

Abraço!

P.S.: Quando li no agregador de feeds: Design Patterns (parte 2), parei tudo que estava fazendo para prestigiar o artigo. :-)

[2] Comentário enviado por psfdeveloper em 26/10/2010 - 01:56h

Caro Julio,

eu fico muito feliz com tal manifestação de apreço... Eu vi que eu esqueci algumas partes do texto em inglês, mas o pessoal do Viva o Linux não tirou. Não sei se foi intencionalmente, mas não vou reclamar.

Metaprogramação é um dos tópicos mais importantes e interessantes da programação como um todo. Quase todas as linguagens possuem capacidades de metaprogramação. Algumas surpreendentemente poderosas, ao ponto de você poder quase que alterar a linguagem inteira (como o Lisp, com suas "macros" - vale a pena dar uma olhada, mesmo que seja como uma referência teórica - recomendo o Racket - http://racket-lang.org/ - que no Debian/Ubuntu pode ser obtido através do pacote plt-scheme), alterar comportamento de objetos e de seus derivados em tempo real (como em Javascript - na verdade uma capacidade de Javascript que só vi em Javascript - talvez na sua linguagem mãe, o Self), ou outras fortemente flexíveis por serem totalmente em tempo de execução - como o Python ou o Perl, em maior grau. O Java possui uma abordagem mista para a metaprogramação (com os Generics), que envolve a necessidade de Reflexion, com aspectos estáticos e dinâmicos.

Mas a linguagem que colocou a Metaprogramação na ordem do dia realmente foi C++, que foi duramente criticada por anos a fio justamente por causa do excesso de poder dado a essa capacidade, pelos templates e em momento de compilação. Quando ficou claro o poder da Metaprogramação por templates, diversas linguagens começaram a copiá-la.

Metaprogramação é um assunto árduo, cuja teoria é mais difícil que a codificação em si, mas dou toda força. Vai fundo.

E muitíssimo obrigado por prestigiar meu trabalho. Não tenho o que dizer.

Abraços.

[3] Comentário enviado por edgardiniz em 27/10/2010 - 18:36h

Ainda não li essa segunda parte, apressei o comentário para não esquecer mais tarde.

Com relação aos códigos, você pode utilizar algo como o pastebin.com, que permite fazer o embed dos códigos, e conta com tudo o que você precisa, sem a necessidade de usar imagens com o código e fornece-lo no final.

A não ser que o VOL não permita embedding nos artigos, não sei...

Mas cara, você está de parabéns, estou aprendendo muito com seus artigos.

Continue com o trabalho excelente.

[4] Comentário enviado por psfdeveloper em 27/10/2010 - 20:08h

Caro edgar,

o VOL não permite embedding de tags html no código, só com muitas restrições. E todo código fonte é posto disponível para download na última página do artigo.

Abraços.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts