# Component Object Model

Component Object Model (COM) é uma plataforma da Microsoft para componentes de software lançada em 1993. Ela é usada para permitir a comunicação entre processos e a criação dinâmica de objetos em qualquer linguagem de programação que suporte a tecnologia. O termo COM é frequentemente usado no desenvolvimento de software para se referir a um grupo de tecnologias que incluem OLE, OLE Automation, ActiveX, COM+ e DCOM. Apesar de introduzido em 1993, a Microsoft não iniciou a divulgação ampla do nome antes de 1997.
Em sua essência, a COM é uma forma independente de linguagem de programação de implementar objetos de forma que eles possam ser utilizados em diferentes ambientes dos quais foram criados, mesmo entre diferentes máquinas e arquiteturas. A COM permite a reutilização de objetos sem o conhecimento de sua implementação interna pois força o desenvolvedor a fornecer uma interface bem definida, que está separada da implementação. As diferentes semânticas na alocação de memória entre linguagens de programação são resolvidas ao tornar os objetos responsáveis por sua própria criação e destruição, através de contagem de referência. A conversão entre diferentes interfaces de um objeto são obtidas através da função QueryInterface. O método preferível de herdar em COM é a criação de sub-objetos (chamada agregação) para as chamadas de método, os quais são delegados.
Apesar de ter sido implementado em diversas plataformas, a COM é usada em sua maioria no Microsoft Windows. Espera-se que ela seja substituída ou pelo menos estendida pela plataforma Microsoft .NET, suportando então Web Services através da Windows Communication Foundation (WCF). A DCOM em redes utiliza formatos binários proprietários, enquanto a WCF utiliza troca de mensagem SOAP baseada em XML. COM também compete com CORBA e Enterprise JavaBeans como um sistema para componentes de software.

## História

Um dos primeiros métodos de comunicação entre processos no Windows foi o DDE, que permitia o envio e recepção de mensagens na chamada "conversação" entre aplicações. Essa tecnologia foi a base da OLE, que era uma das tecnologias mais inovadoras introduzidas no Windows 3.0. Conversações por texto e do Windows não se mostraram tão flexíveis para permitir o compartilhamento de funcionalidades de aplicações de uma maneira extensível. Então, para o lançamento da versão 3.1 do Windows, foi criada a COM como um novo fundamento do sistema, e a OLE foi alterada para a OLE2.
O Visual Basic introduziu o VBX (extensões empacotadas na forma de DLL) que permitia a criação de objetos a serem posicionados graficamente em um formulário e manipulados através de propriedades e métodos. Isso foi adaptado posteriormente para outras linguagens, assim como foi feito no Visual C++. Os controles COM (OCX) tornaram-se um substituto do VBX.
Anthony Williams, um dos mais notáveis pensadores na criação da arquitetura COM, distribuiu alguns artigos internos da Microsoft em pró dos componentes de software: Object Architecture: Dealing With the Unknown – or – Type Safety in a Dynamically Extensible Class Library (1988) e On Inheritance: What It Means and How To Use It (1990). Várias dessas ideias resultaram na primeira arquitetura orientada a objeto da empresa, OLE. A OLE foi construída sobre a DDE e desenvolvida especificamente para documentos compostos. Ela foi introduzida no Microsoft Word e no Microsoft Excel em 1991, e depois incluída no Windows, a começar na versão 3.1 de 1992. Uma exemplo de um documento composto é uma planilha eletrônica embarcada em um documento de texto do Word: caso sejam feitas mudanças na mesma planilha aberta no Excel, ela são atualizadas automaticamente no documento do Word.
Em 1991 a Microsoft introduziu o Visual Basic Extension (VBX) no Visual Basic 1.0. Em 1993 a empresa lançou a OLE 2. Enquanto a primeira versão era focada em documentos compostos, tanto COM quanto OLE 2 foram desenvolvidas para componentes de software em geral. Em 1994 os controles OLE (OCX) foram introduzidos como sucessores dos controles VBX. Na mesma época a empresa declarou que a OLE 2 seria conhecida somente como OLE.
No início de 1996 a Microsoft encontrou novo uso para os controles personalizados OLE, expandido o navegador Internet Explorer para apresentar o conteúdo, renomeando algumas partes da OLE relacionadas ao ActiveX, e gradualmente renomeando todas as tecnologias OLE para ActiveX, exceto a tecnologia de documentos compostos que estava em uso no Microsoft Office. No mesmo ano a DCOM foi introduzida como uma resposta a CORBA.

## Tecnologias relacionadas

COM foi uma plataforma bastante influente no desenvolvimento de software do Windows, por isso influenciou o desenvolvimento de várias tecnologias de suporte.

### COM+

Para fornecer aos desenvolvedores suporte a transações distribuídas, e melhor gerenciamento de memória e processamento, assim como para posicionar o Windows como uma alternativa a outros sistemas operacionais corporativos, a Microsoft introduziu a tecnologia Microsoft Transaction Server no Windows NT Service Pack 4.
No Windows 2000, tal extensão significativa à COM foi incorporada ao sistema operacional e renomeada COM+. Na mesma época a DCOM foi reconsiderada como uma entidade separada.

### .NET

A plataforma COM foi substituída pela Microsoft .NET (lê-se "dot NET"), com a Microsoft focando seu marketing exclusivamente a essa nova plataforma. A COM era geralmente usada para interoperar códigos complexos e de grande desempenho com interfaces ao usuário em Visual Basic ou ASP.
Para algumas extensões a COM agora foi depreciada em favor da .NET. Já que a .NET fornece ferramentas de desenvolvimento rápido similares ao Visual Basic tanto para Windows Forms quanto para Web Forms com JIT, o código de alto desempenho pode ser implementado em C#.
Apesar disso, a COM permanece como uma tecnologia viável com importante base de sistema legado. Por exemplo, a SDK, popular renderizador do DirectX 3D, é baseado em COM. A COM também é ideal para o controle de scripts de aplicações como o Office ou o Internet Explorer, pois fornece uma interface para chamar métodos de objetos COM de um script ao invés de necessitar o conhecimento de uma API em tempo de compilação.
Vários serviços fornecidos pela COM+ ainda são importantes em aplicações .NET corporativas, tais como transações e filas de componentes.

## Segurança da Internet

A ideia da Microsoft de embarcar conteúdo ativo em páginas web como componentes COM/ActiveX (ao invés de, por exemplo, applets Java) criou uma combinação de problemas no Internet Explorer, que lideraram a uma explosão de infecções por vírus de computador, trojan e spyware. A empresa reconheceu o problema com o ActiveX ainda em 1996 quando Charles Fitzgerald, gerente de programas do time de Java da Microsoft disse que "Se você quer segurança na Internet, desligue seu computador. ... Nós nunca declaramos que o ActiveX é intrinsecamente seguro." Como os componentes COM e ActiveX são executados como código nativo na máquina hospedeira, existem algumas pequenas restrições que o código pode fazer. Vários desses problemas foram rediscutidos pela introdução da "assinatura de código" (baseada em assinatura digital) e também na plataforma .NET.

## Detalhes técnicos

Programadores COM constroem software usando componentes compatíveis com a COM. Diferentes tipos de componentes são identificados por identificadores de classe (CLSIDs), que são identificadores globais únicos (GUID). Cada componente COM expõe sua funcionalidade através de uma ou mais interfaces. As diferentes interfaces suportadas por um componente são distinguidas umas das outras através de identificadores de interface (IID), que também são GUID.
Interfaces COM possuem implementações em diversas linguagens, como C, C++, Visual Basic e diversas linguagens interpretadas da plataforma Windows. Todo acesso aos componentes é feito através de métodos das interfaces. Isso permite técnicas como programação entre processos, até mesmo entre computadores, este último utilizando DCOM.

### Interfaces

Todos os componentes COM devem implementar pelo menos a interface padrão IUnknown, e, portanto, todas as interfaces COM são derivadas de IUnknown. Essa interface consiste de três métodos: AddRef e Release, que implementam a contagem de referências e o controle do tempo de vida das interfaces; e QueryInterface, que ao especificar um IID permite ao invocador obter referências às diferentes interfaces que o componentes implementa. O efeito de QueryInterface é similar ao dynamic_cast<> em C++ ou conversões de tipo em Java e C#.
As interfaces de componentes COM são necessárias para exibir as propriedades reflexivas, simétricas e transitivas. A propriedade reflexiva refere-se à habilidade da chamada QueryInterface de uma dada interface de retornar uma mesma instância da interface. A propriedade simétrica exige que quanto uma interface B é obtida de uma interface A via QueryInterface, a interface A também possa ser obtida da interface B da mesma forma. A propriedade transitiva é similar à simétrica, mas requer que se a interface B pode ser obtida da interface A e a interface C pode ser obtida da interface B, então a interface C deve poder ser obtida da interface A.
Uma interface consiste de um ponteiro para uma tabela de funções virtuais que contém uma lista de ponteiros para as funções que implementam as funções declaradas na interface, na mesma ordem que foram declaradas. Essa técnica de passagem de estruturas de ponteiros de função é bastante similar à usada pelo OLE 1.0 para comunicar com suas bibliotecas de sistema.
A COM especifica várias outras interfaces padrão usadas para permitir a comunicação entre componentes. Por exemplo, uma interface dessas é a IStream, que é exposta por componentes que possuem semânticas de fluxos de dados (como o componente FileStream, usado para ler e escrever arquivos). Ela possui os métodos esperados Read e Write para realizar a leitura e escrita de fluxos de dados.

### Classes

Uma classe em COM é denominada coclasse, e permite definir uma classe (no sentido de orientação a objeto) independentemente de linguagem. Ela fornece uma implementação concreta de uma ou mais interfaces. Tais implementações concretas podem ser escritas em qualquer linguagem de programação que suporte o desenvolvimento de componentes COM. Uma das maiores contribuições da COM para o mundo de desenvolvimento para a plataforma Windows foi a filosofia da separação do conceito de interface e implementação, o que influenciou a maneira como vários programadores constroem sistemas atualmente. Uma extensão desse conceito é a noção de uma interface e múltiplas implementações. Isso significa que, em tempo de execução, uma aplicação pode escolher instancializar uma interface entre várias implementações disponíveis.

### IDL e bibliotecas de tipos

Como mencionado anteriormente, as bibliotecas de tipos contém metadados que representam os tipos COM. Entretanto, esses tipos devem antes serem descritos através da Microsoft Interface Definition Language. Inclusive, é uma prática comum no desenvolvimento de um componente COM iniciar com as definições dos tipos usando IDL.
Um arquivo IDL permite que desenvolvedores definam classes orientadas a objeto, interfaces, estruturas, enumerações e outros tipos definidos pelo utilizador, independentemente da linguagem de programação. A IDL é bastante similar em aparência às declarações em C e C++ com a adição das palavras-chave interface e library para a definição de interfaces e coleções de classes, respectivamente.
O arquivo IDL é compilado pelo compilador MIDL em um par de formulários para consumo em diversas linguagens. Para C e C++, o compilador MIDL gera um arquivo de cabeçalho (.h) contendo definições de estruturas para combinar às tabelas de métodos virtuais das interfaces declaradas e um arquivo de código (.c ou .cpp) contendo declarações das GUID. Pode-se também gerar código fonte C++ para um módulo de proxy, que contém esboços de métodos para converter chamadas COM em chamadas de procedimento remoto, habilitando então a DCOM.
Um arquivo IDL também pode ser compilado pelo compilador MIDL em uma biblioteca de tipos (.tlb). Os metadados binários contidos na biblioteca de tipos devem ser processados por compiladores de linguagens e ambientes em tempo de execução (como Visual Basic, Delphi, CLR da .NET).

### COM como uma plataforma de objetos

Os princípios fundamentais da COM possuem suas raízes na filosofia da orientação a objeto. Ela é uma plataforma para o desenvolvimento e implantação de orientação a objeto. Como a plataforma é manipulada em tempo de execução, os tipos devem ser identificáveis e especificáveis individualmente em tempo de execução. Para obter esse resultado são usados os GUID, que são identificadores únicos globais. Cada tipo COM tem designado seu próprio GUID para identificação em tempo de execução.
Para que tal informações seja acessível tanto em tempo de compilação quanto em tempo de execução, a COM apresenta a biblioteca de tipos; é através de seu uso que a plataforma desempenha seu papel na interação dinâmica de objetos. Considerando a seguinte definição de uma coclasse em um arquivo IDL:
O fragmento de código acima declara uma classe COM MyObject que deve implementar uma interface IMyObject e que suporta (mas não implementa) a interface de evento _IMyObjectEvents. Ignorando a interface de evento por um momento, isso é conceitualmente equivalente à definição de uma classe C++ como segue:
no qual ISomeInterface é uma classe virtual C++.
Referindo-se novamente a classe COM: uma vez que a definição de uma coclasse é formalizada em IDL, e uma biblioteca de tipo é compilada através do arquivo IDL, o ônus está no compilador da linguagem de programação em ler e interpretar apropriadamente a biblioteca de tipos e produzir código necessário para o desenvolvedor implementar o código necessário para a coclasse COM.
Após a implementação de uma coclasse COM ser construída e disponibilizada no sistema, a próxima questão é instanciá-la. Em linguagens como C++ isso pode ser feito pela API CoCreateInstance. Chamar essa API da seguinte maneira:
é conceitualmente equivalente em C++ ao seguinte código:
No primeiro caso, é pedido ao sub-sistema COM um ponteiro para um objeto que implementa a interface IMyObject e cuja implementação é CLSID_MyObject. No segundo caso, é pedido a criação instancialização de uma classe C++ que implementa a interface ISomeInterface cuja implementação é CSomeObject.
Conclui-se que uma coclasse é uma classe orientada a objeto no mundo da COM.

### Registro

No Windows, as classes COM, interfaces e bibliotecas de tipos são listadas pelo GUID no Registro do Sistema sob HKEY_CLASSES_ROOT\CLSID para classes e HKEY_CLASSES_ROOT\interface para interfaces. As bibliotecas COM usam o registro para localizar ou o local correto de bibliotecas locais ou a localização na rede de serviços remotos.

### Contagem de referência

A interface mais fundamental da COM, IUnknown (da qual todas as interfaces COM devem derivar), suporta dois conceitos principais: a exploração das funcionalidades através do método QueryInterface e o gerenciamento do tempo de vida do objeto através de AddRef e Release. A contagem de referências e a exploração de funcionalidades são aplicadas aos objetos, e portanto devem ter implementação centralizada.
As especificações COM requerem uma técnica chamada contagem de referências para assegurar que objetos individuais permaneçam na memória enquanto existam clientes que possuem acesso a pelo menos uma de suas interfaces e, da mesma forma, que o mesmo objeto seja destruído quando seu uso já não é mais necessário. Um objeto COM é responsável pela liberação de sua própria memória uma vez que a contagem de referência chega a zero.
Para essa implementação, um objeto COM geralmente mantém uma valor inteiro usado para a contagem de referências. Quando AddRef é invocado por qualquer uma das interfaces do objeto, esse valor é incrementado. Da mesma forma, quando Release é invocado, esse valor é decrementado.
Algumas linguagens (como o Visual Basic) fornecem uma contagem automática de referências de forma que os desenvolvedores COM não precisem manter explicitamente qualquer referência interna no código fonte. Em C, a contagem explícita de referências deve ser feita. Em C++ pode-se escolher entre a contagem explícita de referências ou o uso de ponteiros inteligentes (também chamados smart pointers, ponteiros automáticos que gerenciam automaticamente a contagem de referências).
Para facilitar e promover o desenvolvimento COM, a Microsoft introduziu a biblioteca de rotinas ATL para desenvolvedores C++. Ela fornece um paradigma de alto nível para o desenvolvimento na plataforma, e também protege desenvolvedores de aplicações da necessidade de manutenção de contagem de referências. Outras bibliotecas e linguagens compatíveis com a COM incluem Microsoft Foundation Classes, VBScript, Visual Basic, ECMAScript (JavaScript) e Delphi.

### Instancialização

A COM padroniza o processo de criação de objetos COM ao requerer o uso de factories (construtores) de classes. Para a criação de um objeto COM deve existir uma factory e um identificador. A classe factory é também um objeto COM, que deve expor ou a interface IClassFactory ou a interface IClassFactory2.
Um objeto da classe factory é geralmente contido no mesmo código executável do objeto COM. Quando ele é chamado para a criação de um objeto, o identificador deve ser fornecido, de forma a indicar qual classe deve ser criada. Isso porque uma classe factory pode criar objetos de mais de uma classe, o que é transparente ao sistema COM.
Ao delegar a responsabilidade de criação de objeto em outro objeto, é promovido um grande nível de abstração, dando ao desenvolvedor mais flexibilidade, e separando a aplicação cliente do objeto COM.

### Reflexão

Na época de lançamento das tecnologias COM, a única maneira de um cliente encontrar as funcionalidades de um objeto era somente ao instanciá-lo e posteriormente através de QueryInterface. Essa forma de exploração tornou-se inadequada para várias aplicações, incluindo a seleção dos componentes apropriados para uma tarefa específica e ferramentas para ajudar os desenvolvedores a entender como usar os métodos fornecidos por um objeto.
Como resultado, as bibliotecas de tipos COM foram introduzidas, através das quais os componentes de descrevem. Uma biblioteca de tipo contém informações como o identificador da classe do componente, os identificadores das interfaces que o componente implementa e a descrição de cada um dos métodos das interfaces.

## Críticas
### Processamento de mensagens

Quando a COM é inicializada ela cria uma janela invisível que é usada para o roteamento de mensagens entre processos e threads. Essa janela deve ter sua fila de mensagens regularmente processada. Em versões antigas do Windows, uma falha em tal sistema poderia causar um travamento geral de todo o sistema.

### Contagem de referências

A contagem de referências da COM pode causar problemas se dois ou mais objetos são referenciados circularmente. O projeto de uma aplicação deve levar em contar esse tema, de forma que objetos não se tornem órfãos.

### Inferno de DLLs

Como a localização de cada componente é armazenada de maneira global no sistema (no registro do Windows), só pode existir uma versão de cada componente instalado. Dessa forma, a COM sofre seriamente do problema de inferno de DLLs, no qual duas ou mais aplicações requisitam diferentes versões de um mesmo componente.
O Windows XP introduziu um novo modo de registro de objetos COM, tornando possível às aplicações que precisam instalar objetos COM e todas as informações necessárias no diretório da própria aplicação ao invés de usar o registro global.