quarta-feira, 29 de maio de 2013

HTML, CSS, Javascript - "Baixo Acoplamento e Alta Coesão" (Sim, Por Aqui Também!)

Por causa do Colabre, eu retomei muitas questões de desenvolvimento com HTML, CSS, Javascript -- todos esses assuntos relacionados a front end. E esse post foi inspirado por uma reescrita pesada nas telas. O que gostaria de dizer é:

Evite definir as mesmas classes de elementos HTML que têm propósitos de estilo e Javascript!

Por exemplo, uma classe link-especial de um elemento <a href="/exemplo" class="link-especial">Meu Link Especial</a> não deveria ser usada para deixar esse elemento vermelho, com uma borda preta em baixo e azul em cima e fazer com que elementos dessa classe, sempre que clicados, enviem uma requisição ajax para registrar um log.


.link-especial
{
 border-top: 1px solid blue;
 border-bottom: 1px solid black;
 color: red;
}

(Ok. Eu sei que esse estilo é horrível.)

E

$(".link-especial").click(function(){
 // enviar requisição ajax para registrar log...
});

Talvez para você seja óbvio o motivo de não misturar classes do DOM com propósitos diferentes. Ou talvez nunca tenha tido problema com isso. De toda forma, evite para manter uma boa separação entre estilização e de outros aspectos.

No meu caso, por exemplo, estou mudando todo o Colabre para usar o framework Bootstrap. Se não tivesse separado bem as classes de estilo e as de uso com javascript, teria um trabalho enorme para remover os estilos não mais usados. Você pode usar um prefixo para as classes de uso com javascript -- js-link-logger, por exemplo.

Os princípios de "baixo acoplamento e alta coesão" muito conhecidos na orientação a objetos não são exclusivos ;)

sábado, 30 de março de 2013

Acoplamento - Comparação Entre Web Services e Mensageria

Baixo Acoplamento e Alta Coesão são dois termos muito escutados em orientação a objetos. Se formos nas raízes dos termos, podemos fazer analogias com coisas não relacionadas a sistemas. Vamos tomar o ato de pagar uma conta em um banco como exemplo.
Focando em Baixo Acoplamento, quando você vai até a boca do caixa para pagar uma conta, um detalhe que você precisa saber é onde está o caixa; você não precisa saber quem está atrás do caixa -- tanto faz se todo dia dez você paga suas contas e sempre há um atendente diferente. Obviamente, isso não exemplifica todos os aspectos de baixo acoplamento, mas considere que não existe acoplamento com a pessoa que lhe atende, mas apenas com o caixa. O caixa (objeto não pessoa) introduz uma camada a mais entre você e o atendente -- uma camada de indireção entre vocês dois.

Em software, conseguimos baixo acoplamento adicionando níveis de indireção. Quando um objeto interage com outro por intermédio de uma interface, essa interface é uma camada de indireção. Essa nova onda de nuvem, virtualização, etc. está intrinsecamente relacionada com a indireção de recursos de computação em relação ao hardware, por exemplo.

Existe também uma questão chamada sincronismo. Quando você mantém um diálogo com uma pessoa, existe um sincronismo. Você, se for educado, espera a pessoa concluir uma ideia e então complementa o diálogo -- existe uma atenção para a ordem das falas de cada um; existe um sincronismo. O sincronismo cria um acoplamento temporal. Interações sem sincronismo (assíncronas, nos termos de software) são desacopladas temporalmente. Você pode interagir com outra pessoa deixando um recado em sua caixa postal, por exemplo. Você sabe (espera e conta com isso) que vai haver uma interação com a pessoa quando ela ouvir seu recado, mas não existe atenção ao tempo das coisas (ignorando coisas do tipo "e se eu precisar de uma resposta até tal dia?").

Web Services


Em integração/interação entre sistemas, o baixo acoplamento pode ser desejável também. Em integrações entre sistemas via web services existem os acoplamentos de tempo -- o servidor precisa estar em execução --, e localização -- quem faz a chamada, precisa fazer a chamada para um determinado endereço. A imagem a seguir mostra que uma Aplicação A (quem chama) precisa saber onde a Aplicação B (o servidor) está.


No modelo acima, por mais que exista um modelo compartilhado entre as aplicações, esse modelo terá que ser traduzido (de um formato em XML para objetos locais e vice-versa) tanto para evocar quando para responder à requisições.

RabbitMQ em Cluster


Em um modelo de integração/interação usando mensageria com RabbitMQ, por exemplo, não existe acoplamento de localização se configurarmos as instâncias do RabbitMQ em cluster, ou usando o plugin Shovel ou Federation. Para interações assíncronas, o acoplamento temporal também não existe. Entretanto, para interações onde uma resposta imediata for necessária, não há como fugir do acoplamento temporal. A imagem a seguir demonstra que uma Aplicação A não precisa saber onde está a Aplicação B. E para o caso de uma interação assíncrona, a Aplicação B não precisa nem estar em execução; basta que ela esteja em execução em algum momento no qual um requisito funcional demande.


Nesse modelo, assim como em interações via web services, também deverá haver uma tradução das mensagens para objetos locais. Como disse anteriormente, para diminuir o acoplamento, se faz necessária uma camada de indireção. Nesse caso, a camada de indireção entre as Aplicações A e B é o RabbitMQ. Tudo que as aplicações precisam saber sobre localização é o famoso e bem aventurado localhost. Obviamente, existe o acoplamento de localização em algum ponto dessa solução, mas ele é totalmente delegado à infraestrutura.

Prós e Contras das Soluções


Uma outra vantagem da solução baseada em mensageria sobre a solução com web services é a escalabilidade horizontal -- ela é natural nessa arquitetura. Uma infraestrutura baseada em instâncias RabbitMQ em cluster, permite que os sistemas envolvidos só precisem saber os nomes de suas filas e entrem em acordo sobre os tipos dos objetos que irão enviar e receber (contrato). É possível escalar horizontalmente um serviço baseado em web services, mas isso requer um esforço e configuração maiores.

Uma desvantagem sobre o modelo de mensageria apresentado em relação ao modelo com web services e como qualquer solução com menor acoplamento é o esforço de implementação. Toda camada adicional, obviamente, adiciona trabalho para construí-la. Mas, em contra partida, indireção facilita manutenção. Como tudo na vida, o segredo é sabermos ponderar as coisas levando o máximo de fatos em consideração.

quarta-feira, 23 de janeiro de 2013

Python pip ou easy_install com Proxy

Dica rápida:

É comum haver acesso à internet via proxy em redes corporativas e assim, o easy_install não funciona "de fábrica", é preciso configurar a variável HTTP_PROXY do ambiente. Por exemplo:

C:\> set HTTP_PROXY=http://usuario:senha@endereco_proxy:porta

Com isso, você deve ser capaz de usar a ferramenta pip ou easy_install do Python!

C:\> set HTTP_PROXY=http://usuario:senha@endereco_proxy:porta
C:> echo %HTTP_PROXY%
http://usuario:senha@endereco_proxy:porta
C:\> easy_install pacote
ou
C:\> pip install pacote
...

Você também pode configurar a variável https_proxy da mesma forma.