
É importante saber que os Padrões, por si só, não garantem o sucesso de um projeto, cada um deles descreve quando pode ser aplicado, mas somente a experiência pode proporcionar o entendimento de quando um Padrão em particular melhora a arquitetura do software. Este curso possui o objetivo de lhe prover essa experiência com a parte prática no uso de cada um dos 23 Padrões de Projeto do GoF.
Editores de Java
Um sistema deve ser independente de como seus elementos são criados, compostos e representados.
Um sistema deve ser configurado para trabalhar com uma única família dentre múltiplas famílias de produtos.
Uma família de produtos relacionados é projetada para ser usada em conjunto, e há a necessidade de reforçar essa restrição.
Se quiser criar uma biblioteca de classes de produtos, revelando apenas suas interfaces e não suas implementações.
A criação de um objeto complexo deve ser independente das partes que o compõem e de como estas são conectadas entre si.
O processo de construção deve permitir a criação de diferentes representações do objeto construído.
A classe não pode antecipar a que será criada.
Deseja que suas subclasses especifiquem os objetos que devem ser criados.
Classes delegam responsabilidades para uma dentre várias subclasses auxiliares.
As classes instanciadas são especificadas em tempo de execução.
Evitar a construção de uma hierarquia de classes de fabricação paralela a uma hierarquia de classes de produtos por elas fabricados.
Quando as instâncias de uma classe podem ter algumas poucas variações de estado, é mais simples definir uma quantidade de protótipos e cloná-los do que criar os respectivos estados manualmente.
Deve haver exatamente uma única instância de uma classe, e esta deve estar disponível a todos os clientes de um ponto de acesso bem definido.
Uma única instância possa ser estendida por herança, e os clientes serem capazes de utilizar essa instância estendida sem terem de modificar o seu código.
Usar uma classe já existente porém sua interface não combina com a esperada pelo cliente.
Desejar criar uma classe reutilizável que coopera com classes não relacionadas ou não previstas, isto é, classes que não necessariamente tenham interfaces compatíveis.
Destinado a evitar uma ligação permanente entre a abstração e sua implementação. O que ocorre, por exemplo, quando a implementação deve ser selecionada ou trocada em tempo de execução.
Mudanças na implementação de uma abstração não devem ter impacto nos clientes, isto é, seu código não deve ter que ser recompilado.
Quando se deseja esconder completamente a implementação dos clientes, evitando que a representação de uma classe seja realizada através da interface dessa classe.
Para compartilhar uma implementação entre vários objetos, e este fato deva estar oculto para os clientes.
Representar hierarquias de objetos do tipo todo/parte.
Tratar todos os objetos uniformemente e ignorar a diferença entre composições de objetos individuais.
Adicionar as responsabilidades a objetos individuais de forma dinâmica e transparente sem afetar outros objetos.
Evitar a explosão de subclasses para suportar cada combinação produzidas por um grande número de extensões independentes.
Oferecer uma interface simples para um subsistema complexo. Subsistemas ficam cada vez mais complexos a medida que evoluem.
Desacoplar o subsistema dos clientes e dos outros subsistemas e promover a independência e portabilidade desses subsistemas, para evitar a existência de muitas dependências entre clientes e as classes de implementação de uma abstração.
Minimizar uma grande quantidade de objetos, que acarreta custos no armazenamento, pois uma aplicação pode usar um grande número de objetos.
Substituir grupos de objetos por, relativamente, poucos objetos que possam ser compartilhados, uma vez que o estado extrínseco é removido deles e colocado em outro lugar.
Necessitar de uma referência mais versátil ou sofisticada para um objeto do que um simples ponteiro.
Mais de um objeto pode tratar uma requisição, e estes não são conhecidos a priori. O objeto a tratar a requisição deve ser definido automaticamente.
Pare emitir uma requisição para um dos vários objetos envolvidos, sem especificá-lo explicitamente.
O conjunto de objetos que pode manipular uma requisição deve ser especificado dinamicamente.
Parametrizar objetos por uma ação a ser executada.É uma substituição da Orientação a Objetos das funções de call back.
Especificar, enfileirar ou executar requisições em diferentes momentos.
Suportar log das últimas modificações, de forma que possam ser reaplicadas no caso de uma queda do sistema.
Estruturar um sistema em torno de operações de alto nível construídas a partir de operações primitivas, como no caso de transações.
A gramática é simples.
A eficiência não é o ponto crítico.
Acessar o conteúdo de um objeto agregado sem expor sua representação interna.
Suportar múltiplas varreduras de objetos agregados.
Prover uma interface uniforme para varrer diferentes estruturas agregadas.
Em um conjunto de objetos que se comunica de uma maneira bem definida, porém complexa o que resulta em interdependências desestruturadas e difíceis de entender.
O reuso de um objeto é difícil por causa das suas referências e comunicação com outros objetos.
Para um comportamento que é distribuído entre várias classes e deve ser customizado sem um conjunto de subclasses.
O estado instantâneo de um objeto deve ser salvo até que possa ser restaurado.
Um acesso direto a interface para obter o estado do objeto faz com que sejam expostos detalhes de implementação o que quebraria seu encapsulamento.
Uma abstração tem dois aspectos, e um depende do outro. Encapsulando esses aspectos em objetos separados fará com que se possa variá-los e reusá-los independentemente.
Uma mudança em um objeto requer uma mudança em outros, e não se sabe como esses outros objetos realizam essas mudanças.
Um objeto deve poder notificar outros objetos sem assumir nada sobre eles.
O comportamento de um objeto depende de seu estado, e este deve ser mudado em tempo de execução conforme as mudanças ocorridas em seu estado.
Colocar cada ramo de uma estrutura condicional em uma classe separada. Dessa maneira, o estado do objeto pode ser tratado com seus próprios direitos que podem variar independentemente de outros.
Configurar uma classe com um entre vários comportamentos possíveis.
Diferente variação de um algoritmo são implementadas como uma classe hierárquica de algoritmos.
Evitar a exposição de complexas estruturas de dados de algoritmos específicos.
Implementar partes invariáveis de um algoritmo e deixar que as subclasses implementem os comportamentos variáveis.
Fatorar comportamentos comuns entre subclasses e localizar uma classe comum para evitar duplicação de código.
Uma estrutura de objetos contém várias classes de objetos com diferentes interfaces, e deve fazer operações nesses objetos que dependem de suas classes concretas.
Guardar operações relacionadas juntas em uma classe.
Para obter operações apenas para aquelas aplicações que necessitem delas quando uma estrutura de objetos é compartilhada por várias
aplicações.
Neste curso veremos como utilizar e extrair benefícios de cada um dos 23 padrões de projeto GoF (Gang of Four). Cada Padrão de Projeto é reconhecido como uma solução comprovada para um determinado problema na concepção de um projeto de software, os padrões do GoF são divididos em 3 áreas:
Os padrões foram concebidos para oferecerem as melhores soluções, seguindo um processo detalhado para responder a análise dos requisitos através de uma arquitetura flexível.