O que são Componentes?
Vamos agora detalhar as idéias
Muitas definições foram oferecidas ao longo dos últimos anos (ver aqui)
Apesar da confusão nas definições, podemos enxergar algo em comum
Vamos iniciar com a definição mais geral de D'Souza
Componente geral: "Um pacote coerente de artefatos de software que pode ser desenvolvido independentemente e entregue como unidade e que pode ser composto, sem mudança, com outros componentes para construir algo maior."
Baseando-se nesta definição, todas as coisas que seguem poderiam ser consideradas "componentes", pelo menos em espírito:
Arrastar um widget de GUI, tal como uma list box, e conectar as listas a uma fonte apropriada de dados do domínio do problema
Usar a mesma template de lista em C++ para implementar várias classes do domínio do problema através da especialização do parâmetro do template:
class Pedido {
private: List<ItemDePedido> itens;
};
Usar os seguintes produtos off-the-shelf (produtos prontos): um pacote de calendário, um processador de textos e uma planilha, e montar esses componentes heterogêneos usando scripts que resolver um problema particular do domínio do problema
Usar um framework de classes, usando, por exemplo, componentes do pacote Swing da linguagem Java, para construir uma interface com o usuário para muitas aplicações e conectar os componentes gráficos a seus objetos de domínio de problema
Usar um framework de alocação de recursos que modelar problemas variando da alocação de salas para seminários até o escalonamento de tempo de máquina para a produção de lotes de peças numa fábrica
Usar construções pré-definidas de uma linguagem de programação numa infinidade de contextos:
for(...; ...; ...) {
...
}
Usando essa definição, um componente pode incluir:
Código executável
Código fonte
Projetos (designs)
Especificações
Testes
Documentação
etc.
Mas nós queremos falar apenas de componentes de implementação
Definição de D'Souza, mais uma vez:
Componente de implementação: "Um pacote coerente de implementação de software que (a) pode ser desenvolvido independentemente e entregue como unidade; (b) tem interfaces explícitas e bem definidas para os serviços que oferece; (c) tem interfaces explícitas e bem definidas para os serviços que requer; e (d) pode ser composto com outros componentes, talvez após a customização de algumas propriedades mas sem modificar os componentes em si."
Examinando esta definição (e as outras), podemos ver o que componentes têm de diferente comparados a bibliotecas ou outros artefatos de software
São 3 características básicas
1. Construção de aplicações por montagem
Essa é a diferença principal!
Um componente deve permitir que todo o trabalho (ou quase) seja feito pela composição de pedaços existentes
Isso significa que, no processo de desenvolvimento, novas etapas podem surgir
Design time (ou assembly time) para juntar componentes e montar aplicações
A definição "oficial" da conferência sobre componentes em 1996 fala de "composição por terceiros". Por que isso é importante?
Um "terceiro" é alguém que não tem acesso a detalhes de construção e não possui o código fonte
Portanto, componentes podem ser modificados ao incluí-los na aplicação, mas sem ter código fonte
Componentes maximizam assim o "information hiding"
A modificação pode ser de atributos, por exemplo ("Attribute programming")
A modificação (configuração) do componente usa freqüentemente uma ferramenta visual ("Visual Programming")
2. Um componente explicita suas interfaces
Para ser plugável em vários contextos ("Plug-Replaceable"), temos que usar interfaces padronizadas
Uma interface é um contrato que especifica a funcionalidade do componente
Um componente tem duas interfaces:
Dos serviços que ele oferece (export interface)
Dos serviços que ele requer de outros componentes (import interface)
Esta interface explicita as "dependências de contexto"
O componente não pode depender do contexto onde ele vai atuar a não ser através dessa interface
As linguagens de programação têm se concentrado apenas em especificar as interfaces de serviços oferecidos e não de serviços usados pelos componentes
Se juntarmos um pequeno grupo de objetos funcionando conjuntamente e isolá-los com uma interface de componente, a complexidade (o acoplamento) vai diminuir, reduzindo a chance de Objetos Hyperspaghetti
Para permitir que o ambiente (freqüentemente visual) de composição funcione, as interfaces devem ser auto-descritivas
Deve ser possível descobri-las em tempo de execução, sem ter tido conhecimento algum do componente antes
Isso afeta as opções de binding (detalhes adiante)
3. Um componente é uma unidade de empacotamento (packaging), entrega (delivery), implantação (deployment), e carga (loading)
Unidade de empacotamento
Inclui tudo dentro dele: a especificação de suas interfaces, legível em tempo de execução, implementação, imagens, outros recursos, ...
Unidade de entrega
Um componente não é entregue parcialmente quando vendido. Ele é entregue num formato que é independente de outros componentes com os quais ele venha a ser composto
Unidade de implantação
Um componente não é implantado parcialmente
Durante a implantação, seus atributos podem ser alterados (configurados)
Também significa que é a unidade de troca na manutenção (a aplicação inteira não precisa ser trocada)
Unidade de carga
Na aplicação final um componente é carregado por inteiro: "Quero um desses!"
Não posso dizer: "Me esse componente, mas só carne magra!"
De que consiste um componente, tipicamente?
Várias classes (código binário)
Definições de interfaces, usando algum mecanismo utilizável em tempo de execução
Possivelmente objetos (factories para criar objetos através do componente)
"Recursos" (podem ser arquivos de dados contendo formulários, strings, parâmetros, imagens, etc.) que são usados para configurar o componente
Alguns desses recursos podem ser mudados em tempo de execução
Componentes versus Objetos
As diferenças geram controvérsia
Instanciação
A instanciação de um componente não gera outro componente mas um "objeto" criado a partir de um protótipo (o componente)
Um componente freqüentemente é visto como um factory de objetos e não um objeto em si
Em termos de linguagem OO, um componente pode conter vários objetos
Componentes têm granularidade maior, freqüentemente
Componentes freqüentemente tratam de sua persistência
Objetos não fazem isso
Objetos não são empacotados como componentes
Componentes são sujeitos à composição em tempo de design
Se o componente obedece às suas interfaces, ele pode ser implementado em qualquer linguagem (mesmo sem ser OO!) e rodar em qualquer plataforma
Objetos são manipulados com linguagens OO apenas
Categorias de Componentes
Podemos classificar componentes sob várias dimensões
Escopo
Componentes de Especificação (diagramas, documentos)
Componentes de Implementação (classes, ...)
Objetivo
Domínio (voltado ao problema)
Tecnologia (para o suporte, infra-estrutura)
Abstração
Geral (aplicação em muitos domínios: horizontal)
Específico (aplicação em um único ou poucos domínios: vertical)
Granularidade
Fina (um widget GUI)
Grossa (shopping-cart, agência bancária, fatura, contas a receber)
As oportunidades de reuso podem ser menores mas tais componentes são cruciais para melhorar a produtividade no desenvolvimento
Localização
Cliente
Servidor (Middle tier)
Serviços providos
Gerência de configuração e de propriedades
Notificação de eventos
Acesso a metadados e reflexão
Persistência
Controle de transação e concorrência
Segurança
Licenciamento
Controle de versão
Autotestes
Auto-instalação
Definições de Componentes
Seguem definições de Componentes que apareceram em várias fontes
Cada uma oferece uma perspectiva particular
A definição "oficial" dada numa conferência sobre Componentes em 1996:
"Um componente é uma unidade de composição com interfaces especificadas contratualmente e com dependências de contexto explícitas apenas Um componente de software pode ser implantado [deployed] de forma independente e está sujeito à composição por terceiros"
Jed Harris, President of CI Labs
"Um componente é um pedaço de software pequeno o suficiente para criar e manter, grande o suficiente para implantar (deploy) e suportar e com interfaces padrão para a interoperabilidade."
Grady Booch, um dos "Três Amigos" da UML
"Um componente é uma parte de um sistema que seja não trivial, quase-independente e substituível que desempenha uma função clara... Pode ser usado para montar [assemble] uma arquitetura [ou aplicação] bem definida ... Um componente obedece e provê a realização física [implementação] de um conjunto de interfaces que especificam alguma abstração lógica (i.e., comportamento do sistema)."
Anne Thomas, analista do Patricia Seybold Group
"Componentes são pedaços pré-desenvolvidos de código de aplicação que podem ser montados em aplicações."
Mary Kirtland, um programador no time da Microsoft que desenvolve COM dá duas definições:
"Quando falo de um componente, quero dizer um corpo de código que pode criar e fornecer objetos de um tipo particular em tempo de execução.Usando esta definição, um componente seria implementado como classe na maioria das linguagens modernas de programação orientadas a objeto."
"...unidade de código binário que cria objetos COM incluindo código de packaging, código de registration, uma factory de classes, etc."
Judith Hurwitz, Presidente e CEO de Hurwitz Group
"Um objeto de granularidade grossa (relativamente a um objeto) é um "pacote" de software que contém uma coleção de serviços relacionados e atributos que abrangem a funcionalidade completa de algum problema do negócio."
Desmond D'Souza, famoso pelo processo de desenvolvimento Catalysis oferece três definições: uma para Component-Based Development, uma para componentes em geral e uma para componentes de implementação
Component-Based Development: "Uma forma de desenvolver software na qual todos os artefatos - desde o código executável até as especificações de interfaces, arquiteturas e modelos de negócios; e com escalas variando de aplicações e sistemas completo até pequenas partes - podem ser construídos com montagem [assembly], adaptação, "ligando" entre si componentes existentes numa variedade de configurações."
Componente geral: "Um pacote coerente de artefatos de software que pode ser desenvolvido independentemente e entregue como unidade e que pode ser composto, sem mudança, com outros componentes para construir algo maior."
Componente de implementação: "Um pacote coerente de implementação de software que (a) pode ser desenvolvido independentemente e entregue como unidade; (b) tem interfaces explícitas e bem definidas para os serviços que oferece; (c) tem interfaces explícitas e bem definidas para os serviços que requer; e (d) podem ser composto com outros componentes, talvez após a customização de algumas propriedades mas sem modificar os componentes em si."
Clemens Szperski
"Um componente é uma unidade independente de implantação, uma unidade de composição por terceiros, e não tem estado persistente."
Robert Orfali, Dan Harkey e Jeri Edwards, especialistas conhecidos sobre OOD e CBD
Apareceu no livro "The Essential Distributed Objects Survival Guide (1996)"
"Já que componentes significam coisas diferentes para pessoas diferentes, definiremos as funções que um componente mínimo deve prover ... É uma entidade marketeável ... Não é uma aplicação completa ... Pode ser usada em várias combinações ... Tem uma interface bem definida ... É um objeto interoperável ... Em suma, um componente é um pedaço de software reusável, auto-contido que é independente de qualquer aplicação."
Eles então descrevem componentes inteligentes ou super-componentes:
"Segurança? Licenciamento... Controle de versão? Gerência de ciclo de vida? Suporte para palhetas abertas de ferramentas? Notificação de eventos? Gerência de configuração e de propriedades? Scripting? Metadados e introspecção? Controle de transação e concorrência? Persistência? Relacionamentos? facilidade de uso? Auto-testes? Mensagens semânticas? Auto-instalável."