User talk:Murillocintra

1. Padrões de projeto Introdução (Segundo Erich Gamma e estudos feitos pela UNIVERSIDADE FEDERAL DE SANTA CATARINA.) Os padrões de projeto de software ou padrões de desenho de software, também muito conhecido pelo termo original em inglês: Design Patterns, descreve soluções para problemas recorrentes no desenvolvimento de sistemas de software orientados a objetos. Um padrão de projeto estabelece um nome e define o problema, a solução, quando aplicar esta solução e suas conseqüências. Os padrões de projeto visam facilitar a reutilização de soluções de desenho - isto é, soluções na fase de projeto do software, sem considerar reutilização de código. Também acarretam um vocabulário comum de desenho, facilitando comunicação, documentação e aprendizado dos sistemas de software. Projetar software orientado a objetos é difícil, mas projetar software reutilizável orientado a objetos é ainda mais complicado. Você deve identificar objetos pertinentes, faturá-los em classes no nível correto de granularidade, definir as interfaces das classes, as hierarquias de herança e estabelecer relações entre eles. 1.1	O que é um padrão de projeto?

Em uma definição mais formal: ”padrões para arquitetura de software são soluções de eficiência já comprovadas e amplamente utilizadas para a resolução de problemas comuns em projeto de software. Estas soluções são desenvolvidas e conhecidas por especialistas e tornam-se padrões por serem reutilizadas varias vezes em vários projetos e por terem eficácia comprovada.” (Citado por ALEXANDER, C., ISHIKAWA, S., SILVERSTEIN, M., JACOBSON, M., FIKSDAHL-KING, I., ANGEL, S. "A Pattern Language". New York, NY (USA): Oxford University Press, 1977.) Em geral, um padrão tem quatro elementos essenciais: Nome: descreve a essência do padrão. Problema (motivação, intenção e objetivos, aplicabilidade): apresenta o contexto do padrão e quando ele pode ser usado. Solução (estrutura, participantes, exemplo de código): descreve a solução e os elementos que a compõem. Conseqüências e padrões relacionados: analisa os resultados, vantagens e desvantagens obtidas com a aplicação do padrão. (citado por Erich Gamma e os estudos da UNIVERSIDADE FEDERAL DE SANTA CATARINA)

Como selecionar um padrão de projeto?

Considere como os padrões de projeto solucionam problemas de projeto. Examine as seções de descrição do problema de cada padrão. Estude como os padrões se relacionam. Estude padrões de finalidades semelhantes .Examine uma causa de reformulação de projeto. Considere o que deveria ser variável no seu projeto. (Citado no Livro base: Padrões de projeto: Soluções Reutilizáveisde Software Orientado a Objetos - “The Gang of Four”.)

1.2 Padrões de projeto no MVC de Smalltalk (Segundo Erich Gamma e Trygve M. H. Reenskaug) A tríade de classes Modelo/Visão/controlador (Model-View-controller) (MVC, [KP88]) é usada para construir interfaces com o usuário em Smalltalk -80. Observar os padrões de projeto dentro do MVC ajudará a perceber o que queremos dizer com o termo “padrão”. A abordagem MVC é composta por três tipos de objetos. O modelo é o objeto de aplicação, a visão é a apresentação na tela e o controlador é o que define a maneira como a interface do usuário reage às entradas do mesmo. Antes de MVC, os projetos de interface para o usuário tendiam a agrupar esses objetos.A MVC separa esses objetos para aumentar a flexibilidade e a reutilização. Model-view-controller (MVC) é um padrão de arquitetura de software. Com o aumento da complexidade das aplicações desenvolvidas torna-se fundamental a separação entre os dados (Model) e o layout (View). Desta forma, alterações feitas no layout não afectam a manipulação de dados, e estes poderão ser reorganizados sem alterar o layout.

Um diagrama simples exemplificando a relação entre Model, View e Controller. Obs.: as linhas sólidas indicam associação direta e as tracejadas indicam associação indireta. O modelo (model) é usado para definir e gerenciar o domínio da informação e notificar observadores sobre mudanças nos dados. Ele é uma representação detalhada da informação que a aplicação opera. A lógica de negócio adiciona valor semântico aos dados, e quando há mudança de estado o modelo notifica seus observadores. Por exemplo, aluno, professor e turma fazem parte do domínio de um sistema acadêmico. Operações como calcular a média final do aluno ou o índice de faltas da turma fazem parte da lógica de domínio. A forma como o dado é armazenado ou acessado não é de interesse do MVC, assume-se que é de responsabilidade do modelo. A visão (view) apresenta o modelo num formato adequado ao utilizador, na saída de dados, e diferentes visões podem existir para um mesmo modelo, para diferentes propósitos. O controlador (controller) recebe a entrada de dados e inicia a resposta ao utilizador ao invocar objetos do modelo, e por fim uma visão baseada na entrada. Ele também é responsável pela validação e filtragem da entrada de dados. Um caso prático é uma aplicação web em que a visão é um documento HTML (ou derivado) gerado pela aplicação. O controlador recebe uma entrada GET ou POST após um estímulo do utilizador e decide como processá-la, invocando objetos do domínio para tratar a lógica de negócio, e por fim invocando uma visão para apresentar a saída. Com o aumento da complexidade das aplicações desenvolvidas, torna-se relevante a separação entre os dados e a apresentação das aplicações. Desta forma, alterações feitas no layout não afetam a manipulação de dados, e estes poderão ser reorganizados sem alterar o layout. Esse padrão resolve este problema através da separação das tarefas de acesso aos dados e lógica de negócio, lógica de apresentação e de interação com o utilizador, introduzindo um componente entre os dois, o controlador. 1.3 Descrevendo os padrões de projeto Neste tópico veremos como descrever um padrão de projeto. Anotações gráficas, apesar de muito importantes, não são suficientes. Para reutilizar uma decisão de projeto nós devemos registrar as decisões, alternativas, vantagens e desvantagens. Para ajudar a ver a mplementação em uso devemos utilizar exemplos concretos. A seguir veremos um formato consistente de descrever um padrão segundo Erich Gamma: • Nome e classificação do padrão: O nome do padrão refere-se à essência do padrão. A classificação do padrão reflete o tipo do padrão, iremos introduzir a classificação do padrão na próxima seção. • Intenção do padrão: Um parágrafo que responda as seguintes perguntas; O que o padrão faz? Qual é a intenção do padrão? Qual problema em particular ele resolve? • Também conhecido como: Outros nomes bem conhecidos para o padrão, se existir. • Motivação: Um cenário ilustrando um problema de projeto e como a estrutura de objetos e Classe no padrão resolve o problema. • Aplicabilidade: Em quais situações o padrão pode ser aplicado? Descrever exemplos de implementações pobres em que o padrão pode ser aplicado. Como você pode reconhecer estas situações? • Estrutura: Uma representação gráfica das classes utilizadas no padrão. A linguagem UML [4] é utilizada para representar graficamente um padrão, ela Tem contribuído bastante para o aumento da comunidade de Padrões de projetos. Conceitos como cenários, iterações entre classes, iteração de interfaces de objetos e estados de objetos podem todos ser escritos em UML. Esta linguagem Está além do escopo deste trabalho. Existem excelentes referências de UML [4][5][6][7]. • Participantes: As classes e/ou objetos que participam da implementação e suas responsabilidades. • Colaborações: Como os participantes colaboram para realizar suas responsabilidades. • Conseqüências: Mostra como o padrão reage e seus objetivos. Apresentam quais são os resultados, as Vantagens e desvantagens de utilizar o padrão. • Implementação: Quais armadilhas ou técnicas devem ser evitadas durante a implementação do padrão? Existe algum ponto especifico para alguma linguagem? • Exemplo de Código: Fragmento de código em alguma linguagem para ilustrar como deve ser implementado o padrão. • Usos conhecidos: Exemplos de uso do padrão em sistemas reais. • Padrões Relacionados: Quais padrões estão intimamente relacionados com este? Quais são as principais diferenças? Este padrão deve ser utilizado com quais outros? 1.4 O catálogo de padrões de projeto Abstract Factory é um padrão de projeto de software (também conhecido como design pattern em inglês). Este padrão permite a criação de famílias de objetos relacionados ou dependentes, através de uma única interface e sem que a classe concreta seja pecificada. Adapter, também conhecido como Wrapper, é um padrão de projeto de software ou de desenho (do inglês design pattern). Este padrão é utilizado para 'adaptar' a interface de uma classe. O Adapter permite que classes com interfaces incompatíveis possam interagir. Permite que um objeto cliente utilize serviços de outros objetos com interfaces diferentes por meio de uma interface única. Bridge é um padrão de projeto de software, ou design pattern em inglês, utilizado quando é desejável que uma interface (abstração) possa variar independentemente das suas implementações. Builder é um padrão de projeto de software que permite a separação da construção de um objeto complexo da sua representação, de forma que o mesmo processo de construção possa criar diferentes representações. Chain of Responsibility representa um encadeamento de objetos receptores para o processamento de uma série de solicitações diferentes. Esses objetos receptores passam a solicitação ao longo da cadeia até que um ou vários objetos a tratem. Command Encapsula uma solicitação como um objeto, desta forma permitindo que clientes parametrizem diferentes solicitações, enfileirem ou façam o registro (log) de solicitações e suportem operações que podem ser desfeitas Composite é um padrão de projeto de software utilizado para representar um objeto que é constituído pela composição de objetos similares a ele. Neste padrão, o objeto composto possui um conjunto de outros objetos que estão na mesma hierarquia de classes a que ele pertence. Decorator :Atribui responsabilidades adicionais adicionais a um objeto dinamicamente os decorators fornecem um alternativa flexível a subclasses para extensão da funcionalidade. Façade é um padrão de projeto (design pattern) do tipo estrutural. Os façades são muito comuns em projeto orientados a objeto. Factory Method é um padrão de projeto de software (design pattern, em inglês) que fornece uma interface para criação de famílias de objetos relacionados ou dependentes, sem especificar suas classes concretas. O factory method permite adiar a instanciação para as subclasses. Flyweight é um padrão de projeto de software apropriado quando vários objetos devem ser manipulados, e esses não suportam dados adicionais. No padrão flyweight não existem ponteiros para os métodos do dado, pois isto consome muita memória. Em contrapartida são chamadas sub-rotinas diretamente para acessar o dado. Interpreter: Dada uma linguagem,define uma representação para sua gramática juntamente com um interpretador que usa a representação para interpretar sentenças nessa linguagem. Iterator permite a "iteração" e um modo de acesso a elementos de um agregado de objetos, sequencialmente, sem exposição de estruturas internas. Mediador é quem desacopla e gerencia as colaborações entre um grupo de objetos. Define um objeto que encapsula as interações dentre desse grupo. Momento: Sem violar o encapsulamento,captura e externaliza um estado interno de um objeto,de  modo que os mesmo possa posteriormente ser restauado para este estado. Observer é um padrão de projeto de software que define uma dependência um-para-muitos entre objetos de modo que quando um objeto muda o estado, todos seus dependentes sejam notificados e atualizados automaticamente. Permite que objetos interessados sejam avisados da mudança de estado ou outros eventos ocorrendo num outro objeto. Prototype, é um padrão de projeto de software (design pattern, em inglês) que permite a criação de objetos a partir de um modelo original, ou protótipo. Proxy: Fornece um objeto representante (surrogate), ou um marcador de outro objeto, para controlar o acesso ao mesmo. Singleton é um padrão de projeto de software (do inglês Design Pattern). Este padrão garante a existência de apenas uma instância de uma classe, mantendo um ponto global de acesso ao seu objeto. State: Permite que um objeto altere seu comportamento quando seu estado interno muda.O objeto parecerá ter mudado de classe. Strategy é um padrão de projeto de software (do inglês design pattern). O objetivo é representar uma operação a ser realizada sobre os elementos de uma estrutura de objectos. O padrão Visitor permite definir novas operações sem alterar as classes dos elementos sobre os quais opera. Definir uma família de algoritmos e encapsular cada algoritmo como uma classe, permitindo assim que elas possam ter trocados entre si. Este padrão permite que o algoritmo possa variar independentemente dos clientes que o utilizam. Template Method auxilia na definição de um algoritmo com partes dos mesmos definidos por Método abstratos. As subclasses devem se responsabilizar por estas partes abstratas, deste algoritmo, que serão implementadas, possivelmente de várias formas, ou seja, cada subclasse irá implementar à sua necessidade e oferecer um comportamento concreto construindo todo o algoritmo. Visitor: Representa uma operação a ser executada sobre os elementos da estrutura sobre os elementos da estrutura de um objeto.O Visitor permite que você defina uma nova operação sem mudar as classes dos elementos sobre os quais opera. (citado por Erich Gamma, Richard Helm, Ralph Johnson, John Vlisside ,METSKER, Steven John, FOWLER, Martin. ) 1.5 Organizando o catálogo (Segundo Erich Gamma ) Os padrões de projeto variam na sua granularidade e no seu nível de abstração. Como existem muitos padrões de projeto, precisamos organizá-los. A classificação ajuda a aprender os padrões mais rapidamente, bem como direcionar esforços na descoberta de novos. Os padrões de projeto são classificados por dois critérios: O primeiro critério, chamado finalidade, reflete o que o padrão faz. Os padrões podem ter finalidade de criação, estrutural ou comportamental. Os padrões de criação se preocupam com o processo de criação de objetos. Os padrões estruturais lidam com a composição de classes ou de objetos. Os padrões comportamentais caracterizam as maneiras pelas quais classes ou objetos interagem e distribuem responsabilidades. O segundo critério, chamado escopo, especifica se o padrão se aplica primariamente a classes ou a objetos. Os padrões para classes lidam com os relacionamentos entre classes e suas subclasses. Esses relacionamentos são estabelecidos através do mecanismo de herança, assim eles são estáticos. Os padrões para objetos lidam com relacionamentos entre objetos que podem ser mudados em tempo de execução e são mais dinâmicos. Quase todos utilizam a herança em certa medida.

Propósito De criação	Estrutural	Comportamental Escopo	Classe	Factory Method	Adapter	Interpreter Template Method Objeto	Abstract Factory Builder Prototype Singleton	Adapter Bridge Composite Decorator Façade Flyweight Proxy	Chain of Responsibility Command Iterator Mediator Memento Observer State Strategy Visitor Os padrões de criação voltados para classes deixam alguma parte da criação de objetos para subclasses, enquanto que os padrões de criação voltados para objetos postergam esse processo para outro objeto. Os padrões estruturais voltados para classes utilizam a herança para compor classes, enquanto que os padrões estruturais voltados para objetos descrevem maneiras de montar objetos. Os padrões comportamentais voltados para classes usam a herança para descrever algoritmos e fluxo de controle, enquanto que os voltados para objetos descrevem como um grupo de objetos coopera para executar uma tarefa que um único objeto não pode executar sozinho. Há outras maneiras de organizar os padrões. Alguns padrões são freqüentemente usados em conjunto. Por exemplo: o Composite é freqüentemente usado com o Iterator ou o Visitor. Alguns padrões são alternativos: o Prototype é uma alternativa para o Abstract Factory. Alguns padrões resultam em projetos semelhantes, embora tenham intenções diferentes. Por exemplo: os diagramas de estrutura de Composite e Decorator são semelhantes. Existem muitas maneiras de organizar os padrões de projeto. Ter múltiplas maneiras de pensar a respeito deles aprofundará sua percepção sobre o que fazem como se comparam e como aplicá-los. Os próximos artigos estarão dissecando cada um dos 23 padrões de projetos com pequenos trechos de código em Visual Basic. NET exemplificando os mesmos. Seguindo a ordem padrões de criação, padrões estruturais e padrões comportamentais, o primeiro padrão a ser detalhado será o Abstract Factory. 1.6 Como os padrões solucionam problemas de projeto (segundo Erich Gamma e a UNIVERSIDADE FEDERAL DE SANTA CATARINA.) Os padrões de projeto solucionam muitos dos problemas que os projetistas enfrentam no dia a dia, e de muitas maneiras diferentes.Aqui apresentamos vários desses problemas e como os padrões de projeto os solucionam. 1.6.1Procurando objetos apropriados Programas orientados a objetos são feitos de objetos. Um objeto empacota tanto os dados quando os procedimentos que operam sobre eles. Os procedimentos são tipicamente chamados de métodos ou operações. Um objeto executa uma operação quando ele recebe uma solicitação de um cliente. As solicitações (request) são a única maneira de conseguir que um objeto execute uma operação. As operações são a única maneira de mudar os dados internos de um objeto. Por causa destas restrições, diz-se que o estado interno de um objeto esta encapsulado; ele não pode ser acessado diretamente e a representação é invisível do exterior do objeto. Os padrões de projeto ajudam a identificar abstrações menos obvias bem como os objetos que podem capturá-las. Por exemplo, objetos que representam um processo ou algoritmo não ocorrem na natureza, no entanto, eles são uma parte crucial de projetos flexíveis. O padrão Strategy descreve como implementar famílias de algoritmos intercambiáveis.O padrão State representa cada estado de uma entidade como um objeto. 1.6.2 Determinando a granularidade dos objetos Os objetos podem variar tremendamente em tamanho e número. Podem repre-Sentar qualquer coisa indo para baixo, até o nível do hardware, ou seguindo todo o Caminha para cima, até chegarmos a aplicações inteiras. Como decidimos o que Deve ser um objeto? O padrão Fachada, por exemplo, descreve como representar subsistemas Completos como objetos e o padrão Flyweigth descreve como suportar enormes quantidades de objetos nos níveis de granularidade mais finos. Outros padrões escrevem maneiras específicas de decompor um objeto em objetos menores; 1.6.3 Especificando interfaces de objetos

Cada operação declarada por um objeto especifica o nome da operação, os objetos que ela aceita como parâmetros e o valor retornado por ela. Isto é conhecido como assinatura da operação. O conjunto de todas as assinaturas definido pelas operações de um objeto é chamado de interface do objeto. A interface de um objeto caracteriza o conjunto completo de solicitações que podem ser enviadas para o mesmo. Qualquer solicitação que corresponde a uma assinatura na interface do objeto pode ser enviada para o mesmo. Um tipo é um nome usado para denotar uma interface específica. Quando dizemos que um objeto tem um tipo “Janela”, significa que ele aceita todas as Solicitações para as operações definidas na interface chamada “Janela”. Um objeto Pode ter muitos tipos, assim como objetos muito diferentes podem compartilhar um Mesmo tipo. Parte da interface de um objeto pode ser caracterizada por um tipo, e Outras partes por outros tipos. Dois objetos do mesmo tipo necessitam compartilhar Somente partes de suas interfaces. As interfaces podem conter outras interfaces Como subconjuntos. Dizemos que um tipo é um subtipo de outro se sua interface contém a interface do seu supertipo. Freqüentemente dizemos que um subtipo herda a interface do seu supertipo. As interfaces são fundamentais em sistemas orientados a objetos. Os objetos são conhecidos somente através das suas interfaces. Não existe nenhuma maneira de saber algo sobre um objeto ou de pedir que faça algo sem intermédio de sua interface. A interface de um objeto nada diz sobre sua implementação – diferentes objetos estão livres para implementar as solicitações de diferentes maneiras. Isso significa que dois objetos que tenham implementações completamente diferentes podem ter interfaces idênticas. Quando uma mensagem é enviada a um objeto, a operação específica que será executada depende de ambos – mensagem e objeto receptor. Diferentes objetos, que suportam solicitações idênticas, podem ter diferentes implementações das operações que atendem a estas solicitações. A associação em tempo de execução de uma solicitação a um objeto e a uma das suas operações é conhecida como ligação dinâmica (dynamic binding). A ligação dinâmica significa que o envio de uma solicitação não prenderá você a uma particular implementação até o tempo de execução. Conseqüentemente, você poderá escrever programas que esperam um objeto com uma interface em particular, sabendo que qualquer objeto que tenha a interface correta aceitará a solicitação. Além do mais, a ligação dinâmica permite substituir objetos que tenham interfaces idênticas uns pelos outros. Esta capacidade de substituição é conhecida como polimorfismo e é um conceito-chave em sistemas orientados a objetos. Ela permite a um objeto-cliente criar poucas hipóteses sobre outros objetos, exceto que eles suportam uma interface específica. Polimorfismo simplifica as definições dosclientes, desacopla objetos entre si e permite a eles variarem seus inter-relacionamentos em tempo de execução. Os padrões de projeto ajudam a definir interfaces pela identificação de seus elementos-chave e pelos tipos de dados que são enviados através de uma interface. Um padrão de projeto também pode lhe dizer o que não colocar na interface. Por exemplo, o padrão Memento descreve como encapsular e salvar o estado interno de um objeto de modo que o objeto possa ser restaurado àquele estado mais tarde. Os padrões de projeto também especificam relacionamentos entre interfaces.Em particular, freqüentemente exigem que algumas classes tenham interfaces Similares, ou colocam restrições sobre interfaces de algumas classes. 1.6.4 Especificando implementações de objetos Uma implementação de um objeto é definida por sua classe. A classe especifica os dados internos do objeto e de sua representação e define as operações que o objeto pode executar. Objetos são criados por instanciação de uma classe. Diz-se que o objeto é uma instância da classe. O processo de instanciar uma classe aloca memória para os dados internos do objeto (compostos de variáveis de instância) e associa as operações a estes dados. Muitas instâncias semelhantes de um objeto podem ser criadas pela instanciação de uma classe. Novas classes podem ser definidas em termos das classes existentes usando-se herança de classe. Quando uma subclasse herda de uma classe-mãe, ela inclui as definições de todos os dados e operações que a classe-mãe define. Os objetos que são instâncias das classes conterão todos os dados definidos pela subclasse e suas classes-mãe. Eles serão capazes de executar todas as operações definidas por esta subclasse e seus “ancestrais”. Uma classe abstrata é uma classe cuja finalidade principal é definir uma interface comum para suas subclasses. Uma classe abstrata postergará parte de, ou toda, sua implementação para operações definidas em subclasses, portanto, uma classe abstrata não pode ser instanciada. As operações que uma classe abstrata declara, mas não implementa são chamadas operações abstratas. As classes que não são abstratas são chamadas de classes concretas. As subclasses podem refinar e redefinir comportamentos de suas classes ancestrais (mãe, avó, etc.). Mais especificamente, uma classe pode redefinir uma operação definida por sua classe-mãe. A redefinição dá às subclasses a oportunidade de tratar solicitações em lugar das suas classes ancestrais. A herança de classe permite definir classes simplesmente estendendo outras classes, tornando fácil definir famílias de objetos que têm funcionalidades relacionadas. Aqui é importante compreender a diferença entre herança de classe e herança de interface. A herança de classe define a implementação de um objeto em termos da implementação de outro objeto. Resumidamente, é um mecanismo para compartilhamento de código e de representação. Diferentemente disso, a herança de interface descreve quando um objeto pode ser usado no lugar de outro. 1.6.5 Herança de classes versus Herança de interface A classe de um objeto define como ele e implementado.A classe define como o estado interno do objeto e a implementação de suas operações.Em contraste a isso,o tipo de um objeto se refere somente à sua interface – o conjunto de solicitações às quais ele pode responder.um objeto pode ter muitos tipos,e objetos de diferentes classes podem ter o mesmo tipo. É importante compreender a diferença entre herança de classe e herança de interface.A herança de classe define a implementação de um objeto em termos da implementação de outro objeto e a herança de interface descreve quando um objeto pode ser usado no lugar de outro. Muitos dos padrões de projeto dependem desta distinção.Por exemplo,os objetos numa chain of Responsibility devem ter um tipo em comum,mas usualmente não compartilham uma implementação.No padrão composite,o component define uma interface comum,porém composite define uma implementação em comum.O command,o Observer,o State e  o Strategy são frequentemente implementados com classes abstratas que são puramente interfaces. 1.6.6Programando para uma interface, não para uma implementação A herança de classe é basicamente um mecanismo para estender a funcionalidade de uma aplicação pela reutilização da funcionalidade das classes ancestrais, permitindo definir rapidamente um novo tipo de objeto em termos de um existente. Ela permite obter novas implementações quase de graça, herdando a maior parte do que você necessita de classes existentes. Contudo, a habilidade da herança para definir famílias de objetos com interfaces idênticas (usualmente por herança de uma classe abstrata) também é importante, pois quando a herança é usada apropriadamente, todas as classes derivadas de uma classe abstrata compartilharão sua interface. Isto implica que uma subclasse meramente acrescenta ou substitui operações da classe mãe, e não oculta operações dela. Todas as subclasses podem então responder a solicitações na interface desta classe abstrata, tornando-se, todas, subtipos da classe abstrata.Isto reduz grandemente as dependências de implementação entre subsistemas,favorecendo a reutilização. Baseado no que foi dito acima, não declare variáveis como instâncias de classes concretas específicas. Em vez disso, prenda-se somente a uma interface definida por uma classe abstrata. Naturalmente, você tem que instanciar classes concretas, isto é, especificar uma particular implementação em algum lugar do sistema, e os padrões de projeto permitem fazer exatamente isto, como por exemplo, os padrões Abstract Factoty, Builder e Singleton. Ao abstrair o processo de criação de objetos, estes padrões oferecem diferentes maneiras de associar uma interface com sua implementação de forma transparente no momento da instanciação. Os padrões de criação asseguram que seu sistema esteja escrito em termos de interfaces, não de implementações. 1.6.7 Colocando os mecanismos de reutilização para funcionar Muitas pessoas podem compreender conceitos como objetos,interfaces,classes e herança.O desafio reside em aplicá-los à construção de software flexível e reutilizável,e os padrões de projeto podem mostrar como fazê-lo. 1.6.8Herança versus composição As duas técnicas mais comuns para a reutilização de funcionalidades em sistemas orientados a objetos são a herança de classe e a composição de objetos. A reutilização por meio de subclasses é freqüentemente chamada de reutilização caixa branca (ou aberta), porque, com herança, os detalhes internos das classes ancestrais são freqüentemente visíveis para as subclasses. A composição de objetos é uma alternativa à herança de classe. Aqui, a nova funcionalidade é obtida pela montagem e/ou composição de objetos, para obter funcionalidades mais complexas. A composição de objetos requer que os objetos que estão sendo compostos tenham interfaces bem definidas. Este tipo de reutilização é chamado de reutilização caixa preto, porque os detalhes internos dos objetos não são visíveis. A herança e a composição têm cada uma, vantagens e desvantagens. A herança de classe é definida estaticamente em tempo de compilação e é simples de se usar, uma vez que é suportada diretamente pela linguagem de programação. A herança de classe também torna mais fácil modificar a implementação que está sendo reutilizada. Porém, a herança de classe tem algumas desvantagens. Em primeiro lugar, você não pode mudar as implementações herdadas das classes ancestrais em tempo de execução, porque a herança é definida em tempo de compilação. Em segundo lugar, e geralmente isso é o pior, as classes ancestrais reqüentemente definem pelo menos parte da representação física das suas subclasses. Porque a herança expõe para uma subclasse os detalhes da implementação dos seus ancestrais, freqüentemente é dito que a “herança viola o encapsulamento” [GAM 02 citando SNY 86]. A implementação de uma subclasse, desta forma, torna-se tão amarrada à implementação da sua classe-mãe que qualquer mudança desta forçará uma mudança naquela. As dependências de implementação podem causar problemas quando se está tentando reutilizar uma subclasse. Se algum aspecto da implementação herdada não for apropriado para novos domínios de problemas, a classe-mãe deve ser reescrita ou substituída por algo mais apropriado. Esta dependência limita a flexibilidade e, em última instância, a reusabilidade. Uma cura para isto é herdar somente de classes abstratas, uma vez que elas normalmente fornecem pouca ou nenhuma implementação. A composição de objetos é definida dinamicamente em tempo de execução pela obtenção de referências para outros objetos por um determinado objeto. A composição requer que os objetos respeitem as interfaces uns dos outros, o que por sua vez exige interfaces cuidadosamente projetadas, que não impeçam de você usar um objeto com muitos outros. Porém, existe um ganho. Como objetos são acessados exclusivamente através de suas interfaces, o encapsulamento não é violado. Qualquer objeto pode ser substituído por outro em tempo de execução, contanto que tenha o mesmo tipo. Além do mais, porque a implementação de um objeto será escrita em termos de interfaces de objetos, existem substancialmente menos dependências de implementação. Favorecer a composição de objetos em relação à herança de classes ajuda a manter cada classe encapsulada e focalizada em uma única tarefa. Suas classes e hierarquias de classes se manterão pequenas, com menor probabilidade de crescerem até se tornarem monstros intratáveis. Por outro lado, o projeto terá mais objetos (embora menos classes) e o comportamento do sistema dependerá de seus inter-relacionamentos ao invés de ser definido em uma classe. Idealmente, você não deveria ter que criar novos componentes para obter reutilização. Deveria ser capaz de conseguir toda a funcionalidade de que necessita simplesmente montando componentes existentes através da composição de objetos. Mas este raramente é o caso, porque o conjunto de componentes disponíveis nunca é exatamente rico o bastante na prática. A reutilização por herança torna mais fácil criar novos componentes que podem ser obtidos pela composição de componentes existentes. Assim, a herança e a composição de objetos trabalham juntas. A composição de objetos é aplicada repetidas vezes nos padrões de projeto.

1.6.9 Delegação

A delegação é uma maneira de tornar a composição de objetos tão poderosa para fins de reutilização como a herança [GAM 02 referenciando LIE 86, JZ 91]. Na delegação, dois objetos são envolvidos no tratamento de uma solicitação: um objeto receptor delega operações para o seu delegado. Para exemplificar, ao invés de fazer uma classe Janela uma subclasse de Retângulo (porque janelas são retangulares), a classe Janela deve reutilizar o comportamento de Retângulo, conservando uma variável de instância de Retângulo, e delegando o comportamento específico de Retângulo para ela. Em outras palavras, ao invés da classe Janela ser um Retângulo ela teria um Retângulo. Agora, Janela deve encaminhar as solicitações para a sua instância Retângula explicitamente, ao passo que antes teria herdado essas operações. A principal vantagem da delegação é que ela torna fácil compor comportamentos em tempo de execução e mudar a forma como são compostos. A classe Janela pode ter o formato circular em tempo de execução, simplesmente pela substituição da sua instância Retângula por uma instância de Circulo, assumindo-se que Retângulo e Circulo tenham o mesmo tipo. A delegação tem uma desvantagem que compartilha com outras técnicas que tornam o software mais flexível através da composição de objetos: o software dinâmico, altamente parametrizado, é mais difícil de compreender do que o software mais estático. A delegação é uma boa escolha de projeto somente quando ela simplifica mais do que complica e funciona melhor quando é usada baseada em padrões de projeto. Diversos padrões de projeto usam delegação, como por exemplo, o padrão Strategy. Neste padrão um objeto delega uma solicitação específica para um objeto quer representa uma estratégia para executar a solicitação. A delegação é um exemplo extremo da composição de objetos. Ela mostra se pode sempre substituir a herança pela composição de objetos como um mecanismo para a reutilização de código. 1.6.10 Herança versus tipos parametrizados Uma outra técnica para reutilização de funcionalidade é o uso de tipos parametrizados,também conhecido como generics e templates .Essa técnica permite definir um tipo sem especificar todos os outros tipos que ele usa.Os tipos não-especificados são fornecidos como parâmetros no ponto de utilização. Tipos parametrizados nos dão uma terceira maneira de efetuar a composição de comportamentos em sistemas orientados a objetos. Muitos podem ser implementados usando qualquer uma dessas três técnicas. Para parametrizar uma rotina de classificação pelo sistema que ela usa para comparar elementos, nós poderíamos fazer a comparação 1.Uma operação implementada por subclasses; 2.A responsabilidade de um objeto que é passado para uma rotina de classificação;ou 3.Um argumento de um template de C++ ou um generic em Ada que especifica o nome da função a ser chamada para comparar os elementos. Existem importantes diferenças entre essas técnicas. A composição de objetos permite mudar o comportamento que esta sendo composto em tempo de execução, mas ela também requer endereçamento indireto e pode ser menos eficiente. A herança permite fornecer implementações por falta (by default) para operações e deixa subclasses redefini-las. Os tipos parametrizados permitem mudar os tipos que uma classe pode usar. Porém, nem a herança nem os tipos parametrizados podem mudar em tempo de execução. A melhor abordagem depende do projeto e das restrições de implementação. 1.6.11 Relacionando estruturas de tempo de execução e compilação Considere a distinção entre agregação e associação de objetos e como diferentemente elas se manifestam nos tempos de compilação e execução. A agregação implica que um objeto possui, ou é responsável por, outro objeto. Geralmente dizemos que um objeto tem ou é parte de outro objeto. Agregação implica que um objeto agregado e seu proprietário têm idênticos tempos de vida. Associação implica que um objeto meramente tem conhecimento de outro objeto. Algumas vezes, é chamada de relacionamento ”usa”. Objetos que se conhecem podem solicitar operações uns dos outros, mas eles não são responsáveis um pelo outro. A associação é um relacionamento mais fraco do que a agregação e sugere um acoplamento muito menor entre objetos. É fácil confundir agregação com associação, porque elas são freqüentemente implementadas da mesma forma. Em última instância, a associação e agregação são determinadas mais pela intenção do que por mecanismos explícitos da linguagem. A distinção pode ser difícil de ver na estrutura de tempo de compilação, porém, é significativa. Os relacionamentos de agregação tendem a ser em menor número e mais permanentes que as associações. Em contraste, as associações são feitas e refeitas mais freqüentemente, algumas vezes existindo somente para a duração de uma operação e são também mais dinâmicas, tornando-as mais difíceis de distinguir no código-fonte. Com tal disparidade existente entre as estruturas de um programa em tempo de execução e tempo de compilação, é claro que o código não revelará tudo acerca de como o sistema funcionará. A estrutura de um sistema em tempo de execução deve ser imposta mais pelo projetista do que pela linguagem. Os relacionamentos entre objetos e seus tipos devem ser projetados com grande cuidado porque eles determinam quão boa ou ruim é a estrutura em tempo de execução. Muitos padrões de projeto capturam explicitamente a distinção entre estruturas de tempo de compilação e execução. Por exemplo, o padrão Observer envolve estruturas de tempo de execução que são freqüentemente difíceis de compreender, a menos que você conheça o padrão. 1.6.12 Projetando para mudanças A chave para a maximização da reutilização está na antecipação de novos requisitos e mudanças nos requisitos existentes e em projetar sistemas de modo que eles possam evoluir de acordo. Para projetar um sistema de maneira que seja robusto e em face de tais mudanças, você deve levar em conta como o sistema pode necessitar mudar ao longo de sua vida. Um projeto que não leva em consideração a possibilidade de mudanças está sujeito ao risco de uma grande reformulação no futuro, podendo envolver redefinições e reimplementações de classes. A reformulação afeta muitas partes de um sistema de software e, invariavelmente, mudanças não antecipadas são caras. Os padrões de projeto ajudam a evitar isto ao garantirem que o sistema possa mudar segundo maneiras específicas. Cada padrão de projeto permite a algum aspecto da estrutura do sistema variar independentemente de outros aspectos, desta forma tornando um sistema mais robusto a um particular tipo de mudança. Abaixo, serão apresentadas algumas causas comuns de reformulação de projeto: 1. Criando um objeto pela especificação explícita de uma classe: especificar um nome de uma classe quando você cria um objeto faz com que se comprometa com uma particular implementação, em vez de se comprometer com uma determinada interface. Este compromisso pode complicar futuras mudanças. Para evitá-los, crie objetos indiretamente. 2. Dependências de operações específicas: quando se especifica uma operação em particular, se compromete com uma maneira de atender uma solicitação. Evitando solicitações codificadas inflexivelmente, você torna mais fácil mudar a maneira como uma solicitação é atendida, tanto em tempo de compilação como em tempo de execução. 3. Dependências de plataforma de hardware e software: as interfaces externas do sistema operacional e as interfaces de programação de aplicações (APIs) são diferentes para diferentes plataformas de hardware e software. O software que depende de uma plataforma específica será mais difícil de portar para outras plataformas. Pode ser até mesmo difícil mantê-lo atualizado na sua plataforma nativa. 4. Dependências de representações ou implementações de objetos: clientes que sabem como um objeto é representado, armazenado, localizado ou implementado podem necessitar serem mudados quando o objeto muda. Ocultar essas informações dos clientes evita a propagação de mudanças em cadeia. 5. Dependências algorítmicas: os algoritmos são freqüentemente estendidos,otimizados e substituídos durante o desenvolvimento e reutilização. Os objetos que dependem de algoritmos terão que mudar quando o algoritmo mudar. Portanto os algoritmos que provavelmente mudarão deveriam ser isolados. 6. Acoplamento forte: classes que são fortemente acopladas são difíceis de reutilizar isoladamente, uma vez que dependem uma das outras. O acoplamento forte leva a sistemas monolíticos, nos quais não se pode mudar ou remove uma classe sem compreender e mudar muitas outras classes. 7. Estendendo a funcionalidade pelo uso de subclasses. Customizar ou adaptar um objeto através do uso de subclasses não costuma ser fácil. Cada classe nova tem um custo adicional de inicialização, finalização etc. Definir uma subclasse exige uma compreensão profunda da classe-mãe. Uma operação redefinida pode ser necessária para chamar uma operação herdada. E o uso de subclasses pode levar a uma explosão de classes, porque você pode ter que introduzir muitas subclasses novas, até mesmo para uma extensão simples. 8. Incapacidade para alterar classes de modo conveniente: algumas vezes é necessário modificar uma classe que não pode ser convenientemente modificada. Talvez necessite do código-fonte e não disponha do mesmo (como é o caso de se trabalhar com bibliotecas comerciais de classes), ou talvez qualquer mudança possa requerer a modificação de muitas subclasses existentes. Padrões de projeto oferecem maneiras para modificações de classes em tais circunstâncias. Estes exemplos refletem a flexibilidade que os padrões de projeto podem ajudá-lo a incorporar ao seu software e isso depende do tipo de software que esta sendo construído. Vamos dar uma olhada no papel que os padrões de projeto desempenham no desenvolvimento de três grandes classes de software: 1.6.13 Programas de aplicação O programa construído de aplicação tal como um editor de documentos ou uma planilha, então as prioridades mais altas são reutilizabilidade interna, facilidade de manutenção e de extensão. A reutilizabilidade interna garante que você não projete, nem implemente,mais do que necessita. 1.6.14 Toolkits (Bibliotecas de classes) Freqüentemente uma aplicação incorpora classes de uma ou mais bibliotecas de classes pré-definidas, chamadas toolkits. Um toolkit é um conjunto de classes relacionadas e reutilizáveis, projetadas para fornecer uma funcionalidade útil e de finalidade geral. Os toolkits não impõem um projeto especifico á sua aplicação a executar o seu trabalho. Eles permitem a você, evitar recodificação de funcionalidades comuns. Os toolkits enfatizam a reutilização do código. 1.6.15 Frameworks (Arcabouços de classes) Um framework é um conjunto de classes cooperantes que constroem um projeto reutilizável para uma determinada categoria de software. Outro framework pode lhe ajudar a construir compiladores para diferentes linguagens de programação e diferentes processadores. Outro, ainda, pode ajudar a construir aplicações para modelagem financeira. Você customiza um framework para aplicação especifica através da criação de subclasses especificas para a aplicação, derivadas das classes abstratas do framework. 1.7 Como selecionar um padrão de  projeto 1.7.1 Como selecionar um padrão de projeto (Segundo o artido de ALESSANDRO FERREIRA LEITE) Escolher dentre os padrões existentes aquele que melhor soluciona um problema do projeto, sem cometer o erro de escolher de forma errônea e torná-lo inviável, é uma das tarefas mais difíceis. Em suma, a escolha de um padrão de projeto a ser utilizado, pode ser baseada nos seguintes critérios: I.           Considerar como os padrões de projeto solucionam problemas de projeto. II. Examinar qual a intenção do padrão, ou seja, o que faz de fato o padrão de projeto, quais seus princípios e que tópico ou problema particular de projeto ele trata (soluciona). III. Estudar como os padrões se relaciona. IV. Estudar as semelhanças existentes entre os padrões. V.           Examinar uma causa de reformulação de projeto VI. Considerar o que deveria ser variável no seu projeto, ou seja, ao invés de considerar o que pode forçar uma mudança em um projeto, considerar o que você quer ser capaz de mudar sem reprojetá-lo. 1.7.2 Como usar um padrão de projeto Depois de ter sido feita a escolha do(s) padrão (ões) a ser (em) utilizado(s) no projeto é necessária conhecer como utilizá-lo(s). Uma abordagem recomendada pela gangue dos quatros amigos para aplicar um padrão a um projeto é: I.           Ler o padrão por completo uma vez, para obter sua visão geral. Conhecer o padrão principalmente a sua aplicabilidade e conseqüências são importantes para que ele realmente solucione o seu problema; IV. Estudar seções Estrutura, Participantes e Colaborações. Assegurando-se de que compreendeu as classes e objetos no padrão e como se relacionam entre si; III. Escolher os nomes para os participantes do padrão que tenham sentido no contexto da aplicação; IV. Definir as classes. Declarar as interfaces, estabelecer os seus relacionamentos de herança e definir as variáveis de instância que representam dados e referências a objetos. Identifique as classes existentes na aplicação que serão afetadas pelo padrão e modifique-as; V.           Defina os nomes específicos da aplicação para as operações no padrão. Os nomes em geral dependem da aplicação. Use as responsabilidades e colaborações associadas com cada operação como guia; VI. Implemente as operações para suportar as responsabilidades e colaborações presentes do padrão. A seção de Implementação oferece sugestões para guiá-lo na implementação. Essas são apenas diretrizes que podem ser utilizadas até que seja obtido experiência e conhecimento necessário para desenvolver uma maneira de trabalho particular com os padrões de projeto. Os padrões de projeto não devem ser aplicados indiscriminadamente. Freqüentemente eles obtêm flexibilidade e variabilidade pela introdução de níveis adicionais de endereçamento indireto, e isso pode complicar um projeto e/ou custar algo em termos de desempenho. Um padrão de projeto deverá apenas ser aplicado quando a flexibilidade que ele oferece for realmente necessária.

2.Padrões de criação

Segundo o artigo de Alessandro Leite os padrões de criação são aqueles que abstraem e ou adiam o processo criação dos objetos. Eles ajudam a tornar um sistema independente de como seus objetos são criados, compostos e representados. Um padrão de criação de classe usa a herança para variar a classe que é instanciada, enquanto que um padrão de criação de objeto delegará a instanciação para outro objeto.

Segundo Erick Gamma os padrões de criação tornam-se importantes à medida que os sistemas evoluem no sentido de dependerem mais da composição de objetos do que a herança de classes. O desenvolvimento baseado na composição de objetos possibilita que os objetos sejam compostos sem a necessidade de expor o seu interior como acontece na herança de classe, o que possibilita a definição do comportamento dinamicamente e a ênfase desloca-se da codificação de maneira rígida de um conjunto fixo de comportamentos, para a definição de um conjunto menor de comportamentos que podem ser compostos em qualquer número para definir comportamentos mais complexos.

Ainda segundo Erick Gamma há dois temas recorrentes nesses padrões. Primeiro todos encapsulam conhecimento sobre quais classes concretas são usadas pelo sistema. Segundo ocultam o modo como essas classes são criadas e montadas. Tudo que o sistema sabe no geral sobre os objetos é que suas classes são definidas por classes abstratas. Conseqüentemente, os padrões de criação dão muita flexibilidade no que é criado, quem cria, como e quando é criado. Eles permitem configurar um sistema com objetos “produto” que variam amplamente em estrutura e funcionalidade. A configuração pode ser estática (isto é, especificada em tempo de compilação) ou dinâmica (em tempo de execução).

Abstract Factory

Segundo Erick Gamma a intenção do padrão abstract Factory e a criação de famílias de objetos relacionados ou dependentes sem especificar suas classes concretas. Também muito conhecida como KIT Motivação

Segundo artigo de Alessandro Leite este padrão deve ser aplicado quando se deseja isolar a aplicação da implementação da classe concreta, que poderia ser um componente e ou framework específico no qual a aplicação conheceria apenas uma interface e a implementação concreta seria conhecida apenas em tempo de execução ou compilação. Imagine que em uma aplicação houvesse a necessidade de que ela fosse implementada para oferecer suporte a plataformas e características distintas. Por exemplo: Uma visão desktop e uma móvel (celular Pocket PC). A maneira de constituí-la, seria definindo uma família de componentes para cada plataforma e uma fábrica que os instancia de acordo com a plataforma alvo na qual a aplicação estará sendo executada.

Outro exemplo segundo Erick Gamma,e a classe abstrata WidgetFactory que possui duas especializações: MotifWidgetFactory para widgets Motif e QtWidgetFactory para widgets Qt. Essas especializações são classes concretas capazes de "produzir" os elementos da interface gráfica. O cliente do toolkitob têm os elementos gráficos de que necessita através da classe (interface) WidgetFactory sem ter conhecimento das classes concretas. Da mesma maneira, o cliente somente interage com as interfaces que representam os elementos produzidos pela Abstract Factory (no exemplo, a classe Janela e a classe Botao). Segue o Diagrama: Aplicabilidade Segundo Erich Gamma use o padrão Abstract Factory quando: •	Quando um sistema deve ser independente de como seus produtos são criados, compostos e representados; •	Quando um sistema deve ser configurado com uma entre várias famílias de produtos; •	Quando uma família de produtos relacionados foi projetada para uso conjunto e você deve implementar essa restrição; •	Quando você quer fornecer uma biblioteca de classes e quer revelar sua interface e não sua implementação; Estrutura Participantes

•	AbstractFactory: declara uma interface para operações que criam objetos-produtos abstratos. •	Concrete Factory: implementa as operações que criam objetos-produtos concretos. •	AbstractProduct: declara uma interface para um tipo de objeto-produto. •	ConcreteProduct: define um objeto-produto a ser criado pela correspondente fábrica concreta. Implementa a interface de abstract product. •	Client: usa somente interfaces declaradas pelas classes abstract Factory e Abstract Product. Conseqüência Segundo o artigo de Alessandro Leite o padrão Abstract Factory possui os seguintes benefícios e desvantagens:

•	Ele isola as classes concretas. O padrão Abstract Factory ajuda a controlar as classes de objetos criadas por uma aplicação. Uma vez que a fabrica encapsula a responsabilidade e o processo de criar objetos-produtos, isola os clientes das classes de implementação. Os clientes manipulam as instâncias através das suas interfaces abstratas. Nomes de classes-produtos ficam isolados na implementação da fabrica concreta;elas não aparecem no código do cliente. •	Ele torna fácil a troca de famílias de produtos. A classe de uma fabrica concreta aparecer apenas uma vez numa aplicação- isso é, quando e instanciada. Isso torna fácil mudar a fábrica concreta que uma aplicação usa. Ela pode usar diferentes configurações de produtos simplesmente trocando a fábrica concreta. Uma vez que a fábrica abstrata cria uma família completa de produtos, toda família de produtos muda de uma só vez. •	Ele promove a harmonia entre produtos. Quando objetos-produtos numa família são projetados para trabalharem juntos, é importante que uma aplicação use objetos de somente uma família de cada vez. AbstractFactory torna fácil assegurar isso. •	È difícil de suportar novas tipos de produtos. Entender fábricas abstratas para produzir novos tipos de Produtos não e fácil. Isso se deve pelo fato de que a interface de AbstractFactory fixa o conjunto de produtos que podem ser criados. Suportar novos tipos de produtos exige entender a interface da fábrica, o que envolve mudar a classe AbstractFactory e todas as suas subclasses. Padrões Relacionados

Segundo Erich Gamma as classes AbstractFactory são freqüentemente implementados com métodos-fábricas. Colaborações entre objetos

Segundo ainda o Erick Gamma •	Normalmente uma única instância de uma classe ConcreteFactory é criada em tempo de execução. Essa fábrica concreta cria objetos-produto que têm uma implementação particular. Para criar diferentes objetos-produto, os clientes deveriam usar uma fábrica concreta diferente; •	Essa FactoryConcreta cria objetos tendo uma implementação particular; •	Para criar produtos diferentes, clientes devem usar uma FactoryConcreta diferente; •	FactoryAbstrata depende de suas subclasses FactoryConcreta para criar objetos de produtos.

Referencias bibliográficas Livro: Padrões de Projeto soluções reutilizáveis de software orientado a objetos Autor: Gamma, Erich www.devmedia.com.br http://webcache.googleusercontent.com/search?q=cache:QmwEHykuoigJ:projetos.inf.ufsc.br/arquivos_projetos/projeto_354/TCC_Joaber.pdf+Determinando+a+granularidade+dos+objetos-padroes+de+projeto&hl=pt-BR&gl=br ALEXANDER, C., ISHIKAWA, S., SILVERSTEIN, M., JACOBSON, M., FIKSDAHL-KING, I., ANGEL, S. "A Pattern Language". New York, NY (USA): Oxford University Press, 1977. Trygve M. H. Reenskaug/MVC Richard Helm, Ralph Johnson, John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. 1 ed. Estados Unidos da América: Addison-Wesley, 1995. ISBN 0-201-63361-2 Clube da Programação - Sobre design patterns: Singleton | url: http://www.clubedaprogramacao.com METSKER, Steven John. PADRÕES DE PROJETO EM JAVA, Pág. 197. 2004

FOWLER, Martin. UML ESSENTIALS: um breve guia para a linguagem-padrão de modelagem de objetos. 3ª ed. pág 52. Porto Alegre.Bookman. 2005. Artigo Padrões de projeto São Paulo, 2010 Disponível em:  Acesso em: 03 dez. 2010