29 de jan. de 2010

Surgimento da Orientação a Objetos



Hoje tive uma aula sobre Análise e Projeto OO com UML, como sou um entusiasta do assunto, procurei exprimir as idéias abordadas complementando com algumas leituras adicionais e, navegando por alguns sites relacionados com o assunto, encontrei um post interessantíssimo no blog da Webgoal. Darei então uma breve explanação da origem histórica do paradigma de orientação a objetos conforme explicado no blog citado e em sala de aula, seguido de algumas lições aprendidas e do meu ponto de vista. Vamos então ao que interessa!

A orientação a objetos tem sua origem nos anos 60 na Noruega, com Kristen Nygaard e Ole-Johan Dahl, no Centro Norueguês de Computação. Através da linguagem Simula 67, foram introduzidos os conceitos de classe e herança.

A orientação a objetos foi mais bem conceituada no laboratório da Xerox, em Palo Alto, sendo refinada numa seqüência de protótipos da linguagem Smalltalk. O líder desse projeto foi Alan Curtis Kay, considerado um dos criadores do termo “programação orientada a objetos”.

Alan Kay começou a programar em Simula depois de conhecer um inovador programa chamado Sketchpad. Sketchpad foi um editor gráfico desenvolvido por Ivan Sutherland, no MIT, em 1963. É considerado um marco na informática, sendo o primeiro editor gráfico orientado a objetos. Era possível colocar bits coloridos no canvas, mas também criar objetos que poderiam ser manipulados distintamente uns dos outros. O Sketchpad permitia que fosse definido um “master drawing“, a partir do qual seriam criadas “instance drawing” (herança).

Este paradigma tão utilizado atualmente surgiu na tentativa de solucionar problemas existentes no desenvolvimento softwares complexos e confiáveis com baixo custo de desenvolvimento e manutenção. A necessidade da época demandava por uma solução de nível de abstração de programação que se aproximasse mais do mundo real, com modelos e conceitos representativos. Chegou-se então à conclusão (ou abstração) de que o mundo real é formado por objetos que interagem entre si.

Outra conclusão importante que justifica o uso do paradigma da orientação a objetos é que representar esses objetos em um software é mais natural e permanente do que representar a sua funcionalidade (decomposição funcional), pois esta é mutável.

Logo, conclui-se que, se as abstrações não tiverem uma expressão direta (ou próxima) do mundo computacional, a complexidade da solução seria aumentada e não teriamos a nossa tão conhecida facilidade de desenvolvimento e manutenção em linguagens de alto nível (como Java ou .NET, por exemplo).

Ficamos por aqui pessoal. Um grande abraço e até o próximo post! ;)


.


19 de jan. de 2010

Arquitetura de Software




A arquitetura de software é um assunto largamente discutido nos dias de hoje, principalmente pelo fato de o mesmo ser uma das principais causas de insucesso nos projetos de software (mais especificamente sendo considerada como a segunda maior causa de insucesso, logo depois da definição de requisitos). Logo, uma arquitetura consistente e bem definida se torna fundamental para que o projeto seja implementado eficientemente.

Arquitetura de software nada mais é que a definição de uma representação abstrata de comportamentos e componentes do sistema. Se um programador disser, por exemplo, que para implementar uma determinada funcionalidade ele precisará criar uma interface gráfica com uma extensão X que envia requisições através de um protocolo Y para um determinado componente ou recurso W que acessa o componente de integração ao banco de dados Z, ele estará descrevendo a arquitetura utilizada por seu sistema. Repare que isto tem muito a ver com o estilo de desenvolvimento utilizado.

Existem algumas classificações de arquitetura, como por exemplo as que irei detalhar aqui, a arquitetura de referência e a arquitetura de distribuição.

Arquitetura de Referência: é um tipo de arquitetura que possui uma terminologia unificada, com a definição consistente de padrões de componentes e seus respectivos papéis/responsabilidades. Possui como principais características o fornecimento de flexibilidade e contém um conjunto consistente das melhores práticas de mercado muitas vezes provenientes da consolidação de funcionalidades amplamente utilizadas para resolver um determinado problema em um contexto específico.
Exemplos desta arquitetura: JEE, SOA e JME.

Arquitetura de Distribuição: é mais relacionada com topologia de servidores e componentização, porém não significa necessariamente que a aplicação necessite estar separada fisicamente, mas ela deve permitir que isso aconteça caso essa separação seja necessária um dia. Por exemplo, se uma aplicação roda hoje em um único servidor no qual estão instalados o contâiner web e um servidor de e-mails ao qual esta aplicação web acessa, nada impedirá de um dia separarmos estes dois recursos em dois servidores físicos e um continue acessando o outro normalmente.

Uma arquitetura pode ser representada também por um mapa de camadas, como temos, por exemplo, representado pelo tão utilizado MVC. Uma outra boa representação, ainda mais detalhada, pode ser representado pelas seguintes 5 camadas:

CLIENTE | APRESENTAÇÃO | NEGÓCIOS | INTEGRAÇÃO | RECURSOS

O cliente pode ser representado por uma Applet ou uma página HTML, ou seja, é o que é gerado para a exibição ao usuário final.

A apresentação seria o processo de geração da página do cliente e a nossa camada de controle (ou o controller do MVC), o qual interage com a camada de visão.

A camada de negócios representa toda a implementação efetiva do negócio ao qual o sistema deve atender (as regras do sistema) e a estrutura de representação das entidades no qual o sistema manipula.

A camada de integração é onde estão os componentes que acessam os recursos externos à aplicação, como por exemplo, uma API JDBC para acesso a banco de dados.

E finalmente, a camada de recursos pode representar, por exemplo, arquivos XML, bases de dados, sistemas mainframe, servidores de e-mail, enfim, tudo o que representa interações externas ao qual o sistema depende para executar uma determinada funcionalidade.

Bom, é isto pessoal, espero ter desmistificado alguns conceitos básicos sobre a Arquitetura de Software. O próximo tema abordado tratará a respeito das capacidades de uma arquitetura.

.

2 de jan. de 2010

Implementando valueChangeListener com JSF


Olá pessoal, hoje eu irei compartilhar com vocês uma experiência que tive trabalhando em um projeto, no qual tive que implementar um comportamento de “onchange” em um componente selectOneMenu do JSF 1.2. A princípio a implementação me parecia fácil e bem sugestiva, no entanto, após alguns testes pude perceber que uma “cilada” estaria me surpreendendo: o evento por trás do atributo “valueChangeListener” não executa como esperado!
Tal problema me exigiu alguns esforços para se chegar a uma solução plausível. Creio que este tipo de implementação gere dúvidas também há muitos outros desenvolvedores e, portanto, seguem alguns esclarecimentos:
Tentarei ilustrar o problema com um exemplo de um selectOneMenu que realiza a listagem de carros de acordo com a marca selecionada:
Bom, o primeiro entrave encontrado foi em relação à submissão do formulário: ela não é realizada na alteração da selectOneMenu sem que coloquemos o “onchange=’submit()’” explicitamente!
À primeira vista o código acima parece então sugerir que, ao se alterar uma opção do selectOneMenu, o método declarado no atributo valueChangeListener será invocado. Ah, eis a cilada!
Neste momento, você pode estar me perguntando: mas por que não funcionaria? Eis o segredo: simplesmente porque o método declarado no valueChangeListener é chamado ANTES dos métodos setters do managed-bean serem chamados! Isso implica que, qualquer alteração que você realize nas variáveis no seu método em valueChangeListener seriam sobreescritas quando os setters fossem chamados. E se caso tentassemos pular essas chamadas aos métodos setters invocando “FacesContext.getCurrentInstace.renderResponse()” no método valueChangeListener, simplesmente estariamos pulando também as chamadas aos getters, o que impediria da mesma maneira de exibirmos os valores atualizados na nossa view. Então o que fazer?
Ok, para solucionar nós temos 3 soluções básicas:
1 – Podemos forçar o JSF a recriar a view:
FacesContext context = FacesContext.getCurrentInstance();
 
// Redireciona para a pagina a mesma página.
context.getApplication().getNavigationHandler().handleNavigation(
    context, null, "listarCarros");



E no arquivo faces-config.xml:




2 – Podemos mover o ciclo de vida do JSF à fase de atualização do modelo:

public void listarCarrosMarcaSelecionada(ValueChangeEvent event){
 
  // busca dos carros aqui...
  ...
  PhaseId phaseId = event.getPhaseId();
 
  if (phaseId.equals(PhaseId.ANY_PHASE)){

      event.setPhaseId(PhaseId.UPDATE_MODEL_VALUES);
      event.queue();
  }
}

3 – Podemos criar nosso próprio UIComponent no managed-bean usando “binding” e do método valueChangeListener poderiamos alterá-lo invocando o método “setMethod()”, pois, quando alteramos um UIComponent diretamente, o JSF automaticamente invoca os métodos getters para a atualização da view. Mas ainda sim teriamos que concluir o método invocando “FacesContext.getCurrentInstance().renderResponse()” para forçar a nova renderização.
Para o projeto em que estou, a primeira alternativa foi a adotada pois me pareceu a mais simples e no momento atenderia ao meu propósito. Existem também algumas soluções utilizando ajax, como por exemplo com a implementação do Ajax4JSF que também se mostram interessantes, mas eu não poderia utilizar devido a alguns motivos particulares do projeto.
Bom, então é isso pessoal, ficam aqui as dicas. Espero ter ajudado. Até a próxima!
.

Processo e Modelo de Processo



Olá pessoal, hoje abordarei a diferença entre um modelo de processo de software e um processo de software. Exemplificarei também, dois modos pelos quais um modelo de processo de software pode ser útil para identificar possíveis aprimoramentos no processo.

Um processo de software é o que define quais atividades devem ser realizadas dentro de uma produção de sistemas, define também as pessoas envolvidas e os artefatos a serem gerados. Já o modelo de processo de software define a sequência com que as atividades são executadas e quais as pessoas estão envolvidas e quais os artefatos são gerados por cada atividade.

Um processo de software normalmente é dividido em vários processos menores para se melhor organizar a produção de software. Existem algumas abordagens ou ferramentas sugeridas pela engenharia de software que, à partir delas, é possível se identifcar a acurácia de um modelo de processo de software, e assim se sugerir as possíveis melhorias.

Sugestões de aprimoramento à partir de um modelo podem ser encontradas quando o mesmo é expresso na forma de "papel/ação", por exemplo, porque assim é viável identificar se os papéis estão bem distribuídos por recursos humanos do projeto. Podem ser identificados também no modelo de fluxo de dados, uma outra abordagem na qual observamos se as transformações nos artefatos estão gerando a evolução desejada ao produto final.

Bom, é isso pessoal. Fiquem à vontade para comentar a respeito. Concluo este post com a seguinte frase aprendida: é em tempos de crise que encontramos as melhores oportunidades de rever nosso processo.

Um grande abraço e até o próximo post! ;)

.

Os 4 Grande Atributos dos Produtos de Software



O tópico de hoje aborda os quatro principais atributos que todos os produtos de software devem possuir. Sem tais atributos, não podemos afirmar que o software seja de qualidade.

Estamos falando de Facilidade de Manutenção (Manutenibilidade), Confiança, Eficiência e Usabilidade. Segue abaixo o conceito de cada um dos atributos segundo o estudioso Ian Sommerville:

- Manutenibilidade: O software deve ser escrito de modo que possa evoluir para atender às necessidades de mudança dos clientes. É um atributo fundamental, pois a mudança de software é uma consequência inevitável de um ambiente de negócios em constante mutação;
- Confiança: O nível de confiança de um software tem uma série de características, incluindo confiabilidade, proteção e segurança. Um software confiável não deve causar danos físicos ou econômicos no caso de falha no sistema.
- Eficiência: O software não deve disperdiçar os recursos do sistema, como memória e ciclos do processador. Portanto, a eficiência inclui tempo de resposta, tempo de processamento, utilização de memória e etc;
- Usabilidade: O software deve ser usável, sem esforço excessivo, pelo tipo de usuário para o qual ele foi projetado. Isso significa que ele deve apresentar uma interface com o usuário e documentação adequadas.

Complementando com algumas outras características, sugiro também a Portabilidade, Rastreabilidade, Facilidade de Integração a Outros Sistemas e Aderência às Necessidades de Negócio (muito importante!). E vocês, podem sugerir mais alguns?

Um grande abraço a todos e até o próximo post! ;)

.

Software Genérico X Software Por Encomenda


Hoje gostaria de comentar e esclarecer os principais conceitos do que diferenciam o desenvolvimento de produto genérico de software e o desenvolvimento de software sob encomenda e refletir um pouco sobre o rumo ao qual estes conceitos estão tomando, evidenciando a proximidade entre ambos.

Produtos genéricos, ou produtos de caixinha como muitas vezes são conhecidos, são produzidos por uma organização de desenvolvimento e distribuídos no mercado a quem quiser comprá-los. Já os sistemas sob encomenda são vendidos a um cliente específico e é desenvolvido sob a ótica da necessidade de negócio desse cliente.

A diferença entre os dois está, a cada dia que passa, se tornando mais tênue, já que os sistemas genéricos estão sendo frequentemente customizados por seus compradores. Um forte exemplo disso são os sistemas ERP (Enterprise Resource Planning) : que empresa hoje não o usa de maneira customizada?

Um grande abraço a todos e até o próximo post! ;)

.

Por que o software é mais que um programa executável?

Os programas de software são mais do que os softwares executados pelos usuários porque para a sua produção são envolvidas diversas atrividades intrínsecas ao tipo de software desenvolvido.

Nos sistemas em que é utilizada uma abordagem cascata, por exemplo, as atividades são distintas e bem definidas e os seus custos são medidos separadamente e as atividades de teste e integração são mais caras. Na abordagem iterativa as mesmas atividades são realizadas mas em paralelo com a atividade de desenvolvimento. Já na abordagem por componentes os maiores custos se baseiam na integração e testes.

Portanto, o software é muito mais do que o produto executado pelo usuário final em termos de custo, já que muitas outras atividades e pessoas são necessárias para que se chegue ao produto.

.