Numa aplicação podem distinguir-se três tipos genéricos de objectos: objectos de programador, criados explicitamente pelo programa e da sua inteira responsabilidade; objectos de ligação, criados automaticamente, de forma transparente e fora do controlo directo do programador da aplicação, na altura do arranque da aplicação ou durante a execução; e, objectos de suporte, criados no nível de suporte. Ver-se-ão adiante que formas o código do programador tem para controlar alguns destes acontecimentos.
A distinção entre os objectos dos níveis de ligação e de suporte é algo artificial, pois todos eles são objectos fora do controlo directo do programador da aplicação e geridos automaticamente. A divisão faz-se porque a estrutura dos objectos de ligação é independente da funcionalidade que providenciam, i.e., são objectos que providenciam funcionalidade abstracta. A estrutura dos objectos de suporte depende fortemente de quase todos os aspectos em que estão envolvidos. Dependem, em particular, da funcionalidade providenciada pelo módulo a que pertencem, pormenores de programação, tais como dependências de bibliotecas e sistemas operativos particulares, etc. Existem para isolar o nível de ligação, e, consequentemente, o do programa, dessas mesmas dependências.
Os objectos de ligação são objectos normais da linguagem utilizada. Podem ser de dois tipos: envelopes, que substituem alguns objectos do programador junto do nível de programa; gestores de módulos, que permitem ao nível de programa controlar, de uma forma simples alguns acontecimentos nos níveis mais baixos. São os gestores de módulos que desencadeiam e controlam operações associadas a características especiais dos objectos, e.g. exportação e distribuição, repectivamente.
A cada envelope está associado, no máximo, um objecto de programa, que se designará por carta. A carta está encapsulada pelo envelope, que a substitui, de forma transparente, no código do programa. A interface da carta é um subconjunto da do envelope. Os dois objectos estão associados numa relação um-para-um e diz-se que formam um objecto composto. Cada objecto composto é um pseudo-objecto de programa, do ponto de vista da aplicação, uma vez que, para o código que utiliza o envelope, tudo se passa como se ele não existisse, i.e., como se o objecto de programa original lá estivesse. A funcionalidade adicional do envelope, da qual a interface adicional é uma consequência, não se destina a ser utilizada pelo nível de programa mas sim pelo nível de ligação e, especialmente, pelo de suporte. A interface adicional pode conter funcionalidade característica dos envelopes ou dependente dos vários módulos existentes numa aplicação.
Os envelopes providenciam, assim, um nível de indirecção entre o código do programa e o da classe da qual é instância a carta. A funcionalidade básica desta indirecção é semelhante à da que existe nos casos vistos no capítulo 2, apresentado, contudo, diferenças que a tornam mais flexível e fácil de utilizar. Uma das características mais importantes desta indirecção é a sua transparência e a uniformidade que possibilita nos acessos aos objectos que estão para além do envelope.
A ideia é descrita por Coplien para C++ como um caso particular do paradigma handle/body [Coplien, 1992, capítulos 3 e 5, pp. 133ff,]. O dialecto baseado em envelopes e cartas é uma técnica de programação que consiste em utilizar um par de objectos, instâncias das classes correspondentes, que actuam como um único: um exterior, a ``pega'' ou ``pele'', que é a parte visível, e um interior, o ``corpo'', onde estão escondidos os pormenores de programação. O corpo recebe apenas as mensagens que lhe são passadas pela pele, vindas do exterior. Os dois formam um objecto composto. Esta técnica de desenho possibilita uma maior flexibilidade que a forma canónica de programação.
Escondida detrás de cada envelope, vai estar funcionalidade que possibilita à aplicação ver, associadas a cada objecto composto, algumas características especiais, e.g. persistência. Para que a funcionalidade se manifeste, o nível de programa vai ter que contactar o gestor de módulos apropriado que, por seu turno, vai contactar outros objectos do nível de suporte, e do de ligação, para que seja efectuada a operação desejada. Em particular, o envelope, correspondente ao objecto composto em causa, vai ter que realizar algumas tarefas específicas, dependentes dessa funcionalidade, mas já fora do controla directo do código da aplicação.
Aos envelopes podem estar associados outros objectos que não cartas, possivelmente em simultâneo com elas. A natureza destes objectos depende da funcionalidade a que os envelopes têm/dão acesso. Como exemplo de um destes objectos pode considerar-se um representante de um objecto remoto. Este objecto está encapsulado no contexto local por um envelope que possibilita o acesso à funcionalidade associada à distribuição de objectos. Objectos como o do exemplo serão designados colectivamente por objectos de suporte.
Os objectos de suporte têm uma existência governada pelas necessidades do módulo de que fazem parte. Alguns deles podem ser definidos pelo módulo, enquanto que outros podem ser, automática e indirectamente, gerados a partir das cartas, i.e., do código original do programador. Os objectos de suporte podem ser vistos a partir do nível de ligação, sendo o inverso também verdadeiro. São, contudo, invisíveis a partir do nível de programa, onde o único objecto do visível é o gestor do módulo.
A definição dos objectos de programa é feita de acordo com as normas da linguagem de programação utilizada. A definição dos objectos de ligação é feita, inicialmente, da mesma forma que a dos objectos de programa, sendo estes manipulados, à posteriori, para que, a partir das suas definições, sejam automaticamente gerados os objectos de ligação que lhes vão estar associados.
A geração de código será vista em maior profundidade quando se falar das ferramentas e outros meios de suporte ao desenho.
A figura 3.1 mostra a relação entre envelopes, cartas e o código que os utiliza. A primeira parte da figura mostra a situação habitual, i.e., o código da aplicação utiliza um objecto (aqui designado por carta, embora nesta situação a atribuição deste nome seja discutível). A segunda parte da figura mostra o mesmo código utilizando o que parece ser o mesmo objecto, mas é, na realidade, um envelope. A interface apresentada pelo objecto ao resto da aplicação, representada na figura pelas células contendo as entradas w, x, y e z, mantém a versão anterior podendo acrescentar, opcionalmente mais funcionalidade. Note-se que esta figura está muito simplificada e ignora particularmente a estrutura da aplicação. Deve ser tomada apenas como ilustrativa das relações entre os elementos nela constantes.
Figure: Envelopes, cartas e o resto do código.