Upper-box – Componente para jQuery

fevereiro 18, 2009 by admin · Leave a Comment
Filed under: JavaScript/Ajax, Programação 

Para nós, desenvolvedores, existem scripts, códigos, métodos, estruturas que carregamos conosco ano após ano. Utilizamos essas soluções empacotadas em determinados momentos, muitas vezes salvando nossas horas de descanso.

Há muito tempo, em um sistema web em que o foco era a visualização de documentos, o cliente solicitou que o menu fosse retrátil. Ou seja, o menu superior da aplicação tinha que desaparecer se não estivesse sendo utilizado e aparecer quando o cursor do mouse se aproximasse dele. Para suprir isso criei uma função Javascript (utilizando CSS), e ficou bem bacana, simples e bastante útil. Esse script eu carrego comigo desde lá.

Precisei disso novamente alguns dias atrás, mas dessa vez fiz diferente. Tornei o script genérico, de modo que posso utilizar mais facilmente em qualquer aplicação web que tenha jQuery, e ainda coloquei em um repositório no Github (repositório GIT).

Sei que ainda é bastante primitivo e não está nos padrões de plugin jQuery. Mas essa é uma das intenções de colocar em um repositório público. Quem quiser usar e acoplar funcionalidades, otimizações e mesmo dar opiniões será muito bem-vindo. Pra quem não quer nem tocar no repositório, segue o link pra download (versão mais recente). Veja um exemplo do seu funcionamento aqui.

Pra explicar o que, como, onde, vou transcrever o README do repositório no Github abaixo.

upper-box

API javascript que transforma qualquer elemento de seu HTML (uma div, por exemplo) em uma caixa móvel posicionada na parte de cima da tela.

Para utilizá-lo é necessário estar com o jQuery adicionado ao documento.

O que acontece?

O elemento upper-box vai virar uma caixa invisível na parte de cima da tela.

Quando o usuário se aproxima com o mouse da parte superior da tela (body), o elemento ira rolar, abrindo e exibindo seu conteúdo.

Como usar?

Primeiro inclua os arquivos jQuery e upper-box no seu html, desta forma:

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="upper-box.js"></script>

Seu uso é bem simples, basta adicionar upper-box ao class do elemento que vai virar upper-box.

Exemplo:

<div id='div1' class='divClass'>
 <h2>Olá,</h2>
 <p>Esta div não é um <b>upper-box</b>!</p>
</div>
<div id='div2' class='divClass upper-box'>
 <p>Esta div será um <b>upper-box</b>!</p>
 <p>Simples, não?!</p>
</div>

Espero não só ter ajudado como também ter instigado a colaboração de código.

RUP – Verdade e mitos

fevereiro 18, 2009 by admin · Leave a Comment
Filed under: Dicas, Tecnologia 

O Rational Unified Process é um processo de engenharia de software criado pela Rational que posteriormente foi adquirida pela IBM. O processo utiliza muito a UML bem como uma abordagem para projetos orientados a Objetos.

Muitos autores e profissionais da aérea questionam o uso de UML em projetos. Particularmente eu acredito que a UML traz muito valor para um projeto OO, porém devemos discernir quais diagramas são válidos para a realização da Análise de Requisitos, Design e Arquitetura. O próprio Scott Ambler questiona muito o uso “inicial” de ferramentas para a diagramação. A abordagem recomendada por ele é que após um determinado momento do projeto, quando o Domínio já está mais maduro, que seria interessante diagramar em uma ferramenta.

Bom, voltando ao RUP, vou explicar um pouco mais o processo. Talvez depois dessa explicação muitos mitos que você ouviu ou ainda ouve possam ser explicados. Caso a sessão abaixo não acabe com suas “Dúvidas, Angustias, Agonias e Tristezas” não se preocupe, no final vou fazer um resumo em grandes tópicos desmistificando diversas “Besteiras” que eu e com certeza você já deve ter ouvindo sobre o processo.

Princípios do Processo

O RUP se norteia em princípios largamente utilizados no desenvolvimento de software desde o seu surgimento até os dias presentes. O processo, ao contrário que muitos pensam, não prega que devemos fazer tudo exatamente como está no papel, ele prega que devemos seguir as boas práticas de desenvolvimento de software e ele se propõe a ser um guia que ajuda na construção de software de qualidade.

Os princípios que descreverei a seguir são utilizados há mais de uma década pela Rational com sucesso. O Processo prega que o desenvolvimento deve estar cada vez mais próximo na área de negócios, isso é o ideal que muitas vezes não é feito. Quantos de nós não cansamos de ver projetos sendo Sepultados e falhando porque não atenderam as necessidades do negócio? A idéia do processo é fazer com que de fato essas necessidades sejam atendidas.

1º Adaptar o processo: Bom, eu gosto muito de falar que esse é o primeiro principio chave do RUP, porque as pessoas acham que devem utilizar todos os Roles e Artefatos que existem no RUP. Isso só prova a ignorância e desconhecimento do processo.

O Objetivo desse princípio é dimensionar correntemente o processo para o projeto e a empresa em questão. A instrução é que devemos adaptar o grau de cerimônia e controle que o processo prove bem como o tamanho da equipe e quantidade de roles. Todos esses fatores só podem ser realizados projeto a projeto.

Estimativas iniciais: O Processo é claro quando diz que é um Anti-Pattern desenvolver estimativas antecipadas e fixas e bem como planos precisos e gerência através de ajustes nesse plano estático.

Dependendo do projeto e das características do mesmo, o uso maior de cerimônia e controle. Isso pode ser uma realidade em projetos com muitos investidores e quando existem questões de Compliance como SOX. Isso não é muito comum no Brasil (SOX), mas na Europa e Ásia é uma realidade constante, apesar de ser algo relativamente recente.

2º Equilibrar prioridades dos investidores: Esse princípio prega que devemos equilibrar as necessidades dos investidores do projeto como o desenvolvimento de customizações VS e a reutilização de recursos. A idéia do RUP é de otimizar ao máximo o valor do negócio.

O principio é guarda-chuva para a boa prática de priorização de Requisitos e até mesmo priorização de projetos. Novamente o processo é claro quando diz que é um Anti-Pattern documentar os requisitos minuciosamente no início do projeto e negar a mudança de requisitos.

De forma enfática, o RUP prega que, para podemos atender e priorizar as necessidades dos investidores de forma correta, precisamos gerenciar os requisitos efetivamente. Para que isso aconteça de forma efetiva é necessário que o cliente esteja envolvido no projeto para garantir que as necessidades do mesmo sejam compreendidas.

Reutilização: A Reutilização de recursos como sistemas legados, componentes, serviços pode reduzir os custos de um projeto em até 80%. Portanto a reutilização é necessária para que podemos equilibrar os custos. Nesse ponto o processo se encaixa perfeitamente com a Filosofia SOA. E notem que o RUP surgiu muito antes de SOA.

3º Trabalho em Equipe: Esse principio descreve como é possível desenvolver efetivamente o trabalho e colaboração através de equipes. O princípio diz que é importantíssimo desenvolver uma comunicação ampla no projeto através de ambientes de Colaboração. Vejam que muitos desses conceitos que o RUP traz são pregados por métodos ágeis. Mas o RUP veio muito antes do movimento ágil, então como isso é possível? Será que o movimento ágil se inspirou em conceitos que já existiam no RUP? Isso pode ser muito doloroso para alguns, mas a resposta é SIM!

Esse princípio prega que deve haver uma comunicação efetiva entre analistas, desenvolvedores e outros participantes do projeto, além de motivar pessoas e integração com áreas operacionais do negócio.

Novamente existe clareza na definição do processo quando se diz que é um Anti-Pattern ter desenvolvedores heróicos que trabalham horas a fio, incluindo finais de semana.

Outra questão clara e condenada pelo processo é o fato de ter desenvolvedores altamente qualificados com ferramentas e não existir colaboração e comunicação.

4º Demonstrar Valor iterativamente: O desenvolvimento iterativo Incremental que gera o famoso “Incremento de Software” é a maneira mais eficiente na maioria dos casos para se desenvolver software. Independente do processo e metodologia utilizado, usar o modelo de cliclo de vida de projeto “Iterativo incremental” é um fator chave para o sucesso.

Dentre os benefícios dessa abordagem, temos o Feedback que é importantíssimo e com ele podemos fazer correções de rumo no projeto a tempo.

Isso não é do RUP, mas eu acho fantástica a frase “Abrace as pessoas, Gerencie a mudança“. Devemos gerenciar a mudança e não simplesmente aceitá-la sem maiores entendimento e priorização. Pois se não podemos vivenciar o fenômeno de “Creep Requirements“.

No que diz respeito ao RUP, ele fala que devemos gerenciar as alterações e ele vem em uma abordagem Orientada a Riscos. Significando que devemos atacar inicialmente os maiores riscos do projeto.

Novamente o processo é claro quando diz que é um Anti-Pattern planejar detalhadamente todo o ciclo de vida do projeto. Percebam que o RUP não é contra estimativas, pelo contrario, é a favor, porém existe um momento mais apropriado para estimar, e esse momento não é no inicio do projeto. Nesse ponto que entram questões como o Cone de incertezas e modelos de contratos os quais irem falar mais em futuros posts. :)

Sobre as iterações: A idéia é que a cada iteração realizamos tarefas relacionadas a requisitos, design, arquitetura, implementação, gestão e testes. Essas atividades são repetidas durante várias iterações. Dependendo do tamanho do projeto, a diferença é que a cada iteração essas atividades estarão atuando sobre um conjunto de requisitos diferentes.

5º Elevar o nível de Abstração: Esse conceito não é brinquedo, quando digo isso estou querendo dizer que isso não é uma tarefa simples de ser efetuada. A idéia é que elevando o nível de abstração podemos diminuir a complexidade.

Essa questão está totalmente ligada à quantidade de documentação do processo. Podemos conseguir isso através de reutilização, ferramentas e de modelos arquiteturais. Mas quando eu falo arquiteturais não estou dizendo que a arquitetura deve resolver todos os problemas, mas ela deve resolver os maiores problemas. O princípio reduz a complexidade conforme já relatei antes, mas também é uma fonte poderosa de aumento de produtividade.

O RUP informa que é um Anti-Pattern você desenvolver requisitos vagos de alto nível. É outro Anti-Pattern revisar exaustivamente requisitos capturados ‘Verbalmente’. O RUP coloca como outro Anti-Pattern o fato de colocar a solução de todos os problemas na arquitetura.

Nota: Já participei de projetos em que a arquitetura resolvia tudo à base de frameworks construídos in-house. Não tenho nada contra a construção de frameworks in-house quando os mesmos têm um propósito específico e bem definido. O problema é quando os frameworks e as soluções arquiteturais tentam abraçar o mundo e resolver todos os problemas e deixam os desenvolvedores mais amarrados do que beneficiados.

Na questão da representação das abstrações, a UML é muito útil pois com ela podemos expressar bem esses modelos.

6º Foco Contínuo na Qualidade: Qualidade é algo com que sempre devemos estar comprometidos. Esse princípio do processo enfatiza que podemos atingir a qualidade através de testes contínuos. E até mesmo automação de testes, sendo que em alguns casos é relevante desenvolver uma solução arquitetural para automatização de testes.

Para que o princípio seja atendido, devemos identificar medidas e critérios. Isso não se trata de apenas “Atender os Requisitos”. A qualidade não deve residir apenas na equipe de testes, ou em profissionais de Q.A. Mas em todos os membros da equipe como analistas, desenvolvedores e gerentes.

Por fim, o processo identifica como um Anti-Pattern o ato de fazer com que os testes aconteçam somente em uma fase e conduzir testes detalhados em todos os artefatos.

Além desses princípios chave do processo, o RUP é centrado na Arquitetura e em casos de Uso. Casos de uso não significa que têm que ser visuais conforme o diagrama de casos de uso da UML, mas eles podem ser textuais.

O processo é iterativo Incremental, sendo que ele possui marcos. Esses marcos nos ajudam a nos situarmos no projeto e ver se o projeto tem condições de continuar em termos de riscos e se estamos no rumo correto.

A figura acima mostra as fases do processo (Inception, Elaboration, Construction e Transiction), para detalhar as fases e o propósito de caso preciso de outro post. :) Na seqüência (em outro post) estarei detalhando essas fases.

Mas o propósito da figura, que também é conhecida como gráfico de baleias, é mostrar as disciplinas do projeto como (construção, requisitos, configuração, etc..) através das iterações e com os marcos de fases. O gráfico de baleias mostra a intensidade das disciplinas através das iterações e fases. Pelo amor de Deus não confunda isso com Cascata!

Realizando a Adaptação

Também conhecido como tailoring. Essa palavra é temida por muitas pessoas, mas não podemos condenar nossos irmãos mais ignorantes e desprovidos de informações. Baseados nesses conceitos chaves do RUP que apresentei acima, podemos realizar o tailoring do processo de acordo com as necessidades do mesmo.

O RUP define uma série de elementos essenciais que você deve considerar seriamente ao realizar o tailoring do processo. São os elementos:

1. Visão do projeto: Devemos desenvolver uma visão do projeto para deixar registrados os interesses do projeto bem como os seus objetivos e requisitos que devem ser atendidos. Esse recurso nos possibilita alinhamento com os stakeholders do projeto e membros da equipe técnica.

2. Plano de Gerência: Devemos desenvolver um plano de desenvolvimento e gerência do projeto. No plano do projeto iremos expor o planejamento do projeto de forma aberta demonstrando os recursos necessários como orçamento, escopo e pessoas.

3. Mitigar Riscos: Esse é outro ponto essencial em um tailoring do RUP. Sempre devemos levantar os maiores riscos para o projeto e planejar formar de ação contra esses riscos. Devemos criar uma Lista de Riscos e através dela dirigir ações e decisões do projeto.

4. Casos de Negócio: São as informações necessárias do negócio que nos dizem se vale a pena ou não investir no projeto. Seu propósito é para viabilizar o plano econômico do projeto bem como questões relativas a ROI. Através dele são criados argumentos convincentes em termos de Custo vs. Benefícios que dão base à criação do projeto.

5. Projete uma Arquitetura: Com o aumento da complexidade em termos de desenvolvimento de sistemas, uma arquitetura se faz necessária sendo uma estrutura base que trata e interfaceia os principais problemas da aplicação.

6. Uso de Protótipo: Utilizar protótipos para refinar e entender os requisitos e necessidades do usuário. Esse uso está relacionado à idéia de desenvolvimento iterativo e incremental e com testes.

7. Avaliação de Resultados: É importante a comunicação aberta e freqüente provida através de Feedback. Freqüentemente devemos medir os resultados do produto de software e com isso realizar as correções de rumo necessárias para atender as necessidades do cliente bem como a acomodação de mudanças. Sendo que a avaliação da iteração é um elemento chave no desenvolvimento iterativo e incremental.

8. Controle as mudanças: Controlar mudanças não significa “barrar” mudanças. Mudanças sempre irão ocorrer, isso é fato, mas o que devemos fazer é passar essas mudanças por um mecanismo de controle de mudanças gerências por um processo consistente. Uma das vantagens do controle de mudanças é o fato de possibilitar a análise de impacto, que é uma poderosa ferramenta que pode nos “dizer” o quanto será custoso implementar essa mudança.

Nota: Você pode realizar mudanças com ou sem análise de impacto. A questão é que com análise de impacto você sabe onde está pisando. Sem a análise de impacto você pode tomar um susto no momento de codificar a mudança!

9. Suporte ao Usuário: Aqui o RUP se preocupa com questões de “Usabilidade”. E como são importantes essas questões. Dependendo do produto de software, é necessário ter até um guia ou documentação procedente de como se deve utilizar o produto. Essa necessidade irá variar de acordo com o projeto.

10. Adotar um processo: É fundamental escolher um processo que se adapte ao projeto e a organização em questão. Aqui o RUP se referencia ao seu primeiro conceito chave: Adaptar o processo. As questões de adaptação de projetos o RUP tratam em sua disciplina de ambiente.

Verdades e Mitos

Como mencionado antes, espero que após você ter lido o que eu escrevi, diversas “Bobagens” tenham saído de sua cabeça. Mas se isso não aconteceu, agora vou ser mais direto. Então vamos a algumas verdades.

Verdades

  • O RUP é um processo de desenvolvimento de software com um grau de cerimônia maior.
  • É pago, logo o acesso as informações é dificultado
  • Com certeza é o processo mais utilizado hoje em dia, porém foi e é utilizado de forma errada.
  • Consultorias do processo são caríssimas.

Mitos

O RUP é Cascata: Eu já cansei de ouvir isso. Muitas pessoas pensam que o RUP é cascata. Se você leu o que eu escrevi acima vai ver que eu disse “Iterativo Incremental”. O RUP não é Cascata!

O RUP é pesado: Essa é outra besteira, o que é pesado é a burrice das pessoas. O que pesa é o tailoring do RUP que você faz ou, muitas vezes, o tailoring que você não faz. Existem cenários em que o RUP vai ser realmente muito cerimonioso e formal, porém isso depende da situação. E o fato de algo ser formal não significa que é ruim, depende muito da situação. O RUP não é pesado!

O RUP prega BIG Especs. Up to Front: De forma alguma! Muitos utilizadores do processo acabam cometendo esse erro. Mas se você leu o que eu escrevi acima não vai mais acreditar nisso. Infelizmente esse erro é muito comum dentro os utilizados da metodologia, muitas vezes por desconhecimento. O RUP não prega BIG Especs. Up to Front.

Casos de uso Textuais são ruins: Olha, pessoal, a forma mais amorosa que eu tenho para responder isso é bom… não vou nem falar. O RUP é baseado em casos de uso, além do mais casos de uso são eficientes para especificarmos. Casos de uso não são ruins.

Com o RUP podemos ter pessoas ‘mais fracas’: Pro diabo! Eu já cansei de ouvir isso também. E o pior de utilizadores da metodologia. O RUP não especifica isso em lugar algum na especificação do processo. Com pessoas ‘fracas’ ou ‘incompetentes’, o resultado será ruim. Não existe processo ou metodologia no mundo que consiga obter sucesso com pessoas ‘fracas’. O RUP não encoraja esse tipo de loucura.

Infelizmente as empresas ainda usam o modelo em cascata, e em muitas vezes tentam transvestir esse modelo em cascata com uma roupinha do RUP. Ao meu ver o processo é bom e pode ser utilizado em diversos cenários.

E quanto às metodologias Ágeis?: Acredito que uma coisa não elimina a outra. É extremamente valioso nós unificarmos valores ágeis com processos de software que o RUP prove. Acredito que sempre devemos estar buscando o equilíbrio projeto a projeto: de disciplina a cerimônia vs. agilidade.

O RUP é um processo muito bom que pode ser utilizado em diversos cenários. O que devemos fazer é adaptar o processo de forma correta sempre pensando nos 6 conceitos chave do processo que descrevi nesse post.

Programação orientada a eventos e lambda function em ASP/VBScript

fevereiro 12, 2009 by admin · Leave a Comment
Filed under: ASP, Programação 

Programação orientada a eventos

A programação orientada a eventos, também conhecida como programação baseada em eventos, é um paradigma de programação, isto é, um estilo fundamental de se programar, no qual a execução do programa é afetada por eventos(geralmente detectados por sensores).

Esta forma de se programar é, na minha humilde opinião, a base de todos os sistemas de UI(User Interface) sofisticados. Por exemplo, aquela barrinha do MAC OSX que todos adoram e suas similares:

RocketDock

Ela nunca abre uma janela solicitando “Vá com o mouse para cima de um ícone e clique”, ela simplesmente possui um sensor que avisa “Olha, programa, detectei que o mouse entrou na posição (x,y) da barra”, ao receber esta mensagem o programa faz o zoom e mostra o label dos ícones na posição. Este parece um exemplo bobo, mas acho que ilustra bem a diferença entre a programação em lote e a programação orientada a eventos.

É importante para um programador web conhecer a programação orientada a eventos, pois uma das características mais marcantes da Web 2.0 é a grande quantidade de widgets que fazem parte das chamadas RIA(Rich Application Interface) que são aqueles programas com telas que você pensa “Que legal isso aqui!”.

Uma outra coisa importante a ser notada é que os paradigmas de programação não são mutuamente exclusivos, isto é, uma linguagem, e por conseqüência um programa, pode suportar múltiplos paradigmas. Um programa pode ser puramente em lote, puramente orientado a eventos, ou conter trechos de ambos os paradigmas. Pode-se, portanto, criar programas meio orientado a objetos/procedurais, meio orientado a eventos/lote. Um arquiteto de software experiente saberá qual o melhor paradigma a ser seguido para construir um determinado feature do programa.

Apesar desta forma de se programar poder ser executada em qualquer linguagem de programação, ela é facilitada por linguagens com noções funcionais como JScript, Lisp (a segunda linguagem mais antiga da nossa história), Haskell entre outras. Nos exemplos a seguir mostrarei como programar:

  1. Utilizando-se apenas VBScript.
  2. Fazendo um bridge simples com JScript para utilizar a noção de lambda que ela possui (um bom exercícío aqui é utilizar a noção de lambda do Python para alcançar o mesmo objetivo).

Nota: O segundo exemplo é um dos motivos pelos quais julgo o ASP extremamente versátil, pois ele mostra uma aplicação do conceito exposto no primeiro artigo.

Função lambda

Para aqueles que ainda não foram apresentados, a função lambda é um feature interessante que nasceu com o Lisp e permite você definir e utilizar funções em tempo de execução. Esta é uma das características que facilitaram o desenvolvimento de AI(Artificial Intelligence) (pense em um algorítimo recursivo que gera, interpreta e executa funções para gerar, interpretar e executar funções e vai aprendendo alguma coisa importante durante o processo).

Mãos à massa

Utilizando-se a classe CustomEvent(versão sem comentários) que escrevi para o AXE(ASP Xtreme Evolution), mas que funciona out-of-the-box e tem licensa MIT:

<%

class CustomEvent

    public classType
    public classVersion

    public Owner
    private Handlers
    public Arguments

    private sub Class_initialize()
        classType    = typename(Me)
        classVersion = "1.0.0"

        set Handlers  = Server.createObject("Scripting.Dictionary")
        set Arguments = Server.createObject("Scripting.Dictionary")
    end sub

    private sub Class_terminate()
        Handlers.removeAll()
        Arguments.removeAll()
        set Handlers  = nothing
        set Arguments = nothing
    end sub

    public sub addHandler(fn)
        select case typename(fn)
            case "JScriptTypeInfo"
                set Handlers.item(fn.toString()) = fn
            case else
                set Handlers.item(fn) = getRef(fn)
        end select
    end sub

    public sub removeHandler(fn)
        set Handlers.item(fn) = nothing
        Handlers.remove(fn)
    end sub

    public sub fire()
        dim fn : for each fn in Handlers
            Handlers.item(fn)(Me)
        next
    end sub

    public function revealArguments()
        revealArguments = ""
        dim arg : for each arg in Arguments
            revealArguments = revealArguments & ", " & arg
        next
        revealArguments = mid(revealArguments, 3)
    end function

end class

%>
<script language="javascript" runat="server">
function lambda(f) {
    if(/^function\s*\([ a-z0-9.$_,]*\)\s*{[\S\s]*}$/gim.test(f)) {
        eval("f = " + f.replace(/\r/g, '').replace(/\n/g, ''));
        return f;
    } else {
        return function() {};
    }
}
</script>

Você pode criar eventos nas suas classes como no exemplo de classe abaixo,
que será utilizada nos exemplos 1 e 2:

<%

class ClassWithEvents
    public classType
    public classVersion

    public onComplimentBefore' [1]
    public onComplimentAfter

    private sub Class_initialize()
        classType    = typename(Me)
        classVersion = "1.0.0"

        set onComplimentBefore = new CustomEvent : set onComplimentBefore.Owner = Me' [2]
        set onComplimentAfter = new CustomEvent : set onComplimentAfter.Owner = Me
    end sub

    private sub Class_terminate()
        set onComplimentBefore = nothing' [3]
        set onComplimentAfter = nothing
    end sub

    public sub compliment(firstname, lastname, nickname)
        onComplimentBefore.Arguments.item("firstname") = firstname' [4]
        onComplimentBefore.Arguments.item("lastname")  = lastname
        onComplimentBefore.Arguments.item("nickname")  = nickname

        call onComplimentBefore.fire()' [5]
        Response.write("Method compliment called." & vbNewline)
        call onComplimentAfter.fire()
    end sub

end class

%>

Exemplo 1

Utilizando a classe que possui eventos para criar objetos com eventos em VBScript:

<code><pre><%

sub ev_onComplimentBefore(ev)' [6]
    Response.write("Event onComplimentBefore has been fired.
I was really expecting this method to say:
'Hello World " & ev.Arguments.item("firstname") & " " &
ev.Arguments.item("lastname") & " (" & ev.Arguments.item("nickname") & ")'" & vbNewline)
end sub

sub ev_onComplimentAfter(ev)
    Response.write("Event onComplimentAfter has been fired" & vbNewline)
end sub

dim CwE : set CwE = new ClassWithEvents
call CwE.onComplimentBefore.addHandler("ev_onComplimentBefore")' [7]
call CwE.onComplimentAfter.addHandler("ev_onComplimentAfter")
call CwE.compliment("Fabio", "Nagao", "nagaozen")
set CwE = nothing

%></pre></code>

O código acima deve escrever na tela do seu navegador:

Event onComplimentBefore has been fired. I was really expecting this method to say: ‘Hello World Fabio Nagao (nagaozen)’

Method compliment called.

Event onComplimentAfter has been fired

Seguem abaixo as notas de rodapé [#] que deixei no código fonte:

  1. Definindo os eventos.
  2. Inicializando os eventos como tipo CustomEvent e atribuindo um ponteiro à instância da classe através da propriedade Owner.
  3. Liberando os eventos criados na etapa 2 da memória.
  4. Definindo os argumentos do evento.
  5. Avisando o sensor que ocorreu um evento.
  6. Configurando ações para um determinado evento.
  7. Configurando o sensor para observar um evento.

Exemplo 2

Ok, o exemplo 1 foi legal, mas a maioria das pessoas acostumadas com programação orientada a eventos vai reclamar daquelas subrotinas da nota [6]. O que é natural, pois aquilo é pouquíssimo intuitivo. Afinal de contas, se os eventos estão relacionados ao objeto e somente a ele, porque não os definir dentro do próprio objeto? Bom, isso é verdade, o problema é que o VBScript não possui nenhum método para fazer isso dentro do objeto. Aqui, novamente IMHO(In My Humble Opinion), as alternativas naturais seriam:

* ou extender a classe ClassWithEvents para outra classe que possuísse as definições das ações do evento e depois criar uma instância dessa nova classe, o que é impossível pela noção de objetos do VBScript;

* ou utilizar a noção de lambda function, que também não existe no VBScript.

Então, o que fazer? Se render às limitações expressivas da linguagem? Jamais! Afinal de contas, não adianta mudar de linguagem, pois qualquer linguagem sempre tem limitações, não é verdade?

A solução, dentro do ASP, é mais fácil do que se imagina. Você fala JScript? Python? Haskell? Nossa, o ASP também! Essas linguagens possuem uma capacidade expressiva funcional? Siiim! Pronto, resolvido o problema!

Explicando melhor: Para aqueles que ainda não perceberam, juntamente com a definição da classe CustomEvent, criei também uma função global em javascript (que é a mesma coisa que JScript) chamada lambda. Essa função recebe a definição de uma função, interpreta e retorna a função interpretada. Javascript é uma linguagem tão bonita que incorporou o conceito de lambda ao seu núcleo e portanto ela usa lambda sem ter uma palavra reservada para isso (diferentemente do Python). Esta função, dentro do ASP, não é global apenas para o JScript, ela é global para a aplicação inteira, isto é, você pode invocar ela do VBScript. Com essa nova função em mãos, podemos transformar o exemplo 1 no seguinte:

<%

dim CwE : set CwE = new ClassWithEvents
call CwE.onComplimentBefore.addHandler(lambda("function(ev){ Response.write('Event onComplimentBefore has been fired. I
was really expecting this method to say: \'Hello World ' + ev.Arguments.item('firstname') + ' ' +
ev.Arguments.item('lastname') + ' (' + ev.Arguments.item('nickname') + ')\'\r\n') }"))
call CwE.onComplimentAfter.addHandler(lambda("function(ev){ Response.write('Event onComplimentAfter has been fired') }"))
call CwE.compliment("Fabio", "Nagao", "nagaozen")
set CwE = nothing

%>

Que também imprime a mesma mensagem do exemplo 1 na tela do navegador. Convenhamos, ficou bem melhor agora, não? Muito mais intuitívo também.

Resumo da história

O paradigma de programação orientada a objetos aplicado juntamente com o de programação orientado a eventos, permite ao programador criar ambientes que se assemelham muito à forma que compreendemos os objetos e eventos no nosso mundo físico. Por exemplo, estamos acostumados a atravessar a rua quando o semáforo está verde e a parar quando está vermelho. Um programador, ao tentar modelar este ambiente, pode criar, por exemplo, as classes “Pedestre” e “Semáforo”. O “Pedestre” tem um método “.andarPara(local)” que diz para ele ir para algum local. Este método, possui um sensor “onSemáfaroVermelho” que aciona o procedimento “.parar”, quando o sensor do pedestre receber “onSemáfaroVerde” do “Semáforo”, então ele chama “.andarPara(local)” novamente.


Tecnologias para ajudar as empresas a crescer e economizar

fevereiro 12, 2009 by admin · Leave a Comment
Filed under: Dicas, Tecnologia 

Vou listar a seguir algumas opções que as pequenas e médias empresas têm para economizar e ajudar seu crescimento nestes tempos “bicudos”.

A primeira destas tecnologias é a computação em nuvem. Neste caso, processamento, armazenamento em disco ou aplicativos são oferecidos como serviços através da Internet (algumas opções gratuitas). Os dados e aplicativos ficam espalhados por diversos datacenters distribuídos pelo mundo e os usuários não sabem (nem precisam saber) onde eles estão. Bons exemplos são serviços do Hotmail ou Google, como Gmail, Google Docs e Google Sites.

Para situações mais específicas existem serviços pagos, mas ainda assim podem ser bem econômicos por não necessitarem de pessoal especializado ou gastos com uma infraestrutura avançada de TI. Nesta categoria encontramos aplicativos de CRM (Customer Relationship Management - Gerenciamento do relacionamento com clientes -, Acompanhamento de força de vendas ou ERP (Enterprise Resource Planning – Sistema integrado de gestão empresarial. Não podemos esquecer os serviços de hospedagem de servidores.

A tecnologia de VoIP (Voz sobre IP) permite a transmissão da voz através de redes de computadores privadas ou a Internet. Isto faz com que o custo das ligações não dependa da distância entre a origem e o destino. Esta característica pode economizar de 40% a 85% na comunicação telefônica e reduzir um peso significativo nas contas das empresas. Além do Skype, você pode contar com uma grande quantidade de operadoras de VoIP instaladas no Brasil. Para conhecer as opções existentes entre no site da Anatel, clique na aba “Informações Técnicas”, depois no item “Comunicação Multimídia” e no subitem “Empresas Autorizadas”.

Ter o produto certo na hora certa e reduzir estoques desnecessários é uma outra forma de economia. Para isto a logística inteligente é uma grande aliada. Sistemas de logística e controle de estoque online, coletores de dados, aplicativos de cálculo de rotas e etiquetas inteligentes (RFID) podem ajudar a aumentar o giro dos produtos.

No próximo artigo volto com mais algumas tecnologias que podem ajudar as empresas a enfrentar estes tempos difíceis da economia.

Programando em equipe

fevereiro 5, 2009 by admin · 1 Comment
Filed under: Dicas, Tecnologia 

O desenvolvimento de um software consiste em um grupo de pessoas manuseando os mesmos arquivos fontes e componentes. Se um indivíduo deste grupo não conseguir escrever a sua parte de forma clara, de fácil compreensão e manutenção, o projeto estará comprometido a uma série de conseqüências problemáticas. Entendo que isso é uma situação de peso, uma vez que a manutenção representa em média 80% do tempo de vida de um sistema.

Ao longo das consultorias em projetos de que venho participando, diagnostiquei que os programadores em geral não sabem o significado de se “Programar em Equipe”. Percebo que é um problema de nível cultural e acredito que isso possa ser revertido se cada um pensasse da seguinte forma:

Eu estou trabalhando em uma equipe, por isso eu tenho que me esforçar ao máximo para implementar este requisito da forma mais simples, clara e de fácil manutenção possível…porque haverá algum momento no ciclo de vida do desenvolvimento que um companheiro de equipe precisará alterar ou complementar o que eu fiz e inevitavelmente eu também precisarei manusear algum código que foi construído por outra pessoa.

Acredito que o fato acontece por 3 motivos:

  • Pessoas remanescentes de outras tecnologias/ferramentas nas quais não existiam esta filosofia.
  • O desconhecimento de que na tecnologia Java existe um padrão de codificação.
  • A falta de uma sólida base de princípios de projeto orientado a objeto.

1. Pessoas remanescentes de outras tecnologias/ferramentas nas quais não existiam esta filosofia:

Eu percebo que atualmente existe uma galera muito inteligente e esforçada que vem migrando de outras tecnologias para o Java e que realmente tem conseguido produzir softwares funcionais, entretanto 100% deles deixam muito a desejar neste ponto. Percebo que o pessoal traz seus costumes e hábitos de programação para dentro do Java.

2. O desconhecimento de que na tecnologia Java existe um padrão de codificação:

Em Java existe uma forma padrão de como se deve ser escrito um código fonte. Ou seja, o autor não tem a liberdade de ficar usando/inventando uma série firulas, gafs, comentários, regras de espaçamentos sem coerências, delegação de nomes para identificadores completamente malucos etc….. Existe um documento chamado “Java Code Conventions” que possui todas as regras e diretrizes previamente estudadas e estabelecidas para que qualquer pessoa em qualquer lugar no mundo possa escrever o mesmo código fonte. Isto quer dizer o que? Quer dizer que uma pessoa de um lado do mundo pode abrir o código fonte de uma outra pessoa, do outro lado e ter a sensação de que ela mesma que escreveu! Sendo que ambos devem seguir a convenção de codificação.

3. A falta de uma sólida base de princípios de projeto orientado a objeto:

Fácil manutenção está intimamente ligada à utilização de princípios e diretrizes da filosofia orientada a objetos e é aqui onde o galera mais deixa a peteca cair! Como é incrível ver o pessoal mesmo usando uma tecnologia OO conseguir programar usando conceitos procedurais/globais e fazer uma coisa simples OO virar um monte de macarrão trançado. Sempre lembrando que a POO é uma filosofia e pode ser furada fácil, fácil, em qualquer parte do projeto.

Segue abaixo a lista resumida dos erros mais comuns:

* Estado do objeto – Não use variáveis de instâncias para controle de fluxos locais! Variável de instância é usada para definir estado do objeto durante seu ciclo de vida. Caso precise controlar algo localmente, use variáveis locais.

* Declaração de variáveis – Somente declare e inicialize as variáveis locais antes (o mais próximo o possível) de serem usadas! Único momento onde é aceitável declarar uma variável muito longe de sua utilização é em caso de utilização fora de escopos de controle de fluxo ou loop. Mesmo assim, mantenha em mente que você deve declarar sempre o mais perto possível.

* Escopo de variáveis – Sempre reduza os escopos das variáveis o máximo possível! Nunca declare uma variável fora de um escopo lógico (while, if, do/while, for) se você só vai precisar da variável dentro dele.

* Nomeação de variáveis – Independente do seu escopo (instância ou local), os nomes das variáveis devem ser auto-explicativos! Não coloque nomes sem sentido ou com apenas um caractere! Único lugar aceitável para se colocar uma variável com um único caractere é no contador de um for, o resto tem que possuir um nome significativo dentro do contexto de implementação. Outra coisa, não faça nomes grandes demais, resuma ou procure um sinônimo menor.

* Nomeação de classes e métodos – Nome de classe geralmente é um substantivo que reflete a abstração da automação de alguma coisa do mundo real, e os nomes dos métodos devem ser verbos que refletem ações que um objeto da classe faz. Qualquer coisa que passar disso fará com que o projeto fique completamente ilegível e confuso! Única possibilidade de exceção a este caso seria a possível utilização de design patterns dentro da arquitetura.

Programador procedural no mundo orientado a objetos:

* Reduza a visibilidade da classe – Nunca deixe público e exposto pela classe algo que somente está sendo usado por ela internamente (atributos e métodos). Quanto mais coisas públicas as classes possuírem, menos flexibilidade de manutenção ela terá.

* Use sobrecarga de métodos – Dê preferência à sobrecarga de métodos em vez de ficar implementando controle de lógica baseado na passagem de parâmetros.

* Longas listas de argumentos – Métodos com muitos parâmetros refletem em geral a falta de percepção de que está faltando a criação de um objeto que contivesse estes dados devidamente encapsulados, utilizado posteriormente como agregação.

* Classes sem métodos ou sem atributos – A classe é a expressão de um componente portador de características e comportamentos. Salvo em raros casos, na utilização consciente de design patterns.

* Reutilização de código - Na POO podemos reutilizar código de duas formas: por herança ou agregação. Sempre faça uma análise crítica no caso de qual utilizar, mantendo em mente de que a agregação é a forma mais flexível. Entretanto, existirão casos de herança (considere casos de classes abstratas). De forma alguma faça CTRL+C e CTRL+V nas classes por menor que seja a circunstância!

* Polimorfismo sempre - Use indiscutivelmente quando puder argumentos, variáveis, tipos de retornos polimórficos. Não existe nenhuma outra coisa na POO que ofereça mais flexibilidade e manutibilidade como a codificação polimórfica.

* Classes Enormes – Isso é uma das picaretagens mais feias que podem ser feitas contra o patrimônio OO!!! Nunca faça classes longas, cheias de métodos, resolvendo tudo……é o famoso canivete suíço. Passe um pente fino nas classes usando a SRP – Single Responsability Principle – na qual afirma que cada classe deve ser implementada para resolver apenas uma situação, uma responsabilidade! Busque a granularidade certa entres as classes do seu projeto, considerando, é claro, o escopo em questão.

* Métodos Enormes – Métodos grandes, cheios de controle de fluxo normalmente devem ser analisados e fracionados em métodos menores com visibilidades mais restritas.

* Abuso em Recursos Estáticos – Outra ofensa contra o patrimônio OO! Na POO não existem funções e variáveis globais perdidas no espaço mágico do mundo encantado! Tudo é objeto se relacionando com outro objeto através de seus estados e ações. Classes que apresentam abusos deste recurso expressam que o programador (autor) não conseguiu visualizar as abstrações e seus relacionamentos dentro do contexto da implementação. Recursos estáticos representam um escopo especial que é compartilhado por todos os objetos de uma classe e devem ser usados para satisfazer somente este caso.

* Nunca Reinvente a Roda – O Java tem 14 anos (desde 1995) de existência e apresenta uma série de recursos agrupados pelas plataformas. Fora isso, existem muitos produtos proprietários, open-source ou pagos e, por esse motivo, nunca tente elaborar ou inventar algo do zero antes de pesquisar a fundo! Porque na maioria dos casos você vai achar alguma coisa pronta (classe, componentes, framework, especificação, produto open-source ou proprietário pago com preço acessível) para resolver aquilo que você está necessitando!

* Encapsulamento - Sempre esconda as estruturas internas de uma classe e controle o acesso ao estado dos objetos através do encapsulamento usando a padronização JavaBean.

* Implemente as Regras Arquiteturais - Se uma classe é a última da hierarquia, declare como final!! Se um método não pode ser anulado, declare com final! Se um argumento ou variável não deve ser mudado, declare como final etc… Ou seja, impeça ou force polimorfismo, libere ou restrinja visibilidades em herança ou agregações. Entenda seu domain model e expresse-as no modelo de classes!

* Ciclo de vida dos objetos – Sempre programe pensando em cooperar com o coletor de lixo!! Ou seja, analise bem os escopos de criação dos objetos (estático, instância ou local) e os libere (atribuindo null para as referências) logo após verificar que não irá mais utilizá-los. Perceba que esta prática deixa o código claro e legível.

* Modere a Criação de Objetos – Sempre seja moderado na criação de objetos, nunca criando mais do que você precisa, sendo que o coletor de lixo é muito eficiente, mas não faz milagres. Quando possível, tente reusar os mesmos objetos reiniciando-os ao seu estado inicial. Analise cada new que você declarar!! Em aplicações de médio/grande porte isso pode resultar em uma grande economia e conseqüentemente performance.

Controlando condições excepcionais:

* Controle de Erros – Nunca use como controle de erros com retorno de booleano ou códigos de erros! Em Java existe uma mecânica padronizada chamada de tratamento de exceções. Lance exceções indicando as condições excepcionais, usando classes existentes no core do JSE ou não tenha receio de criar as suas próprias quando necessário.

* Propagação de Exceções – Nunca propague uma exceção ocorrida de dentro de uma camada lógica para fora da mesma, sendo que a outra camada cliente não deve conhecer detalhes internos de execução. Neste caso propague outras exceções mais significativas referentes ao contexto da camada/componente/classe ou serviço.

* Exceções Polimórficas – Nunca use o tratamento de exceções de forma polimórfica! Sempre encadeie os catch de todas as exceções, deixando o código claro e legível para o próximo programador amigão do peito!

* Comendo Exceções – Nunca faça um try sem colocar nada no catch! No mínimo, tem que existir uma impressão da lista do trace ou substitua, se possível, o try por um if identificando a condição.

* Fluxo de Controle em Exceções – Nunca use um try/catch como fluxo de controle!! Ou seja, não baseie nenhuma lógica condicional no controle de exceções. O próximo programador agradece a legibilidade do seu código.

Arquitetura de Data Warehouse – Parte 01

fevereiro 5, 2009 by admin · Leave a Comment
Filed under: Dicas, Tecnologia 

A escolha da arquitetura é uma decisão gerencial do projeto e está baseada (normalmente) nos fatores relativos à infra-estrutura atualmente disponível (que se for o caso de aquisição do mesmo), ao ambiente de negócios, escopo desejado, além de capacitação dos recursos disponibilizados no projeto e funcionários da empresa projetos para tal investimento.

O DW é projetado e construído com base nas necessidades da empresa como um todo e considerado um repositório comum de dados de suporte à decisão, disponível em toda a empresa.

A arquitetura global pode ser fisicamente centralizada ou fisicamente distribuída nas instalações de uma empresa.

A centralização física é utilizada quando a empresa existe em um único local e o DW é administrado por alguma pessoa ou recurso de TI.

A distribuição física de um DW é utilizada quando a empresa possui diversos locais físicos (instalações) e os dados em múltiplas instalações físicas. Também é administrado por alguém do departamento de TI.

Obs.: Quando o departamento de TI adminstra o DW, isso não quer dizer que o departamento de TI controla o DW. Isso pode ser feito por outro departamento ou até mesmo por uma empresa especializada em controle e administração de DW, pois é ele quem decide quais e que dados irão entrar no DW e quando devem ter a carga incremental (atualização), além de como outros departamentos irão acessar, que pessoas podem acessar os dados, etc.

Dentro desse contexto, resume-se que a implementação e a administração devem ser realizadas por um departamento e profissionais específicos da área de TI, até porque o departamento de TI é o que administra a rede interna de comunicação de dados da empresa.

A figura a seguir mostra a arquitetura de um Data Warehouse, considerando que a implementação é top-down (relembrando o artigo anterior: Top-Down é quando a empresa cria um DW e depois parte para a segmentação, ou seja, divide o DW em áreas menores gerando assim pequenos bancos orientados por assuntos aos departamentos.), ou seja, segundo Inmon, direto ao DW.

Arquitetura de Data WarehouseArquitetura de Data Warehouse

Os dados são extraídos de sistemas transacionais (OLTP) e/ou de fontes de dados externas, seja via arquivo local (TXT, XML por exemplo) ou ainda por um ERP.

Os dados são filtrados, sendo eliminados os dados não necessários e realiza-se o processo de ETL, que é a extração, transformação e carga desses dados e metadados, que, então, posteriormente e logicamente, são carregados no DW.

A partir do DW, os dados e metadados são extraídos para os Data Marts (DM), que, por sua vez, as informações estão em maior nível de sumarização e, normalmente, não apresentam o nível histórico encontrado no DW.

Essa implementação tem como lado positivo o fato de “forçar” a empresa a definir regras de negócio de forma corporativa antes de iniciar-se projeto de DW em si.

Vantagens e devantagens dessa arquitetura:

Vantagens:

  • Herança de arquitetura: todos os DM originados de um DW utilizam a arquitetura e os dados desse DW, permitindo uma fácil implementação.
  • Visão de empreendimento: o DW concentra todos os negócios da empresa, sendo possível extrair dele níveis menores de informações.
  • Repositório de metadados centralizado e simples: o DW provê de um repositório de metadados central para o sistema. Essa centralização permite manutenções mais simples do que aquelas realizadas em múltiplos repositórios.
  • Controle e centralização de regras: a arquitetura top down garante a existência de um único conjunto de aplicações para extração, limpeza e integração dos dados, além de processos centralizados de manutenção e monitoração.

Desvantagens:

  • Implementação muito longa: os DW são, normalmente, desenvolvidos de modo iterativo, por áreas de assuntos, como por exemplo, vendas, finanças e recursos humanos. Mesmo assim, são necessários, em média 15 ou mais meses para que área de assunto entre em produção, dificultando a garantia de apoio político e orçamentário.
  • Alta taxa de risco: não existem garantias para o investimento nesse tipo de ambiente.
  • Heranças de cruzamentos funcionais: é necessária uma equipe de desenvolvedores e usuários finais altamente capacitados para avaliar as informações e consultas que garantam à empresa habilidade para sobreviver e prosperar na arena de mudanças de competições políticas, geográficas e organizacionais.
  • Expectativas relacionadas ao ambiente: a demora do projeto e a falta de retorno podem induzir expectativas nos usuários.

No próximo artigo, continuarei abordando a arquitetura de DW, mais precisamente sobre a implementação Botton Up e de Implementação Combinada.

Referências Bibliográficas:

Tecnologia e Projeto de Data Warehouse, Felipe Nery Rodrigues Machado, 2007.

.NET – Invocação de objetos Remotos (Remoting)

fevereiro 2, 2009 by admin · Leave a Comment
Filed under: .Net, Programação 

O .NET Remoting suporta a comunicação de objetos distribuídos pela utilização da representação binária ou SOAP do fluxo de dados.

Sendo mais direto: O .NET Remoting proporciona que seus aplicativos tenham comunicação com sistemas remotos utilizando protocolos de comunicação.

Uma das vantagens é que podemos aproveitar os recursos de um projeto desktop (Windows Forms) em um projeto web usando o .NET Remoting, efetuando troca de informações entre os processos através de métodos e funções. Dessa forma temos que os objetos distribuídos representam serviços que uma camada de componentes oferece para uma camada de apresentação do sistema. Lembre-se que para que a troca de informações seja possível, os objetos devem ser serializáveis.

Os 3 componentes principais do .NET Framework Remoting são:

  1. Remotable Object
  2. Remote Listener Application – (escuta requisições para o Remote Object)
  3. Remote Client Application – (efetua requisições para o Remote Object)

O Remote Object é implementado em uma classe que deriva de System.MarshalByRefObject .

Portanto o Remotable Object é qualquer objeto fora do domínio da aplicação. Qualquer objeto pode ser transformado em um objeto remoto a partir da classe MarshalByRefObject. (Um objeto remoto é derivado da classe MarshalByRefObject)

A classe MarshalByRefObject permite acesso a objetos através de limites de domínio do aplicativo em aplicativos que suporte o Remoting.

Um domínio de aplicativo é uma partição em um processo do sistema operacional onde um ou mais aplicativos residem. Objetos no mesmo domínio do aplicativo se comunicam diretamente. Objetos em domínios diferentes aplicativos se comunicam por transporte de cópias dos objetos através de limites de domínio de aplicativo, ou usando um proxy para trocar mensagens.

MarshalByRefObject é a classe base para objetos que se comunicam através de limites de domínio de aplicativo, trocar mensagens usando um proxy. Objetos que não herdam de MarshalByRefObject são implicitamente empacotados por valor. Quando um aplicativo remoto referencia um pacote por valor de objeto, uma cópia do objeto é passada através de limites de domínio de aplicativo.

Objetos que não herdem de MarshalByRefObject são chamados de Non-Remotable Objects.

A seguir temos um fluxo básico da arquitetura .NET Remoting:

Quando um cliente chama um método remoto, ele não chama o método diretamente, ele recebe um proxy para o objeto remoto e o utiliza para invocar o método em um Remote Object.

Desde que o proxy recebe a chamada do método do cliente, ele codifica a mensagem usando um formato apropriado (Binary Formatter ou SOAP Formatter).

Formatters são usados para codificar e decodificar mensagens antes que elas sejam transportadas pelo Canal.

Existem dois tipos de formatadores suportados:

  • Binary Formatter – (System.RunTime.Serialization.Formatters.Binary) – os dados possuem um tamanho menor;
  • SOAP Formatter – (System.RunTime.Serialization.Formatters.Soap) – dados no formato texto baseado em arquivos XML que podem ser lidos;

A configuração dos formatadores e dos canais é feita através de arquivos de configuração como arquivos XML.

A seguir ele efetua a chamada para o servidor usando um canal selecionado (TcpChannel ,HttpChannel).

Canais são usados para transportar mensagens entre objetos Remotos, sendo assim objetos responsáveis pelo tratamento dos protocolos de rede e formatos de serialização.

Um canal pode ser implementado pela chamada do método ChannelServices.RegisterChannel ou pela utilização do arquivo de configuração, mas deve ser registrado antes dos objetos.

Quando um canal é registrado, ele automaticamente inicia a escuta para as requisições do cliente em uma porta especificada. Pelo menos um canal deve ser registrado antes que um Remote Object possa ser chamado.

Existem dois tipos de canais :

  • canal HTTP – transporta mensagens para e a partir de objetos remotos usando o protocolo SOAP;
  • canal TCP – usa o formato binário para serializar todas as mensagens para um fluxo binário e transporta o fluxo para uma URL de destino usando o protocolo TCP;

O canal do lado do servidor recebe a requisição do proxy e encaminha para o Servidor no sistema remoto que localiza e invoca os métodos do objeto Remoto.

Quando a execução do método remoto é completada, qualquer resultado da chamada é retornado de volta ao cliente.

Antes de uma instância do objeto de um tipo Remotable poder ser acessado, ele precisa ser criado e inicializado pelo processo chamado Activation que pode ser classificado em dois modelos: Client-Activated Objects e Server-activated Objects.

A diferença entre client-activated e server-activated é que o primeiro não é realmente criado quando faz a sua instanciação, ao invés disso, ele é criado somente quando necessário.

Por padrão .NET Framework vem com dois formatadores: Binary Formatter or SOAP Formatter e dois canais : TcpChannel ,HttpChannel

Trabalhando com .NET Remoting

1- Criando o Remotable Type

No código abaixo temos um exemplo da criação de um objeto remoto no VB .NET que envia a hora atual para a aplicação cliente usando o Framwork Remoting.

Note que a classe RemoteTime é derivada de MarshalByRefObject e, que no interior da classe, ele possui o método getTime() o qual retorna a hora atual de um Remote Object.

Imports System
Public Class RemoteTime
   Inherits MarshalByRefObject

   Private currentTime As String = ""

   Public Function getTime() As String
          currentTime = DateTime.Now.ToShortTimeString()
          Return "Hora do servidor remoto : " & currentTime
   End Function 

End Class 

Crie uma aplicação do tipo Class Library no VB .NET e salve com o nome de RemoteTime.vb; em seguida compile o arquivo em um library usando a linha de comando do NET Framework com a seguinte sintaxe:

vbc /t:library RemoteTime.vb

Após isso você irá obter o arquivo RemoteTime.dll .

2- Criando o Remote Listener Application

Agora temos que criar um objeto Listener para permitir que os objetos do domínio da outra aplicação possam criar instâncias do nosso objeto RemoteTime remotamente.

Quando da criação do objeto Listener temos que escolher e registrar o canal para o tratamento do protocolo de rede e do formato de serialização e registrar o Tipo no .NET Remoting de forma que ele possa usar o canal para escutar as requisições para o Tipo.

No exemplo a seguir vamos criar uma aplicação listener chamada TimeListener que irá atuar como um objeto Listener para o Tipo Remoto RemoteTime.

A classe Listener TimeListener precisa estar habilitada a encontrar o arquivo TimeListener.exe.config para carregar a configuração para a classe RemotableType.

Vamos criar uma aplicação do tipo console no VB 2008 Express com o nome TimeListener;

A seguir copie o código abaixo no arquivo TimeListener.vb;

Imports System
Imports System.Runtime.Remoting

Public Class TimeListener
     Public Shared Sub Main()
             RemotingConfiguration.Configure("TimeListener.exe.config")
             Console.WriteLine("Escutando requisições do cliente. Para sair pressione ENTER...")
             Console.ReadLine()
      End Sub
End Class

A seguir temos que criar um arquivo de configuração adicional para fornecer a informação da comunicação para o objeto listener.

O arquivo de configuração é um arquivo padrão XML onde podemos especificar o modo de ativação (Activation Mode) , o tipo Remoto (Remote Type) , Canal , porta para comunicação , etc.

Vemos abaixo o arquivo XML TimeListener.exe.config:

<configuration>
   <system.runtime.remoting>
     <application>
       <service>
       <wellknown mode="Singleton" type="RemoteTime, RemoteTime" objectUri="RemoteTime.rem" />
      </service>
       <channels>
        <channel ref="http" port="9090" />
       </channels>
   </application>
    </system.runtime.remoting>
</configuration>

Vamos compilar o arquivo TimeListener.vb usando a ferramenta de linha de comando da plataforma .NET. O comando é o seguinte:

vbc /r:RemoteTime.dll TimeListener.vb

Após compilar você deve obter o arquivo TimeListener.exe.

Criando o aplicação CLiente

3- Criando o Remote Client Application

A aplicação cliente que faz a chamada ao método do objeto Remoto é muito fácil de criar no VB .NET.

Crie uma nova aplicação do tipo Console no VB .NET com o nome Client e copie o código abaixo no arquivo Client.vb;

Imports System
Imports System.Runtime.Remoting

Public Class Client
   Public Shared Sub Main()
         RemotingConfiguration.Configure("Client.exe.config")
        Dim remoteTimeObject As New RemoteTime()
        Console.WriteLine(remoteTimeObject.getTime())
End Sub
End Class

A aplicação cliente cria uma instância do Tipo remoto RemoteTime e chama o método getTime() ; além disso ela usa o arquivo de configuração cliente.exe.config para obter a informação da comunicação para o Remoting Framework.

Temos então que criar um arquivo de configuração adicional para fornecer a informação da comunicação para o objeto Client.

<configuration>
    <system.runtime.remoting>
      <application>
       <client>
              <wellknown type="RemoteTime, RemoteTime" url="http://localhost:9090/RemoteTime.rem" />
       </client>
     </application>
  </system.runtime.remoting>
</configuration>

Compile o arquivo Client.vb usando a ferramenta da linha de comando do NET Framework SDK. O comando é o seguinte:

vbc /r:RemoteTime.dll Client.vb

Iremos obter o arquivo Client.exe.

Compilando e rodando a aplicação

Já temos os arquivos necessários para colocar para funcionar o nosso exemplo de aplicação usando o .NET Remoting. Então vamos lá…

Crie uma nova pasta chamara SRC e ponha os três arquivos que criamos nesta pasta:

  1. RemoteTime.vb
  2. TimeListener.vb
  3. Client.vb

Inclua os dois arquivos de configuração na mesma pasta:

  1. TimeListener.exe.config
  2. Client.exe.config

Lembre-se de que os arquivos já foram compilados usando a ferramenta de linha de comando do .NET Framework SDK. Os comandos usados foram:

vbc /t:library RemoteTime.vb

vbc /r:RemoteTime.dll TimeListener.vb

vbc /r:RemoteTime.dll Client.vb

Nota: Você deve fornecer o caminho físico para cada arquivo na compilação. Ex: se os arquivos estiverem na pasta c:\SRC , você deverá informar:

vbc /r:c:\SRC\RemoteTime.dll c:\SRC\TimeListener.vb

Após compilar os arquivos fontes deveremos obter os 3 arquivos na pasta SRC: RemoteTime.dll, TimeListener.exe e Client.exe

Rodando a aplicação

Agora crie duas novas pastas com o nome Server e Client respectivamente:

- Copie os arquivos : RemoteTime.dll , TimeListener.exe and TimeListener.exe.config para a pasta Server;

- Copie os arquivos: RemoteTime.dll , Client.exe and Client.exe.config para pasta Client;

Abra um prompt de comando na pasta Server e digite : TimeListener

Você deverá obter uma janela exibindo a mensagem : Escutando requisições do cliente. Para sair pressione ENTER…

Abra um prompt de comando na pasta Client e digite Client;

Você deverá obter a hora atual do objeto remoto.

Nota: Se você obtiver uma exceção relativa à segurança do IIS, você deverá configurar o IIS.

Pronto! Você acabou de criar o seu primeiro programa usando .NET Remoting com sucesso.

SEO Powered by Platinum SEO from Techblissonline