<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Ambiente Oak2</title>
</head>
<body>
<h1>Ambiente Oak2</h1>
<p>Uma questão importante para garantir a redução do acoplamento
entre as partes de um sistema de informação complexo, é a de
evitar chamadas a classes específicas para funcionalidades que
podem em geral ser substituídas por outras implementações. Por
exemplo, a camada de visualização da interface, pode precisar ser
substituída entre, por exemplo, uma UI Gtk+, Qt, ncurses
etc. Desta forma é interessante que todas essas escolhas sejam
feitas através de pontos centralizadores.</p>
<p>Este padrão é conhecido como "Class Factory". A idéia é, ao
invés de instanciar um objeto de uma classe específica, ou de
fazer o controle das alternativas em todos os pontos, delegar essa
função a uma classe especial, responsável apenas por isso.</p>
<p>E esta é a motivação do ambiente Oak2, representado pela classe
Oak2::Environment. Esta classe irá receber as requisições para
objetos que implementem determinadas APIs, e de acordo com regras
que poderão ser parametrizadas ou estendidas, fazer a escolha de
qual implementação será utilizada.</p>
<p>Qualquer aplicação Oak2 terá o seu ambiente gerenciado, ou
seja, isso fará parte da base de todo o Oak2, independente se
estamos tratando de uma aplicação de pequeno porte, ou de um
sistema de informação complexo e distribuído. Informações
específicas como chaves de autenticação, caches etc serão
gerenciados pelo ambiente.</p>
<h2>A Visão dos Serviços</h2>
<p>A classe Oak2::Environment tem uma certa similaridade com o
InitialContext da API do Java, mas existem algumas diferenças
claras. Em primeiro lugar, não é específico a uma tecnologia de
comunicação. O InitialContext é bastante atrelado ao RMI, ele é,
principalmente, um cliente JNDI. O Oak2::Environment vai permitir
que serviços se registrem nele localmente, permitindo acesso
(através dele) a classes locais e remotas.</p>
<p>Para sintetizar, o Oak2::Environment é o local onde você irá
localizar qualquer tipo de serviço, seja ele local ou remoto. É
através dele que a infra-estrutura de plugins pode ser
montada.</p>
<p>A implementação de Oak2::Environment, sozinha, não pode fazer
muita coisa, pois ela não conhece a implementação de nenhum
serviço. Qualquer serviço que vá estar disponível precisa se
registrar antecipadamente, dessa forma, qualquer aplicação Oak2 é
potencialmente cliente e servidor de qualquer serviço.</p>
<h3>Pequeno <i>background</i>: Como plugins podem fazer mágica em
um sistema de informação?</h3>
<p>Isso foi uma conclusão a qual eu cheguei após estar trabalhando
na arquitetura de sistemas de informação relativamente complexos
durante alguns anos. E foi a resposta que eu encontrei para uma
pergunta que eu sempre me fazia até então: Como criar um sistema
integrado mas mesmo assim manter o acoplamento reduzido?</p>
<p>Vamos imaginar que você tem um sistema, com o cadastro de
clientes, e que os dados dos clientes são utilizados na hora de
criar um pedido de Venda. Você precisa, na interface de venda,
permitir que o usuário navegue na lista de clientes (algo como um
combobox) para escolher qual o cliente que está efetuando a
compra.</p>
<p>Agora vamos imaginar duas situações próximas. A primeira: Em
uma das implantações do sistema os clientes não são gerenciados
pelo seu sistema. Você deve obter a lista de um outro sistema, se
mantendo integrado.</p>
<p>A segunda: Um cliente específico quer que o usuário navegue
utilizando o código de cadastro do cliente, e não o nome, mas você
não pode mudar o sistema para ser dessa outra forma porque outros
clientes continuam querendo que seja navegado pelo nome.</p>
<p>Sem pensar em plugins, que opções você tem? Implementar as três
versões e mantê-las separadamente, implementar parametrização no
componente da lista de clientes (isso imaginando que você
implementou um componente reutilizável para isso), parametrizar o
código como um todo para saber de onde buscar a lista de
clientes.</p>
<p>É possível que você já tenha passado por essa situação e é bem
provável que você tenha feito uma das três coisas. Não é tão
absurdo pensar em um if clientex faça assim, else faça assado. Eu
mesmo já cheguei a implementar coisas assim, porque se esse tipo
de situação não for contornado arquiteturalmente, não será
possível dar uma solução elegante, serão necessárias muitas
gambiarras para tornar possíveis as coisas.</p>
<p>No entanto, se o sistema tiver sido modelado utilizando
plugins, será possível não acoplar o código do registro das vendas
a nenhuma das três possibilidades, apenas à API que possibilita a
seleção do cliente, de forma que será possível definir facilmente
(sem if amarrado em código) que neste ambiente será usada esta
implementação ou a outra.</p>
<h2>E como funciona?</h2>
<p>Isso é simples. Qualquer aplicação Oak2 sempre terá carregado a
classe Oak2::Environment. Basta chamar o método, simples como:</p>
<pre>$Oak2::Environment->methodX(parameters => values)</pre>
<p>Isso é possível por que a classe é carregada pela classe
Oak2::Object. Como todos os objetos são descendentes de
Oak2::Object, ele sempre estará lá.</p>
<h3>Principais métodos</h3>
<p>Os métodos mais importantes da classe são os métodos
register_service, unregister_service e request_service. Os três
utilizam a mesma nomenclatura de URI (Universal Resource
Identifier) para os serviços, mas existem duas URIs, a primeira é
a URI da interface sendo implementada, utilizando o exemplo
anterior seria algo como "/clientes/combobox". A segunda é a URI
da implementação, que seria algo como "/clientes/combobox/byNome",
"/clientes/combobox/byCodigo" e "/clientes/combobox/remote". Esses
identificadores são as chaves para se obter os serviços.</p>
<p>É possível registrar mais de um serviço com a mesma URI de
interface no mesmo ambiente, mas a URI de implementação deve ser
única. Quando o cliente requisitar o serviço, ele irá obter uma
das implementações (se chamar o método no contexto de scalar) ou a
lista de todas as implementações (se chamar o método no contexto
de lista).</p>
<p>Para maiores detalhes, veja a documentação da classe
Oak2::Environment.</p>
<hr>
<address><a href="mailto:daniel@ruoso.com">Daniel Ruoso</a></address>
<!-- Created: Thu Apr 7 21:30:20 GMT+3 2005 -->
<!-- hhmts start -->
Last modified: Fri Apr 8 07:31:57 GMT+3 2005
<!-- hhmts end -->
</body>
</html>