Neste artigo continuaremos o estudo sobre os padrões de projeto. Iremos abordar o padrão Abstract Factory, implementando-o de duas formas: como uma classe abstrata e como uma interface. Daremos um enfoque maior à segunda opção.
Para que serve
Abstract Factory não é apenas a ancestral de todas as Concrete Factorys, mas é também um modo de desacoplar ainda mais os seus sistemas, por delegar a criação de famílias inteiras de objetos sem se especificar uma classe concreta e usando uma única interface. Pode ser até uma fábrica de fábricas.
Em que situação o tema é útil
Quando o seu sistema necessita de um alto nível de generalização ele também precisará de um alto nível de desacoplamento. Enquanto as concrete Factorys permitem criar uma gama diferente de objetos da mesma família através de seus Factory Methods, contanto que a fábrica concreta seja especificada, Abstract Factory pode flexibilizar até mesmo qual será a fábrica concreta a ser usada, delegando o tipo de retorno de seus Factory Methods a seus descendentes. Isso nos permitirá, por exemplo, criar conexões com bancos de dados diferentes por usar linhas/fabricantes de componentes diferentes.
Resumo do DevMan
Desacoplar é a chave para flexibilizar. Se o seu sistema for capaz de montar automaticamente todo um fluxo que vai desde as interfaces, passando pelos objetos de negócio e indo até a persistência, livre de qualquer dependência com outras tecnologias podemos dizer que o sistema é flexível. A flexibilidade no Delphi ainda traz os benefícios de se estar usando uma linguagem compilada, nativa e fortemente tipada.
Como se sabe a orientação a objetos sempre foi um dos pilares das boas práticas de programação, permitindo que seja possível construir aplicações robustas e ao mesmo tempo flexíveis, ou seja, que sejam capazes de sofrer modificações sem tornar isso uma tarefa árdua e desgastante. Embora todo o IDE do Delphi seja Orientado a Objetos, esta ainda é uma prática pouco utilizada pelos seguidores do Object Pascal, devido à metodologia procedural que sempre foi adotada pela maioria. Porém, acompanhando fóruns de discussão, é possível notar que este quadro tem se revertido, mostrando um interesse maior e uma mudança de ideias em relação à adoção da orientação a objetos como metodologia cotidiana dos desenvolvedores Delphi.
Para a melhor utilização da metodologia é necessário compreender os principais fundamentos e conceitos, e porque não dizer obrigatórios e indispensáveis, para visualizar a orientação a objetos de forma clara e organizada. Para isto, foram criados os padrões de projeto, que ganharam popularidade através dos autores Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides, ou GoF (Gang Of Four) como é mais conhecida, através do livro Design Patterns: Elements of Resuble Object-Oriented Software.
Os padrões de projeto são basicamente divididos em três famílias:
Padrões de criação ou criacionais:
Abstract Factory, Factory Method, Singleton, Builder e Prototype;
Padrões estruturais:
Adapter, Bridge, Composite, Decorator, Façade, Flyweight e Proxy;
Padrões comportamentais:
Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method e Visitor;
No artigo anterior foi comentado a respeito do padrão de projeto Factory Method. Factory Method é um método que se responsabiliza pela criação (e possível configuração ou ligação) de um objeto ou de um grupo de objetos.
Nesse contexto o construtor de uma classe (Create no Delphi Win32, new no Delphi Prism) pode ser considerado como um método fábrica degenerado, pois cria apenas um tipo de objeto, sem parametrizá-lo muito e ainda tem um alto acoplamento com a unidade desta classe por motivos óbvios: ele foi escrito como método desta classe, nesta mesma unidade.
Já nesta parte da série, será abordado o Abstract Factory. Para facilitar a compreensão do padrão, imagine já ter criado melhorias em um sistema por delegar a criação de certos objetos a alguns métodos que serão usados por “clientes” (outros objetos que necessitem destes).
A limitação aqui refere-se a necessidade de instanciar uma classe fábrica concreta para cada tipo ou família de objetos que seja criada. Supondo-se por exemplo, que uma fábrica de conexões com o Interbase fosse criada, ela criaria tanto o IBConnection como os IBDataSets, e talvez uma outra fábrica concreta poderia criar AdoConnections e AdoDataSets.
O objetivo do Abstract Factory é criar uma interface comum para acesso e manipulação de qualquer fábrica concreta. Com o Abstract Factory criam-se variáveis genéricas, com métodos que criarão o objeto indiretamente, delegando aos descendentes da Abstract Factory a responsabilidade de saber qual o tipo de objeto correto a se criar.
Há duas formas de atribuir uma interface comum a todas as fábricas de objetos: ou elas são descendentes do mesmo ancestral comum ou elas implementam uma mesma interface.
Será adotada a segunda opção pelas vantagens que o uso de interfaces proporciona: contagem de referências (veja nota do DevMan) e a possibilidade de criar uma fábrica concreta que não seja necessariamente “da família” das outras fábricas. Porém, antes de criar uma interface padrão para as fábricas concretas, será criada uma interface padrão para os produtos concretos. Isso flexibilizará a aplicação a tal ponto que para um objeto ser considerado um produto concreto basta que implemente a interface, mesmo que não seja “parente” dos outros produtos. Isso exibe um cenário em que virtualmente qualquer classe pode ser uma fábrica e criar qualquer tipo de produto.
Interfaces, contagem de referência, TInterfacedObject e IInterface
Objetos que implementam interfaces, caso sejam descendentes de TInterfacedObject não necessitam ser destruídos, pois tem um contador de referências interno que automaticamente destrói o objeto que a implementa quando esse contador chega a zero. Além disso, TInterfacedObject tem um mecanismo para trabalhar com multithread que previne que um objeto seja destruído quando ainda não terminou de ser criado. Então, teoricamente usando interfaces e criando classes como descendentes de TInterfacedObject não precisamos nos preocupar com a destruição dos objetos e nem com Memory Leaks, que é o termo dado para um objeto que foi criado em tempo de execução, contudo, após seu devido uso e descarte, não é destruído / eliminado da memória.
Como sabemos, toda classe emObject Pascalacabará herdando de uma outra conhecida comoTObject. Desse modo, os métodos dessa classe estarão disponíveis a qualquer outra que for herdada. Não surpreendentemente, o mesmo acontece com as interfaces. Toda e qualquer interface no Delphi, mesmo que não seja declarado explicitamente, herdará deIInterface.
A diferença na herança entre classes e interfaces está na falta de implementação. Se uma interface X herda de Y, um objeto que implemente X também deverá implementar os métodos de Y. Ou seja, se seguirmos essa ideia até o topo da hierarquia, todos os objetos que implementem interfaces, deverão definir implementações para os métodos deIInterface. Na prática normalmente não implementamos diretamente nenhum método deIInterface(mesmo que ainda não saibamos quais eles sejam).
Vejaa seguir a declaração de IInterfacee TInterfacedObject, retirada dos fontes da VCL do Delphi XE:
IInterface = interface
['{00000000-0000-0000-C000-000000000046}']
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;
TInterfacedObject = class(TObject, IInterface)
protected
FRefCount: Integer;
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
public
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
class function NewInstance: TObject; override;
property RefCount: Integer read FRefCount;
end;
...
Confira outros conteúdos:
Instalando o ACBr
Mapeamento Objeto-Relacional com TMS...
Introdução aos componentes JEDI
Black November
Desconto exclusivo para as primeiras 200 matrículas!
Pagamento anual
12x no cartão
De: R$ 69,00
Por: R$ 54,90
Total: R$ 658,80
Garanta o desconto
- Formação FullStack Completa
- Carreira Front-end I e II, Algoritmo e Javascript, Back-end e Mobile
- +10.000 exercícios gamificados
- +50 projetos reais
- Comunidade com + 200 mil alunos
- Estude pelo Aplicativo (Android e iOS)
- Suporte online
- 12 meses de acesso
Pagamento recorrente
Cobrado mensalmente no cartão
De: R$ 79,00
Por: R$ 54,90 /mês
Total: R$ 658,80
Garanta o desconto
- Formação FullStack Completa
- Carreira Front-end I e II, Algoritmo e Javascript, Back-end e Mobile
- +10.000 exercícios gamificados
- +50 projetos reais
- Comunidade com + 200 mil alunos
- Estude pelo Aplicativo (Android e iOS)
- Suporte online
- Fidelidade de 12 meses
- Não compromete o limite do seu cartão
<Perguntas frequentes>
Nossos casos de sucesso
Eu sabia pouquíssimas coisas de programação antes de começar a estudar com vocês, fui me especializando em várias áreas e ferramentas que tinham na plataforma, e com essa bagagem consegui um estágio logo no início do meu primeiro período na faculdade.
Estudo aqui na Dev desde o meio do ano passado!
Nesse período a Dev me ajudou a crescer muito aqui no trampo.
Fui o primeiro desenvolvedor contratado pela minha
empresa. Hoje eu lidero um time de desenvolvimento!
Minha meta é continuar estudando e praticando para ser um
Full-Stack Dev!
Economizei 3 meses para assinar a plataforma e sendo sincero valeu muito a pena, pois a plataforma é bem intuitiva e muuuuito didática a metodologia de ensino. Sinto que estou EVOLUINDO a cada dia. Muito obrigado!
Nossa! Plataforma maravilhosa. To amando o curso de desenvolvimento front-end, tinha coisas que eu ainda não tinha visto. A didática é do jeito que qualquer pessoa consegue aprender. Sério, to apaixonado, adorando demais.
Adquiri o curso de vocês e logo percebi que são os melhores do Brasil. É um passo a passo incrível. Só não aprende quem não quer. Foi o melhor investimento da minha vida!
Foi um dos melhores investimentos que já fiz na vida e tenho aprendido bastante com a plataforma. Vocês estão fazendo parte da minha jornada nesse mundo da programação, irei assinar meu contrato como programador graças a plataforma.
Wanderson Oliveira
Comprei a assinatura tem uma semana, aprendi mais do que 4 meses estudando outros cursos. Exercícios práticos que não tem como não aprender, estão de parabéns!
Obrigado DevMedia, nunca presenciei uma plataforma de ensino tão presente na vida acadêmica de seus alunos, parabéns!
Eduardo Dorneles
Aprendi React na plataforma da DevMedia há cerca de 1 ano e meio... Hoje estou há 1 ano empregado trabalhando 100% com React!
Adauto Junior
Já fiz alguns cursos na área e nenhum é tão bom quanto o de vocês. Estou aprendendo muito, muito obrigado por existirem. Estão de parabéns... Espero um dia conseguir um emprego na área.
Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.