• Nenhum resultado encontrado

BEHAVIOURAL DESIGN PATTERNS

N/A
N/A
Protected

Academic year: 2021

Share "BEHAVIOURAL DESIGN PATTERNS"

Copied!
19
0
0

Texto

(1)

BEHAVIOURAL DESIGN PATTERNS

Jann Claude Mousquer1, Kenner Alan Kliemann1, Miguel Diogenes Matrakas2

1Curso de Ciˆencia da Computac¸˜ao – Faculdades Anglo-Americano (FAA) 2Mestrado em Inform´atica Aplicada – Pontif´ıcia Universidade Cat´olica

do Paran´a (PUC-PR) Foz do Iguac¸u, PR - Brasil

{jannclaude,kenner.hp}@gmail.com, mdmatrakas@yahoo.com Abstract. Design patterns make it easier to reuse successful designs and ar-chitectures. Design is a way of interpreting the implementation, analyzing and understanding the interactions between certain parts of the system. And the behavioral patterns are concerned with algorithms and the assignment of res-ponsibility between objects. Describe not only the patterns of objects or classes but also the patterns of communication between them.

Resumo. Design patterns torna mais f´acil reutilizar projetos e arquiteturas bem sucedidas. Design ´e uma forma de interpretar a implementac¸˜ao, analisando e compreendendo as interac¸˜oes entre determinadas partes do sistema. Os pat-terns comportamentais est˜ao preocupados com os algoritmos e as atribuic¸˜oes de responsabilidade entre objetos. Descrevem n˜ao s´o os padr˜oes entre objetos ou classes, mas tamb´em os padr˜oes de comunicac¸˜ao entre eles.

Palavras Chave: Padr˜oes, Design, Software;

1. Introduc¸˜ao

Dificilmente uma empresa consegue sobreviver sem aux´ılio de ferramentas computacio-nais. Algumas organizac¸˜oes necessitam de ferramentas b´asicas como editores de texto, planilhas ou geradores de apresentac¸˜ao enquanto outras necessitam de ferramentas es-pec´ıficas (sistemas corporativos) que contemplem todos os processos administrativos da organizac¸˜ao. Em geral, a complexidade no desenvolvimento e na manutenc¸˜ao de um sis-tema corporativo ´e alta. Essa complexidade aumenta o custo e o tempo para desenvolvˆe-lo e mantˆe-lo.[K19 2012]

Projetar software orientado a objetos ´e dif´ıcil e projeto de software orientado a objetos reutiliz´avel ´e ainda mais. ´E preciso encontrar objetos pertinentes, fator´a-los em classes com a granularidade certa, definir interfaces de classe e hierarquias de heranc¸a e estabelecer relac¸˜oes entre eles. O projeto deve ser espec´ıfico para o problema em quest˜ao, mas tamb´em geral o suficiente para resolver os problemas e necessidades futuras. Vocˆe tamb´em quer evitar redesign, ou pelo menos minimiz´a-lo. Projetistas de software experi-entes ir˜ao lhe dizer que um projeto reutiliz´avel e flex´ıvel ´e dif´ıcil e talvez imposs´ıvel de se obter o “certo” na primeira vez. Antes da conclus˜ao de um projeto, eles costumam tentar reutiliz´a-lo v´arias vezes, modificando-o toda vez.[Gamma et al. 1994]

Padr˜oes de projeto tornam mais f´acil reutilizar projetos e arquiteturas bem su-cedidas. Expressando t´ecnicas comprovadas como padr˜oes de projeto os tornam mais

(2)

acess´ıveis aos desenvolvedores dos sistemas. Os padr˜oes de design ajudam a escolher al-ternativas de projetos que tornam um sistema reutiliz´avel e evitam as alal-ternativas que com-prometam a reusabilidade. Padr˜oes de projeto pode at´e mesmo melhorar a documentac¸˜ao e manutenc¸˜ao de sistemas existentes, fornecendo uma especificac¸˜ao expl´ıcita de classe e interac¸˜oes de objetos e sua intenc¸˜ao subjacente. Simplificando, os padr˜oes ajudam um designer `a obter um design ”certo”mais r´apido.[Gamma et al. 1994]

Christopher Alexander diz: ”Cada padr˜ao descreve um problema que ocorre re-petidas vezes em nosso ambiente e ent˜ao descreve o cerne da soluc¸˜ao para esse pro-blema de tal forma que ´e poss´ıvel utilizar esta soluc¸˜ao um milh˜ao de vezes, sem nunca fazer da mesma forma duas vezes”[Alexander et al. 1977]gof. Apesar de Alexander fa-lar sobre padr˜oes em edif´ıcios e cidades, o que ele diz ´e valido sobre design patterns. As soluc¸˜oes s˜ao expressas em termos de objetos e interfaces em vez de paredes e por-tas, mas no cerne de ambos os tipos de padr˜oes ´e a soluc¸˜ao de um problema em um contexto.[Gamma et al. 1994]

De mais a mais, GoF ´e uma abreviac¸˜ao para ”Gang of Four”e refere-se aos quatro escritores do livro ”Design Patterns: Elements of Reusable Object-Oriented Software”. 1.1. Objetivo

Design ´e uma forma de interpretar a implementac¸˜ao, analisando e compreendendo as interac¸˜oes entre determinadas partes do sistema, como poss´ıveis impactos que uma mudanc¸a em um ponto causa em outro componente que o acessa direta ou indiretamente.[Silveira et al. ]. Neste artigo ser´a realizada uma revis˜ao bibliogr´afica dos padr˜oes de projeto (Design Patterns) comportamentais e suas aplicabilidades.

2. Padr˜oes de Projeto

Inicialmente, como descrever padr˜oes de design? Notac¸˜oes gr´aficas, embora importantes e ´uteis, n˜ao s˜ao suficientes. Eles simplesmente capturam o produto final do processo de design como as relac¸˜oes entre classes e objetos. Para reutilizar o design, tamb´em dever´a registrar as decis˜oes alternativas e os trade-offs que levaram a ela. Exemplos concretos s˜ao muito importantes, porque eles ajudam a ver o projeto em ac¸˜ao.[Gamma et al. 1994]

GoF [Gamma et al. 1994] descreve padr˜oes de projeto usando um formato con-sistente. Cada padr˜ao ´e dividido em sec¸˜oes de acordo com um modelo. O modelo d´a uma estrutura uniforme para as informac¸˜oes, tornando os padr˜oes de design mais f´acil de aprender, comparar e usar. O modelo ´e dividido em t´opicos, como por exemplo:

• Nome do padr˜ao e sua classificac¸˜ao; • Intenc¸˜ao. O que ele faz e por que existe; • Aplicabilidade. Onde pode ser aplicado.

Os padr˜oes de design variam na sua granularidade e n´ıvel de abstrac¸˜ao, porquanto h´a muitos padr˜oes de projeto e ´e preciso organiz´a-los. GoF [Gamma et al. 1994]classifica os padr˜oes de projeto por dois crit´erios:

• O primeiro crit´erio chamado de prop´osito, o que um padr˜ao faz. Os padr˜oes podem ser criacionais, estruturais ou comportamentais. Padr˜oes de criac¸˜ao di-zem respeito ao processo de criac¸˜ao do objeto. Padr˜oes estruturais lidam com a composic¸˜ao de classes ou objetos. Os padr˜oes comportamentais se caracterizam pelas classes ou objetos que interagem e distribuem responsabilidades;

(3)

• O segundo crit´erio chamado escopo, especifica se o padr˜ao se aplica principal-mente `as classes ou objetos. Padr˜oes de classe lidam com as relac¸˜oes entre as classes e suas subclasses. Essas relac¸˜oes s˜ao estabelecidas por meio de heranc¸a, que est˜ao est´aticos. Padr˜oes de objetos lidam com os relacionamentos de objetos, que podem ser alterados em tempo de execuc¸˜ao, al´em de mais dinˆamicos.

Figura 1. Tabela de Design Patterns segundo GoF

A figura 1 apresenta a tabela de classificac¸˜ao dos padr˜oes de acordo com os crit´erios citados anteriormente.

3. Behavioral patterns

Padr˜oes comportamentais est˜ao preocupados com os algoritmos e as atribuic¸˜oes de res-ponsabilidade entre objetos. Descrevem n˜ao s´o os padr˜oes entre objetos ou classes, mas tamb´em os padr˜oes de comunicac¸˜ao entre eles.

Estes padr˜oes caracterizam um complexo uxo de controle que ´e dif´ıcil de seguir em tempo de execuc¸˜ao. Eles transportam a atenc¸˜ao para longe do uxo de controle e permite ao programador se concentrar apenas no modo como os objetos est˜ao interconec-tados. [Gamma et al. 1994]

A seguir ser˜ao apresentados os padr˜oes e suas caracter´ısticas. 3.1. Chain of responsibility

Evitar o acoplamento do emissor (sender) de um pedido para o seu receptor (receiver), dando mais de um objeto a chance de lidar com o pedido. Cadeia de objetos que recebem e passam a solicitar ao longo desta at´e que um objeto lide com ele.

O padr˜ao resenta ´e um encadeamento de objetos receptores para o processamento de uma s´erie de solicitac¸˜oes diferentes. Esses objetos receptores passam a solicitac¸˜ao ao longo da cadeia at´e que um ou v´arios objetos a tratem.

(4)

Cada objeto receptor possui uma l´ogica descrevendo os tipos de solicitac¸˜ao que ´e capaz de processar e ensina como passar adiante aquelas que requeiram processa-mento por outros receptores. A delegac¸˜ao das solicitac¸˜oes pode formar uma ´arvore de recurs˜ao, com um mecanismo especial para inserc¸˜ao de novos receptores no final da ca-deia existente.[Soares 2012]

Um exemplo da aplicac¸˜ao desse padr˜ao ´e o mecanismo de heranc¸a nas lingua-gens orientadas a objeto: um m´etodo chamado em um objeto ´e buscado na classe que implementa o objeto, caso n˜ao seja encontrado na superclasse dessa classe, de maneira recursiva. [Soares 2012]

Figura 2. Chain of Responsability Pattern

A figura 2 representa a estrutra do padr˜ao. Para tanto, tem os seguintes partici-pantes:

• Handler (HelpHandler)

– Define uma interface para controlar requisic¸˜oes; – (Opcional) Implementa o link sucessor.

• ConcreteHandler (PrintButton, PrintDialog) – controle de requisic¸˜ao se poss´ıvel for; – Pode acessar o sucessor;

– se o ContreteHandler consegue controlar a requisic¸˜ao, fac¸a; caso contr´ario tente o pr´oximo.

• Client

– inicia a requisic¸˜ao para um objeto ConcreteHandler.

Quando um cliente emite uma solicitac¸˜ao, o pedido se propaga ao longo da cadeia at´e que um objeto ConcreteHandler assume a responsabilidade de lidar com ele.

O primeiro objeto na cadeia recebe o pedido, manipula-o ou encaminha-o para o pr´oximo candidato na cadeia, que faz o mesmo. O objeto que fez o pedido n˜ao tem conhecimento expl´ıcito de que vai lidar com isso - ´e dito que o pedido tem um receptor impl´ıcito.

Para encaminhar a requisic¸˜ao ao longo da cadeia e garantir os receptores perma-necem impl´ıcitas, cada objeto implementa uma interface comum para o tratamento dos pedidos para acessar o seu sucessor na cadeia.

(5)

• Reduc¸˜ao de acoplamento. O padr˜ao libera um objeto de saber que outro objeto manipula uma requisic¸˜ao;

• Maior flexibilidade na atribuic¸˜ao de responsabilidades aos objetos. O padr˜ao ofe-rece mais flexibilidade na distribuic¸˜ao de responsabilidades entre os objetos; • O Recebimento n˜ao ´e garantido. Uma vez que um pedido n˜ao tem receptor

expl´ıcito, n˜ao h´a garantia de que vai ser tratado, o pedido pode sair da cadeia sem nunca ter sido tratado.

Por outro lado, o padr˜ao ´e indicado nos seguintes casos:

• Mais de um objeto pode lidar com uma requisic¸˜ao e o manipulador n˜ao ´e conhe-cido. O manipulador deve ser determinado automaticamente;

• Emiss˜ao de um pedido a um dos v´arios objetos, sem especificar o receptor de forma explicita;

• O conjunto de objetos que podem lidar com um pedido deve ser especificado di-namicamente.

3.2. Command ´

E poss´ıvel encapsular uma requisic¸˜ao como um objeto, permitindo que clientes parame-trizem diferentes requisic¸˜oes, enfileirem ou fac¸am o registro de requisic¸˜oes e suportem operac¸˜oes que podem ser desfeitas.

Al´em disso, controla as chamadas a um determinado componente, modelando cada requisic¸˜ao como um objeto. Permiti ainda que as operac¸˜oes possam ser desfeitas, enfileiradas ou registradas. [K19 2012]

Figura 3. Command Pattern

A figura 3 representa a estrutura do padr˜ao, tendo como participantes, os seguin-tes:

• Command: declara uma interface para executar uma operac¸˜ao. • ConcreteCommand(PasteCommand, OpenCommand)

– Define uma ligac¸˜ao entre um objeto receptor e uma ac¸˜ao;

– Implementa o m´etodo Execute invocando a operac¸˜ao correspondente no receptor.

• Client (Application): cria um objeto ConcreteCommand e o seta como receptor; • Invoker(MenuItem): Pede ao Commanda para executar a solicitac¸˜ao;

• Receiver(Document, Application): sabe como executar as operac¸˜oes de um re-quest. Qualquer classe pode ser um receptor.

(6)

No entanto, quando o cliente emite uma requisic¸˜ao de ac¸˜ao, os receptores ir˜ao identificar a solicitac¸˜ao e saber˜ao execut´a-la.

Como consequˆencias, temos:

• O Command desacopla o objeto que invoca a operac¸˜ao daquele que sabe como execut´a-la;

• Commands s˜ao objetos de primeira classe, ou seja, podem ser manipulados e es-tendidos como qualquer outro objeto;

• Um comando pode ser composto por outros comandos;

• ´E f´acil acrescentar novos Commands porque n˜ao ´e preciso mudar classes j´a exis-tentes.

O padr˜ao ´e indicado nos seguintes casos:

• Parametrizar objetos para uma ac¸˜ao a ser tomada;

• Especificar, enfileirar e executar solicitac¸˜oes em tempos diferentes. Um objeto de comando pode ter uma vida independente da solicitac¸˜ao original;

• Suporte a desfazer. O Command pode armazenar as operac¸˜oes de execuc¸˜ao, ar-mazenando seus estados e possibilitando desfazer os mesmos;

• Suporte a mudanc¸as de registro, para que possam ser reaplicadas em caso de uma falha do sistema;

• Estruturar um sistema em torno de operac¸˜oes de alto n´ıvel constru´ıdas sobre operac¸˜oes primitivas. Tal estrutura ´e comum em sistemas de informac¸˜ao que su-portam transac¸˜oes. A transac¸˜ao encapsula um conjunto de alterac¸˜oes aos dados. 3.3. Interpret

Dada uma linguagem, define uma representac¸˜ao para sua gram´atica juntamente com um interpretador que usa a representac¸˜ao para interpretar sentenc¸as na l´ıngua.

Se um determinado tipo de problema ocorre com frequˆencia suficiente, ent˜ao ele pode ser ´util para expressar instˆancias do problema como sentenc¸as em uma linguagem formal. Depois, vocˆe pode construir um int´erprete que resolva o problema por meio da interpretac¸˜ao dessas sentenc¸as, a qual ´e usada para ajudar na aplicac¸˜ao a entender uma declarac¸˜ao de linguagem natural e executar a funcionalidade da declarac¸˜ao.[Soares 2012]

A figura 4 representa a estrutura do padr˜ao e possui os seguintes participantes: • AbstractExpression (RegularExpression): declara um Interpretador de operac¸˜ao

abstrata que ´e comum a todos n´os na ´arvore sint´atica. • TerminalExpression (LiteralExpression)

– Declara uma operac¸˜ao abstrata Interpret que ´e comum a todos n´os na ´arvore sint´atica;

– ´E necess´aria uma instˆancia para cada s´ımbolo terminal da sentenc¸a. • NonterminalExpression (AlternationExpression, RepetitionExpression,

Sequen-ceExpressions)

– Uma classe ´e necess´aria para cada regra n˜ao-terminal na gram´atica; – Mant´em as vari´aveis de instˆancia do tipo AbstractExpression para cada

(7)

Figura 4. Interpreter Pattern

– Implementa um Interpret para os simbolos n˜ao-terminais na gram´atica. Interpret normalmente tem chamadas recursivas para vari´aveis que repre-sentam regras n˜ao-terminais.

• Context: Cont´em informac¸˜oes que s˜ao globais para o interpretador. • Client

– Constr´oi (ou ´e fornecido) uma ´arvore de sintaxe abstrata que representa uma sentenc¸a particular na l´ıngua que a gram´atica define. A ´arvore de sintaxe abstrata (AST) ´e montada a partir de instˆancias das classes Nonter-minalExpression e TerNonter-minalExpression;

– invoca a operac¸˜ao Interpret.

O cliente constr´oi (ou ´e fornecido) a sentenc¸a como uma ´arvore de sintaxe abstrata (AST) de instˆancias de NonterminalExpression e TerminalExpression. Em seguida, o cliente inicializa o contexto e invoca a operac¸˜ao Interpret.

Cada n´o NonterminalExpression define Interpret em termos de interpretar em cada sub-express˜ao. A operac¸˜ao Interpret de cada TerminalExpression define o caso base na recurs˜ao.

As operac¸˜oes do Interpret em cada n´o utilizam o contexto para armazenar e acessar o estado do int´erprete.

Como consequˆencias temos:

• Facilidade para alterar e extender gram´aticas. O padr˜ao utiliza classe para repre-sentar regras, as quais podem ser estendidas via heranc¸a;

• Facilidade para implementar gram´aticas. Classes que definem os n´os na ´arvore de sintaxe abstrata tˆem implementac¸˜oes similares. Essas classes s˜ao f´aceis de escrever, e muitas vezes a sua gerac¸˜ao pode ser automatizada com geradores de compilador ou interpretador; muitas vezes a sua gerac¸˜ao pode ser automatizada com geradores de compilador ou interpretador;

• Adic¸˜ao de novas maneiras de interpretac¸˜ao de express˜oes. O padr˜ao Interpreter viabiliza formas f´aceis de avaliar express˜oes.

(8)

Por´em, o seguinte item deve ser levado em considerac¸˜ao:

• Gram´aticas complexas s˜ao dif´ıceis de manter. O interpretador define uma classe para cada regra na gram´atica, muitas regras implicam em grandes recursos com-putacionais.

O padr˜ao ´e indicado nos seguintes casos:

• Unicamente para interpretac¸˜ao de linguagens. Como, por exemplo, express˜oes regulares.

3.4. Iterator ´

E fornecer uma maneira de acessar sequencialmente os elementos de um objeto agregado sem expor sua representac¸˜ao subjacente.

Um objeto agregado, como uma lista, deve fornecer uma maneira de acessar seus elementos sem expor sua estrutura interna. Al´em disso, ´e poss´ıvel percorrer a lista de maneiras diferentes.

A ideia do padr˜ao Iterator ´e fornecer um meio eficiente de se percorrer todos os elementos de uma determinada colec¸˜ao.[K19 2012]

Figura 5. Iterator Pattern

A figura 5 representa a estrutura do padr˜ao e tem os seguintes participantes: • Iterator: Define uma interface para atravessar elementos.

• ConcreteIterator

– Implementa a interface Iterator;

– Mant´em a posic¸˜ao do elemento corrente no atravessamento de objetos agregados.

• Aggregate: Define uma interface para criac¸˜ao de um objeto Iterator.

• ConcreteAggregate: Implementa a iterface de criac¸˜ao Iterator para retornar uma instˆancia do correto ConcreteIterator.

(9)

O padr˜ao encapsula uma iterac¸˜ao, permitindo acessar os elementos da classe que a implementa independentemente de sua estrutura e organizac¸˜ao.

O ConcreteIterator mant´em o controle do objeto atual e pode calcular o objeto sucessor na travessia.

Como consequˆencias temos:

• Variac¸˜oes diversas na travessia de um agregado; • Simplificac¸˜ao da interface;

• Diversas travessias ao mesmo tempo. Um iterador mant´em o controle de seu pr´oprio estado de travessia.

O padr˜ao ´e indicado nos seguintes casos:

• Acessar o conte´udo de objeto agregados sem expor sua representac¸˜ao interna; • Suporte a mais de uma maneira de percorrer a colec¸˜ao;

• Prover interface ´unica para percorrer estruturas agregadas diferentes. 3.5. Mediator

Um Mediator define um objeto que encapsula como um grupo de objetos interage. Pro-move o desacoplamento, mantendo referˆencias expl´ıcitas entre os objetos e permite variar suas interac¸˜oes de forma independente.

Projetos de software orientado a objetos incentivam a distribuic¸˜ao de comporta-mento entre os objetos. Essa distribuic¸˜ao pode resultar em uma estrutura de objetos com muitas conex˜oes e acoplamento entre objetos. No pior caso, cada objeto acaba sabendo sobre todos os outros.

Quanto mais classes houver no seu projeto, a comunicac¸˜ao entre essas classes ser´a mais complexa. Isso faz com que a leitura e a manutenc¸˜ao do programa fiquem mais dif´ıcil, tal situac¸˜ao acarreta na dificuldade de mudanc¸as no projeto, j´a que, uma simples mudanc¸a pode afetar todo o c´odigo e as outras classes.[Soares 2012]

Com o padr˜ao mediator, a comunicac¸˜ao entre os objetos ´e encapsulada com um objeto mediador. Isso reduz a dependˆencia entre os objetos que est˜ao se comunicando.[Soares 2012] A ideia do padr˜ao Mediator ´e semelhante `a ideia de central telefˆonica. Eliminar conex˜oes excessivas entre elementos por meio da introduc¸˜ao de um intermedi´ario ´unico.[K19 2012]

A figura 6 representa a estrutura do padr˜ao e tem os seguintes participantes: • Mediator: Define uma interface para comunicac¸˜ao com objetos Colleague. • ConcreteMediator (FontDialogDirector)

– Implementa o comportamento cooperativo, por meio da coordenac¸˜ao ob-jetos Colleague;

– Conhece e mant´em seus colegas. • Colleague classes (ListBox, EntryField)

– Cada classe Colleague conhece seu Mediator;

– Cada objeto Colleague se comunica com o Mediator ao inv´es de outros Colleagues.

(10)

Figura 6. Mediator Pattern

Um objeto Mediador deve encapsular toda a comunicac¸˜ao entre um grupo de ob-jetos. Cada objeto participante conhece o mediador, mas ignora a existˆencia dos outros objetos.

O mediador conhece cada um dos objetos participantes e a interface do Mediador ´e usada para iniciar a comunicac¸˜ao e receber notificac¸˜oes. O mediador recebe requisic¸˜oes dos remetentes e repassa as requisic¸˜oes aos destinat´arios

Como consequˆencias temos:

• Desacoplamento entre os diversos participantes da rede de comunicac¸˜ao (partici-pantes n˜ao se conhecem); de comunicac¸˜ao (partici(partici-pantes n˜ao se conhecem) • Eliminac¸˜ao de relacionamentos muitos para muitos (s˜ao todos substitu´ıdos por

relacionamentos um para muitos); • Abstrai como os objetos se comunicam;

• A pol´ıtica de comunicac¸˜oes est´a centralizada no mediador e podem ser alterados sem alter os Colleagues.

O padr˜ao ´e indicado nos seguintes casos:

• Um conjunto de objetos se comunica de maneiras bem definidas, mas complexas. As interdependˆencias resultantes s˜ao n˜ao estruturadas e de dif´ıcil compreens˜ao; • Reutilizac¸˜ao de um objeto ´e dif´ıcil porque ele se refere e se comunica com muitos

outros objetos;

• Um comportamento que ´e distribu´ıdo entre v´arias classes deve ser personaliz´avel sem criar diversas subclasses.

3.6. Memento

Sem violar o encapsulamento, captura e externaliza o estado interno de um objeto para que o objeto possa ser restaurado mais tarde.

Captar e externalizar um estado interno de um objeto, de maneira que esse estado seja restaurado ao objeto em outro momento, sem violar seu encapsulamento.[Soares 2012]

A maneira mais comum de guardar informac¸˜oes dessa maneira ´e por meio de um clone do objeto, instanciado com as informac¸˜oes do estado a ser guardado.[Soares 2012]

(11)

Figura 7. Memento Pattern

• Memento (SolverState)

– Salva o estado interno do objeto Originator; – Protege o acesso dos objetos.

• Originator (ConstraintSolver) – Cria um snapshot do objeto;

– Usa o Memento para restaurar o objeto. • Caretaker (undo mechanism)

– ´E respons´avel por manter o Memento;

– Nunca altera ou examina o conte´udo do Memento.

Um Caretaker solicita um snapshot de um objeto e passa o resultado para o Me-mento manter.

Como consequˆencias temos:

• Preserva limites do encapsulamento; • Simplifica o Originator;

• Definic¸˜ao de interfaces estreitas e largas. Pode ser dif´ıcil em algumas linguagens para garantir que apenas o criador pode acessar o estado do memento.

O padr˜ao ´e indicado nos seguintes casos: • Na implementac¸˜ao de ac¸˜oes de “desfazer”;

• Para o armazenamento de estados a serem restaurados de um objeto, como por exemplo, um banco de dados;

• Para a captac¸˜ao de estados de objetos que s˜ao encobertos por encapsulamento. 3.7. Observer

Define uma dependˆencia um-para-muitos entre objetos de modo que quando um objeto muda de estado, todos os seus dependentes s˜ao notificados e atualizados automaticamente. Permite que objetos interessados sejam avisados da mudanc¸a de estado ou outros eventos ocorrendo num outro objeto. O padr˜ao Observer ´e tamb´em chamado de Publisher-Subscriber, Event Generator e Dependents.[Soares 2012]

A ideia fundamental do padr˜ao Observer ´e atribuir aos objetos que tem seus esta-dos alteraesta-dos a tarefa de notificar os objetos interessaesta-dos nessas mudanc¸as.[K19 2012]

(12)

Figura 8. Observer Pattern

• Subject

– Conhece seus observers. Quaisquer n´umeros de observers podem observar um subject;

– Disponibiliza uma interface para anexar e desanexar objetos observers. • Observer: Define uma interface de atualizac¸˜ao para os objetos que devem ser

notificados sobre mudanc¸as no subject. • ConcreteSubject

– Armazena o estado por qual os ConcreteObservers tˆem interesse; – Envia uma notificac¸˜ao aos seus observers sempre que este estado muda. • ConcreteObserver

– Mant´em referˆencia(s) para o(s) ConcreteSubject(s) sendo observado(s); – Armazena o estado que deve ser mantido consistente com o estado do

sub-ject;

– Implementa a interface de atualizac¸˜ao do Observer.

O ConcreteSubject notifica seus observers sempre que uma mudanc¸a (que pode tornar o estado do observer inconsistente) ocorrer.

Depois de informado sobre uma mudanc¸a no ConcreteSubject o ConcreteObser-ver pode consultar o ConcreteSubject e utilizar a informac¸˜ao obtida para reconciliar seu estado com o estado do ConcreteSubject.

Como consequˆencias temos:

• Acoplamento abstrato entre o Subject e Observer; • Suporte para comunicac¸˜ao em broadcast.

Mas deve-se atententar ao detalhe: • Atualizac¸˜oes inesperadas;

– Devido ao fato que observers n˜ao conhecem a presenc¸a de outros observers eles n˜ao tˆem ciˆencia do custo final de atualizac¸˜ao de um subject;

– Um protocolo muito simples de atualizac¸˜ao (sem parˆametros) pode fazer com que os observers tenham que realizar muito trabalho para deduzir o que mudou.

(13)

• Quando uma abstrac¸˜ao possui dois aspectos, um dependente do outro. Encapsular estes aspectos em objetos diferentes permite que vocˆe os modifique e reutilize de forma independente;

• Quando uma mudanc¸a em um objeto requer a mudanc¸a em outros e vocˆe n˜ao sabe quantos e quais objetos precisam ser modificados. Ou seja, n˜ao se deseja um alto acoplamento entre estes objetos.

3.8. State

Permitir que um objeto altere o seu comportamento como consequˆencia de uma mudanc¸a no seu estado interno.

Considerando uma classe TCPConnection que representa uma conex˜ao de rede. Um objeto TCPConnection pode estar em um dos v´arios estados diferentes: Established, Listening, Closed.. Quando um objeto TCPConnection recebe pedidos de outros objetos, ele responde de forma diferente, dependendo do seu estado atual.

Figura 9. State Pattern

A figura 9 representa a estrutura do padr˜ao e tem os seguintes participantes: • Context (TCPConnection)

– Define a interface de interesse dos clientes;

– Mant´em uma instˆancia do ConcreteState que define o estado atual do con-texto.

• State (TCPState): Define uma interface que encapsula o comportamento associado a um estado particular do contexto.

• ConcreteState subclasses (TCPEstablished, TCPListen, TCPClosed): Cada sub-classe implementa o comportamento associado com o estado do contexto que ela representa.

O Context delega requisic¸˜oes espec´ıficas de estado ao ConcreteState atual e, ainda, pode passar ele pr´oprio como argumento para o objeto State atendendo a requisic¸˜ao. O Context ´e a interface prim´aria para clientes. Clientes configuram o Context com objetos State.

O Context ou as subclasses ConcreteState podem decidir qual estado sucede outro e em quais circunstˆancias. Como consequˆencias temos:

(14)

• Localiza o comportamento espec´ıfico para os diferentes estados; • Faz com que as transic¸˜oes se tornem expl´ıcitas;

• Objetos State podem ser compartilhados. O padr˜ao ´e indicado nos seguintes casos:

• Quando o comportamento do objeto depende do seu estado e este comportamento deve ser modificado em run-time;

• Quando os m´etodos possuem sentenc¸as condicionais grandes e com v´arias opc¸˜oes. O padr˜ao State coloca cada ramo da sentenc¸a condicional em uma classe separada. 3.9. Strategy

Definir uma fam´ılia de algoritmos, encapsular cada um e torn´a-los intercambi´aveis. Es-trat´egia permite que o algoritmo varie independentemente dos clientes que o utilizam.

Existem muitos algoritmos para quebrar um fluxo de texto em linhas.

N˜ao ´e desej´avel acoplar estes algoritmos para as classes que necessitam deles.

Figura 10. Strategy Pattern

A figura 10 representa a estrutura do padr˜ao e tem os seguintes participantes: • Strategy (Compositor)

– Declara uma interface comum a todos os algoritmos suportados;

– O Context utiliza esta interface para chamar um algoritmo definido por um ConcreteStrategy.

• ConcreteStrategy (SimpleCompositor, TeXCompositor, ArrayCompositor): Im-plementa o algoritmo utilizando a interface Strategy.

• Context (Composition)

– ´E configurado com um ConcreteStrategy; – Mant´em uma referˆencia para o objeto Strategy;

– Pode definir uma interface que permite que os ConcreteStrategies acessem seus dados;

O Strategy e o Context interagem para implementar o algoritmo escolhido. O Context pode passar todos os dados necess´arios `a execuc¸˜ao do algoritmo ou o Context passa ele pr´oprio como argumento da operac¸˜ao, permitindo que o Strategy consulte os dados necess´arios.

(15)

Um Context repassa requisic¸˜oes do cliente para o seu Strategy. O cliente geral-mente cria e configura o Context com um ConcreteStrategy e passa a interageir sogeral-mente com o Context.

Como consequˆencias temos:

• Fam´ılia de algoritmos relacionados;

• Uma alternativa a sub-classing. Pode-se derivar o Contexto para prover diferentes implementac¸˜oes;

• As Strategies eliminam declarac¸˜oes condicionais. O padr˜ao ´e indicado nos seguintes casos:

• Quando muitas classes relacionadas diferem somente no seu comportamento; • Quando ´e necess´ario utilizar diferentes variac¸˜oes de um algoritmo;

• Quando um algoritmo utiliza dados que n˜ao devem estar expostos aos clientes; • Quando uma classe define m´ultiplos comportamentos atrav´es de sentenc¸as

condi-cionais em seus m´etodos. 3.10. Template Method

Definir o esqueleto de um algoritmo em uma operac¸˜ao, adiando alguns passos para sub-classes. Template Method permite que subclasses redefinam determinadas etapas de um algoritmo sem alterar a estrutura do algoritmo.

A ideia fundamental desse padr˜ao ´e definir a ordem de execuc¸˜ao dos passos que resolvem um determinado problema e permitir que cada passo possa ser implementado de maneiras diferentes.[K19 2012]

Figura 11. Template Method Pattern

A figura 11 representa a estrutura do padr˜ao e tem os seguintes participantes: • AbstractClass (Application)

– Declara operac¸˜oes primitivas abstratas a serem definidas por sub-classes ao implementar os passos do algoritmo;

– Implementa o Template Method definindo o arcabouc¸o do algoritmo. Este Template Method invoca tanto as operac¸˜oes primitivas quanto operac¸˜oes concretas de AbstractClass ou de outros objetos.

(16)

• ConcreteClass (MyApplication): Implementa as operac¸˜oes primitivas, executando os passos do algoritmo espec´ıficos desta subclasse.

ConcreteClass depende de AbstractClass para implementar as medidas invariantes do algoritmo.

Como consequˆencias temos:

• Template Methods ´e uma t´ecnica fundamental para a reutilizac¸˜ao de c´odigo. Esta t´ecnica ´e particularmente importante em bibliotecas de classes, porque ela ´e o meio para fabricar um comportamento comum em classes de bibliotecas.

• Template Methods podem invocar os seguintes tipos de m´etodos:

– Operac¸˜oes concretas (da sua pr´opria classe ou de outros objetos); – Operac¸˜oes primitivas (m´etodos abstratos);

– Factory Methods;

– M´etodos hook (m´etodos de AbstractClass com implementac¸˜oes default mas que podem ser sobrepostos pelas sub-classes).

O padr˜ao ´e indicado nos seguintes casos:

• Implementac¸˜ao ´unica das partes invariantes de um algoritmo e deixar que subclas-ses implementem o comportamento que varia;

• Quando um comportamento comum entre subclasses deve ser fatorado e locali-zado em uma classe comum, com o objetivo de evitar repetic¸˜ao de c´odigo;

• Para controlar as extens˜oes realizadas pelas subclasses. O Template Method pode definir operac¸˜oes hook em pontos espec´ıficos e, portanto, permitindo variac¸˜oes somente nestes locais.

3.11. Visitor

Representar uma operac¸˜ao a ser realizada sobre os elementos de uma estrutura de objeto. Visitor permite que vocˆe defina uma nova operac¸˜ao sem mudar as classes dos elementos sobre os quais opera.

Permite atualizac¸˜oes espec´ıficas em uma colec¸˜ao de objetos de acordo com o tipo particular de cada objeto atualizado.[K19 2012]

A figura 12 representa a estrutura do padr˜ao e tem os seguintes participantes: • Visitor (NodeVisitor)

– Declara uma operac¸˜ao visit() para cada classe de ConcreteElemente pre-sente no agregado;

– O nome e a assinatura da operac¸˜ao visit() identifica a classe que solicita a execuc¸˜ao do visit() no Visitor;

– Isto permite que o Visitor determine a classe concreta do elemento sendo visitado e se comunique diretamente com ele.

• ConcreteVisitor (TypeCheckingVisitor)

– Implementa cada operac¸˜ao declarada no Visitor;

– Cada operac¸˜ao implementa o fragmento do algoritmo espec´ıfico da classe em quest˜ao;

(17)

Figura 12. Visitor Pattern

– O ConcreteVisitor disponibiliza o contexto para o algoritmo e geralmente armazena estado local que acumula resultados durante a varredura do agre-gado.

• Element (Node): Declara a operac¸˜ao accept() que recebe o visitor como parˆametro.

• ConcreteElement (AssignmentNode,VariableRefNode): Implementa a operac¸˜ao accept().

• ObjectStructure (Program)

– Pode enumerar seus elementos;

– Pode disponibilizar uma interface de alto n´ıvel para permitir que o Visitor visite seus elementos;

– Pode ser ou um Composite ou uma collection como uma lista ou conjunto. Um cliente que usa o padr˜ao Visitor deve criar um objeto ConcreteVisitor e, em seguida, atravessar a estrutura do objeto, visitando cada elemento.

Quando um elemento ´e visitado, ele chama a operac¸˜ao o Visitor que corresponde a sua classe.

O elemento em si fornece ´e um argumento para esta operac¸˜ao para deixar seu estado ao Visitor, se necess´ario.

Como consequˆencias temos:

• O Visitor torna f´acil a adic¸˜ao de novas operac¸˜oes;

• O Visitor agrupa operac¸˜oes relacionadas e separa as n˜ao-relacionadas; • O Visitor torna dif´ıcil a adic¸˜ao de novos ConcreteElements;

• Com o Visitor os objetos visitados n˜ao precisam ter um ancestral comum;

• Acumulando estado. Visitors podem acumular estado `a medida em que visitam os elementos. Sem o Visitor este estado seria passado como parˆametro das operac¸˜oes que realizam a varredura ou declarado atrav´es de vari´aveis globais;

(18)

• Quebrando o encapsulamento. Ao utilizar o Visitor assume-se que a interface do ConcreteElement ´e poderosa o suficiente para permitir que o Visitor fac¸a o seu trabalho.

O padr˜ao ´e indicado nos seguintes casos:

• Quando um agregado cont´em objetos de diversas classes (com diferentes interfa-ces) e deseja-se realizar operac¸˜oes nestes objetos que dependem das suas classes concretas;

• Quando muitas operac¸˜oes distintas e n˜ao relacionadas precisam ser aplicadas a um agregado e n˜ao se deseja poluir as classes dos objetos do agregado com tais operac¸˜oes;

• Quando as classes que definem os objetos do agregado raramente mudam, por´em definem-se novas operac¸˜oes com certa frequˆencia.

4. Conclus˜ao

Padr˜oes de projeto s˜ao otimizados, sendo as soluc¸˜oes reutiliz´aveis para os problemas de programac¸˜ao que nos deparamos todos os dias. Um padr˜ao de design n˜ao ´e uma classe ou uma biblioteca que podemos simplesmente plugar em nosso software; ´e muito mais do que isso. ´E um molde que tem de ser aplicada na situac¸˜ao correta. Tamb´em n˜ao ´e espec´ıfico de linguagem. Um padr˜ao de design bom deve ser implement´avel na maioria (se n˜ao em todas) as linguagens, dependendo de seus recursos. Ainda, qualquer padr˜ao de design pode ser uma faca de dois gumes, pois se implementado no lugar errado pode ser desastrosa e criar muitos problemas. No entanto, implementado no lugar certo, na hora certa, ele pode ser a soluc¸˜ao.[Bautista 2010]

Design patterns devem ter seu uso planejado, devemos lembrar sempre da m´axima:

Se est´as com dor de cabec¸a, n˜ao ir´as tomar dez comprimidos de dorflex!

4.1. Trabalhos futuros

Design de software n˜ao ´e limitado `a arquitetura e estruturas, podem ser aplicados `a forma que o c´odigo ´e escrito, organizado, sua legibilidade e complexidade.

• Anti-patterns: s˜ao determinados padr˜oes de desenvolvimento de software que s˜ao considerados uma m´a pr´atica de programac¸˜ao.

• Refactoring Com a refatorac¸˜ao, os programadores podem transformar at´e mesmo o software mais ca´otico em sistemas bem desenhados que s˜ao muito mais f´aceis de evoluir e manter. Refatorac¸˜ao ´e uma t´ecnica controlada para melhorar o de-senho de uma base de c´odigo existente. Sua essˆencia ´e a aplicac¸˜ao de uma s´erie de pequenas transformac¸˜oes que preservam o comportamento, refatorac¸˜ao ´e est´ar aperfeic¸oando a qualidade do c´odigo.

Referˆencias

Alexander, C., Ishikawa, S., Silverstein, M., Jacobson, M., Fiksdahl-King, I., and Angel, S. (1977). A Pattern Language. Oxford University Press.

(19)

Gamma, E., Helm, R., Johnson, R., and Vlissides, J. (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Pearson Education.

K19 (2012). Design Patterns em Java.

Silveira, P., Silveira, G., Lopes, S., Moreira, G., Steppat, N., and Kung, F. Introduc¸˜ao ´a Arquitetura de Design de Software. Elsevier Brasil.

Referências

Documentos relacionados

O método propriamente dito de um trabalho científico só pode ser estabelecido depois que o objetivo tiver sido definido. Por esse motivo, no caso da Computação, normalmente a revisão

Muitas vezes as crianças aprendem as letras, sílabas e as palavras sem sentido, mas não entendem o que escrevem, não é considerado alfabetizado, pois a escrita é considerada

Terreri, Greve e Amatuzzi (2001, p.63) corroboram com a importância da dinamometira isocinética para a avaliação e tratamento de lesões, quando citam em seu estudo

II - os docentes efetivos, com regime de trabalho de 20 (vinte) horas semanais, terão sua carga horária alocada, preferencialmente, para ministrar aulas, sendo o mínimo de 8 (oito)

A microrregião deste grupo de maior participação no PIB real agropecuário de Minas Gerais foi Passos, com 1,89% do PIB agropecuário do estado em 2003, o que mostra que

Objective: Analize data on patients submitted to transfer of the pronator teres (PT) or the flexor carpi ulnaris (FCB) to the ex- tensor carpi radialis longus/brevis (ECRL/B) in

ATRIBUIÇÕES: prestar assistência dietética e promover educação nutricional a indivíduos sadios ou enfermos em nível hospitalar ou ambulatorial, visando a promoção,

Dos 37 espécimes submetidos à extração e sequenciamento de DNA, 32 geraram sequências capazes de serem analisadas para os marcadores - primeiro e segundo espaçador transcrito