Como mudar o Perfil de uma Aplicação

Olá a todos!

A questão é a seguinte:

Tenho uma aplicação que possui funcionamento diferente para diferentes disponibilidades de recursos.

Por exemplo, se minha aplicação for CONFIGURADA para funcionar off-line, ela deve saber que NÃO-TERÁ conectividade, e assim não enviar pacotes de dados, tentar enviar alertas para outras máquinas, enfim, não tentar se comunicar. E OUTRA possibilidade é ela ser configurada para funcionar ON-LINE, mas por algum motivo temporário não possuir conectividade. Vejam que são duas situações bem diferentes.

Qual seria a melhor maneira de ter essa flexibilidade em uma aplicação?

Não é trivial; eu poderia ter uma classe que representa-se todos os recursos do equipamento (computador) e configurações da aplicação, e toda vez que for executar alguma operação que demande a checagem de algum tipo de recurso-variável, eu checaria nessa minha classe se o recurso foi configurado como ativo, e se SIM, verificar se ele está disponível, se estiver (e foi configurado para ser usado) eu executo a dita operação (que pode ser um método apenas, ou uma sequência de operações).

O problema dessa abordagem, é a poluíção de if’s no código, e também por ser muito trabalhosa para manutenção e dependiosa do ponto de vista computacional pelo fato de ter que fazer 1 ou 2 verificações a cada operação que pode ser muito simples.

Oobs.: Eu citei apenas recursos de conexão, mas poderia ser outros tipos de recursos, como processamento, memória, disco, outro hardware, etc. Porém, o de conectividade realmente é o mais utilizado.

Obrigado(a), :slight_smile:

Dê uma olha no padrão state:
http://en.wikipedia.org/wiki/State_pattern

Para que você mude o comportamento de parte do sistema sem ficar entrando em cadeias intermináveis (e horrorosas) de ifs =Z

Abraços.

[quote=xdraculax]Olá a todos!

A questão é a seguinte:

Tenho uma aplicação que possui funcionamento diferente para diferentes disponibilidades de recursos.

Por exemplo, se minha aplicação for CONFIGURADA para funcionar off-line, ela deve saber que NÃO-TERÁ conectividade, e assim não enviar pacotes de dados, tentar enviar alertas para outras máquinas, enfim, não tentar se comunicar. E OUTRA possibilidade é ela ser configurada para funcionar ON-LINE, mas por algum motivo temporário não possuir conectividade. Vejam que são duas situações bem diferentes.

Qual seria a melhor maneira de ter essa flexibilidade em uma aplicação?
[/quote]

A forma mais simples é desacoplar o que o sistema faz de como ele o faz.
Vc cria um ou mais serviços para poder se comunicar. A aplicação usa esses serviços transparentemente.
No incio da aplicação vc chega o arquivo de configuração e innicializar os serviços com base nessa configuração, ou seja, vc instancia classes diferentes.

O exemplo classico é o enviador de email. Vc cria um serviço EmailSendingService e suas implementações. Uma que envia e uma que não envia.
durante a inicialização vc checa qual deve carregar, algo assi,


public void seuMetodoDeInicializacao(){

EmailSendingService  emailService;
   if ( comunicationStatus.isOnline() ){
           emailService = new JavaMailemailService();
   }  else {
           emailService = new OffLineEmailService();
   }
}

ServiceRegistry.setEmailSendingService  (emailService);

}


// em outro lugar da aplicação

EmailSendingService   emailService = ServiceRegistry.getEmailSendingService  ();
emailService.sendEmail(email); // a aplicação não sabe se está offline ou não.

Claro que se usar um injetor de dependências é mais fácil. Mas nesse caso terá que ter uma fábrica de EmailSendingService dentro da qual vc toma a decisão de qual instancia escolher.

A ideia é fornecer as implementações conforme o ambiente e não deixar a aplicação se preocupar com isso (excepto por exceções que possam acontecer).

Interessante a ideia de criar uma classe com o conceito de serviço, funciona como uma camada.
Fica um pouco verboso, mas realmente, não tem como fazer isso de forma enxuta e natural.

Uma aplicação configurável é algo complicado de implementar (não a parte de obter, guardar e gerenciar a configuração, isso é fácil) mas sim a forma de lidar com essas configurações dentro da aplicação, gera muita “programação orientada a if´s”.

[quote=xdraculax]Interessante a ideia de criar uma classe com o conceito de serviço, funciona como uma camada.
Fica um pouco verboso, mas realmente, não tem como fazer isso de forma enxuta e natural.

Uma aplicação configurável é algo complicado de implementar (não a parte de obter, guardar e gerenciar a configuração, isso é fácil) mas sim a forma de lidar com essas configurações dentro da aplicação, gera muita “programação orientada a if´s”.[/quote]

Não se vc usar o conceito de injetor automático de dependências (IAD). As dependencias injetadas dependem da configuração do motor de injeção ( do spring etc…) mas as configurações elas mesmas podem ser montadas dinamicamente. Logo, vc reduz os ifs apenas a decidir quais configurações quer (na camada de configuração). O resto é automático e transparente.

usando um IAD vc consegue livrar-se dos ifs.

Mesmo se a configuração puder ser modificada em tempo de execução?

Sim. Muitos injetores já suportam isso nativamente ( não o spring que eu saiba) mas quando não, vc pode simular através de um factory.

Funciona assim: Todos os objetos injetados são na realidade proxies dos objetos verdadeiros. Quando a configuração é alterada
o objeto verdadeiro é alterado mas o proxy não. Então o objeto que foi injetado continua funcionando normalmente chamando agora uma classe diferente.
Se acontecer de algum método ser chamado enquanto o objeto está sendo alterado, o método do proxy bloqueia até que o objeto novo esteja disponível.

O OSGi tem este processo por default.

Interessante.

Eu tinha pensado em usar o Observer para notificar objetos que usavam algum tipo de configuração, quando essa configuração fosse alterada.
Assim, alterada a configuração, os objetos utilizadores eram notificados, e passavam a utilizar a nova configuração.

Já tive um problema muito chato com o AOP do Spring de somente o promeiro método ser chamado através do proxy e métodos internos ao primeiro dentro desse método não eram chamados através do proxy (ou seja, qualquer tratamento no proxy -uma auditoria por exemplo-, não seria mais feita depois do primeiro método).

Mas vou dar um olhada nesse framework que você falou.

[quote=xdraculax]Interessante.

Eu tinha pensado em usar o Observer para notificar objetos que usavam algum tipo de configuração, quando essa configuração fosse alterada.
Assim, alterada a configuração, os objetos utilizadores eram notificados, e passavam a utilizar a nova configuração.
.[/quote]

A sua ideia está certa, mas quem é notificado é o proxy, não o objeto que foi injetado. Desta forma vc desacopla totalmente os objetos já que eles não precisam saber que estão sendo injetados e muito menos terem que reagir a modificações