Qualidade de Software

Desenvolvimento Psicopata - Qualidade Total

domingo, 4 de outubro de 2009

O problema não é meu - Parte I

Devo desculpas aos amigos que acompanham este singelo espaço, por não escrever nenhum artigo há muito tempo. Infelizmente isso deve ser comum neste próximo ano. Estou em uma equipe que atua com BPM e estamos implantando este conceito em uma das maiores empresas do Brasil.

Já vinha estudando sobre gerenciamento de processos desde fevereiro deste ano, época da minha primeira passagem pela equipe. Tive uma rápida passagem por ETL e, há dois meses, estou de volta ao BPM. Aprendi muitas coisas neste período, principalmente a lidar com a diversidade de profissionais. E é justamente esse o ponto central desta pequena série. Tenho trabalhado com o ALBPM e com um Java que não é Java, mas é Java. Sim, a coisa é meio confusa. Entretanto, existem aplicações puramente Java que auxiliam o sistema como um todo, como as consultas.

Bem, como eu disse, o ponto central deste post é a diversidade de profissionais.

Quando somos jovens, com o excesso de energia que é peculiar desta idade, e encontramos códigos que não estão em boa forma (good shape), a reação mais natural é criticar. Entretanto, quando amadurecemos e olhamos para nossos próprios códigos do passado, com os olhos do conhecimento que adquirimos durante os anos, percebemos que já desenvolvemos de forma amadora. A evolução é algo natural (ou deveria ser) e, naturalmente, tendemos a achar ruim hoje, o que fizemos ontem. Assim, considerando apenas os profissionais que estão preocupados com a sua carreira, não existem bons ou ruins e sim, profissionais que estão em diferentes níveis de carreira.

Acredito que os três níveis tradicionais de analista - júnior, pleno e sênior - não são suficientes para expressar os níveis reais da carreira. Acho que poderiamos explodir o pleno em mais três níveis (como baixo, médio e alto). Reforço que estou me referindo aos profissionais que realmente se preocupam com a sua carreira, que estudam e buscam o aprimoramento, mesmo nos horários de folga.

Dentro deste grupo de profissionais, considero o analista bom ou ruim baseado na sua reação quando encontra um código ruim pela frente. Você diz, isso não é problema meu?

Deixa eu explicar melhor. Nas grandes empresas, é natural assumir aplicações legadas, que chamo, carinhosamente, de filhas adotivas. É natural também, que estas aplicações tenham passado pelas mãos de muitas pessoas. Estas pessoas, obviamente, se encontram em níveis diferentes de conhecimento.

Com aplicações em produção, é comum atendermos chamados solicitando melhorias ou correções (bug-fixes). É neste momento que podemos (e devemos) fazer a diferença.

Se você está no grupo de pessoas que afirmam que um código legado mal feito não é um problema seu, está na hora de rever conceitos e, talvez, se tornar um pouco mais psicopata.

Acredito que o pior cenário para fazer melhorias de código, seja o de grandes empresas, por inúmeros fatores, alguns exemplos:
  • Ambiente de produção fora do seu controle: Geralmente os processos de deploy e restart de servidores de aplicação não estão nas mãos dos analistas e sim de uma equipe especializada;
  • Muitas camadas de testes antes de um deploy: Normalmente, os únicos testes que estão na mão dos analistas são os unitários. Outros testes como os integrados e regressão, estão nas mãos de equipes especializadas em testes.

Estes exemplos mostram como pode ser complicado "subir" alguma modificação motivada "apenas" por melhorias no código. Como um outro post, já planejado, pretende mostrar, o cliente, normalmente, não está preocupado com isso. Não concordo com essa visão, entretanto expor meu ponto de vista sobre esta situação não é propósito deste post.

Estes motivos, na minha visão, já são suficientes para tornar nosso o problema.

Assim, um chamado de melhoria ou correção é uma ótima oportunidade de deixarmos a nossa vida um pouco mais tranquila no futuro. Como? Só vejo uma forma, sendo psicopata.

O meu tempo, como a da maioria das pessoas que frequenta este blog, é escasso. Assim, quando fazer as alterações não contempladas em um chamado? Como fazer de forma segura? Como ser eficiente para não afetar as metas?

Estas perguntas serão respondidas no próximo e último post dessa série. Até lá.

domingo, 30 de agosto de 2009

Integrando JSF 1.2 com Richfaces e EJB3 utilizando JBOSS AS 5 e Eclipse - Parte I

Como encontrei pouquíssimas fontes de consulta sobre o assunto em sites brasileiros, resolvi escrever esse artigo que visa exemplificar uma das formas de se integrar com sucesso esses três frameworks em sua aplicação. Foi a solução que implementei em meu projeto e espero que seja de utilidade para outros desenvolvedores que possam estar passando pelos mesmos problemas que eu enfrentei para deixar a aplicação funcionando 100% sem bugs.

Esse é meu primeiro artigo e minha intenção é ajudar a comunidade pois obtenho muita ajuda em fórums e outros artigos, por isso quem notar alguma dificuldade me relate mas sem stress! =)

Em primeiro lugar, tenha certeza de possuir todas as libs necessárias. Caso não possua alguma das libs listadas abaixo, coloque o nome do JAR no Google que com certeza várias fontes para download estarão disponíveis. As libs do JBoss vem junto com o servidor, voce deve usá-las para evitar do Eclipse ficar exibindo erros de falta de bibliotecas em cada linha de código que voce escrever que vá usar algum componente de EJB dentro do seu projeto web.

Esse artigo toma por base que você ja saiba como trabalhar com EJB mas nao sabe como utiliza-lo nos seus projetos com JSF.

COMMONS
  • commons-beanutils.jar
  • commons-collections.jar
  • commons-logging.jar
  • commons-digester.jar
  • commons-codec-1.3.jar
  • commons-discovery-0.4.jar
  • commons-el.jar

JBOSS
  • Libs do diretorio "client" do jboss
JSF
  • jsf-api.jar
  • jsf-impl.jar
JSTL
  • standard.jar
  • jstl.jar

Richfaces
  • richfaces-api-3.3.0.GA.jar
  • richfaces-impl-3.3.0.GA.jar
  • richfaces-ui-3.3.0.GA.jar
Outras LIBs
  • jsr250-api.jar
  • jsp-api.jar
  • tomahawk-1.1.6.jar

Listei a api Tomahawk por ela ter me facilitado muito a vida em algumas coisas que a JSF sozinha não conseguiu realizar.

Essas libs devem ser copiadas para o diretorio: <raiz_do_seu_jboss>/server/default/lib e o servidor deve ser reinicializado para reconhecer as novas libs.

Voce tambem poderá marcar as libs para exportação dentro do Eclipse marcando as mesmas na configuração do build-path na guia "Order and Export". Porém as libs abaixo NÃO devem ser marcadas para exportação caso esse método seja escolhido:

Libs do diretorio client do Jboss
  • jsf-api.jar
  • jsf-impl.jar

OBS: Eu não recomendo esse método por deixar o arquivo war final muito grande.

Configuração do diretório web-inf
Desenvolvendo meu projeto, percebi que intermitentemente as tags disponíveis nos TLDs de algumas bibliotecas ficavam indisponíveis como se o container não conseguisse localizar o TLD da tag corretamente. Eu precisava sempre reiniciar o servidor e torcer para que ele localizasse os TLDs nos diretorios META-INF dos JARs das bibliotecas, coisa que nem sempre acontecia. A solução que encontrei para acabar com isso, foi copiar algumas TLDs diretamente para o diretório WEB-INF. Dessa forma, caso você passe por problema semelhante, será necessário copiar os seguintes TLDs para dentro do seu diretorio WEB-INF:
  • a4j.tld
  • ajax4jsf.tld
  • rich.tld
  • richfaces.tld
  • tomahawk.tld

Esses TLDs podem ser encontrados dentro dos diretorios META-INF das suas respectivas bibliotecas.

Configuração do web.xml
Adicionar as seguintes tags no web.xml para configurar o JSF:
<welcome-file-list>
   <welcome-file>index.jsf</welcome-file>
</welcome-file-list>

<context-param>
   <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
   <param-value>server</param-value>
</context-param>

<context-param>
   <param-name>javax.faces.CONFIG_FILES</param-name>
   <param-value>/WEB-INF/faces-config.xml</param-value>
</context-param>


<servlet>
   <servlet-name>Faces Servlet</servlet-name>
   <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
   <load-on-startup>1 </load-on-startup>
</servlet>


<servlet-mapping>
   <servlet-name>Faces Servlet</servlet-name>
   <url-pattern>*.jsf</url-pattern> // extensao que o cliente web utilizará. Pode ser qualquer coisa.
</servlet-mapping>
Observe que a tag <welcome-file-list> aponta para um arquivo index.jsf que deve ser criado em branco com esse nome na raiz da aplicação. É uma técnica utilizada para "enganar" o container de forma que você consiga acessar sua pagina inicial (index.jsp) sem precisar digitá-la no navegador e trabalhando com JSF, voce provavelmente terá problemas com isso se não proceder dessa forma.

É possível alterar a extensão pela qual suas páginas responderão no navegador do cliente. Voce poderá configurar a extensão que quiser (*.jsf, *.java, *.abacaxi, etc). Portanto voce nao esta preso a utilizar 'index.jsf' e 'index.jsp' como suas páginas, voce pode configurar como desejar no welcome-file-list e no <servlet-mapping> de Faces Servlet.

Para configurar o Richfaces, é necessário adicionar as seguintes tags:
<filter>
   <display-name>RichFaces Filter</display-name>
   <filter-name>richfaces</filter-name>
   <filter-class>org.ajax4jsf.Filter</filter-class>
</filter>

<filter-mapping>
   <filter-name>richfaces</filter-name>
   <servlet-name>Faces Servlet</servlet-name>
   <dispatcher>REQUEST</dispatcher>
   <dispatcher>FORWARD</dispatcher>
   <dispatcher>INCLUDE</dispatcher>
</filter-mapping>

<context-param>
   <param-name>org.richfaces.SKIN</param-name>
   <param-value>blueSky</param-value>
</context-param>
blueSky é o tema padrão utilizado nos componentes do richfaces. Temas diferentes podem ser configurados por essa tag.

Configuração do faces-config.xml
É aqui que a integração com o EJB começa a tomar forma. O faces-config.xml é um arquivo XML com a seguinte estrutura básica:
<faces-config>
   <managed-bean>

   (configuração do bean)

   </managed-bean>
</faces-config>

A tag <managed-bean> é a tag que voce é responsável por configurar para integração de seus EJBs no JSF. Abaixo segue um exemplo de um <managed-bean> básico configurado:
<managed-bean>
   <managed-bean-name>exemplo</managed-bean-name>
   <managed-bean-class>pacote.BeanExemplo</managed-bean-class>
   <managed-bean-scope>request</managed-bean-scope>
</managed-bean>
O parâmetro <managed-bean-name> é o nome utilizado pela sua interface JSF mapeado para o controlador do EJB configurado em <managed-bean-class>. O <managed-bean-scope> possui 3 parâmetros aplicáveis: REQUEST, APPLICATION e SESSION, sendo que o mais comumente utilizado é o REQUEST.

Bom, com isso finalizamos a etapa de configuração. Na próxima parte começaremos a criar uma pequena aplicação de exemplo para juntarmos todas as peças simulando um sistema real.

domingo, 23 de agosto de 2009

Uma amostragem da EJB 3.1 (Tradução)

por Ken Saks

O último update da tecnologia Enterprise JavaBeans (EJB), EJB 3.1, está próximo de ser finalizado. O final draft da especificação já está disponível. O objetivo principal desta nova especificação é simplificar o desenvolvimento usando EJB e adicionar algumas funcionalidades há muito solicitadas, como os singleton beans.

A versão 3.1 da especificação será incluída na JEE 6. Um preview está disponível para download. Esta versão inclui uma implementação quase completa da especificação EJB 3.1 e uma aplicação de exemplo que se beneficia de algumas das nova funcionalidades presentes na nova especificação.

Este Tech Tip introduz um pouco dessas novas capacidades excitantes da EJB 3.1. Também inclui instruções de como rodar a aplicação exemplo presente no preview

Facilidade de desenvolvimento
A EJB 3.1 é baseada nos componentes de fácil usabilidade da EJB 3.0, fornecendo muitas alternativas novas para aumentar a produtividade do desenvolvedor. A principal delas é a habilidade de implementar session beans usando apenas uma classe bean e a habilidade empacotar os beans diretamente em um arquivo war, sem a necessidade de um arquivo ejb-jar.

No-interface View
O EJB 3.0 local client view é baseado em uma Plain Old Java Interface (POJI) chamada de local business interface. Uma interface local define os métodos de negócio que são expostos para o cliente a que serão implementados nas classes bean. Apesar desta separação entre interface e implementação ser uma abordagem bem aceita para design de aplicações, a separação algumas vezes se torna uma complexidade desnecessária e adiciona pouco valor. Isto é verdade, especialmente, quando usamos componentes fine-grained, com clientes muito acoplados que são colocados no mesmo módulo.

Desenvolvedores tem questionado uma forma de obter a mesma funcionalidade de enterprise bean sem precisar escrever business interfaces separadas. A especificação EJB 3.1 responde esse questionamento, tornando as local business interface opcionais. O resultado é no-interface local view.

A no-interface view tem o mesmo comportamento da local view da EJB 3.0, por exemplo, suporta funcionalidades como a chamada semântica por passagem por referência e propagação de transação e segurança. Entretanto, no-interface view não requer uma interface separada, isto é, todos os métodos públicos da classe bean são expostos automaticamente para o cliente. Por default, qualquer session bean que tem uma cláusula vazia implements e não define nenhum outro client view local ou remoto, expõe uma no-interface client view.

Por exemplo, o session bean a seguir expõe uma no-interface view
@Stateless
public class HelloBean {

  public String sayHello() {
   String message = propertiesBean.getProperty("hello.message");
   return message;
  }
}
Como no caso para as local view, o cliente de uma no-interface view adquire uma referência EJB -- através de injeção ou JNDI lookup. A única diferença é que o tipo Java da referência EJB é a classe bean, em vez de o tipo da local interface. Isto é mostrado no seguinte cliente bean:
@EJB
private HelloBean helloBean;
   ...
   String msg = helloBean.sayHello();
Note que mesmo que não seja uma interface, o cliente não pode usar o operador new() para instanciar explicitamente a classe bean. Isto porque todas as invocações de bean são feitas através de uma referência especial, ou proxy, fornecidas pelo container. Isto permite ao container fornecer todos os serviços adicionais de bean, como pooling, transações gerenciadas pelo container e gerenciamento de concorrência.



Pacotes simplificados
A especificação EJB sempre necessita que os enterprise beans sejam empacotados em um módulo chamado arquivo ejb-jar. Como isto é comum para aplicações web Java EE, para usar enterprise beans, este requerimento de empacotamento pode ser penoso. Estas aplicações são forçadas a usar um web application archive (arquivo .war) para a aplicação web, um arquivo ejb-jar para os enterprise beans e um enterprise archive (arquivo .ear) que engloba os outros pacotes. Esta abordagem de empacotamento é complicada pelo suporte especial necessário para qualquer classes ou recursos que devem ser compartilhados entre os módulos.

A especificação EJB 3.1 endereça este problema removendo a restrinção de que classes enterprise beans devem ser empacotadas em um arquivo ejb-jar. Você agora tem a opção de colocar as classes EJB diretamente no arquivo .war, utilizando a mesma orientação de empacotamento aplicada as classes web applications. Isto significa que você pode colocar classes EJB sob o diretório WEB-INF/classes ou em um arquivo .jar no diretório WEB-INF/lib. O EJB deployment descriptor também é opcional. Se necessário, você pode empacota-lo como um arquivo WEB-INF/ejb-jar.xml.

Novas funcionalidades na EJB 3.1
Devido ao foco concentrado na faciliadade de uso no EJB 3.0, não houve tempo suficiente para adicionar muitas outras funcionalidades requeridas pelos desenvolvedores. A especificação EJB 3.1 adiciona algumas dessas funcionalidades na API EJB. Quatro dessas novas funcionalidades são os singleton session beans, application initialization/shutdown callbacks, invocações assíncronas de session beans e automatic EJB timers.

Singleton
Uma omissão de muito tempo na API EJB foi a habilidade de facilmente compartilhar estado entre multiplas instâncias de um componente enterprise bean ou entre multiplos componentes enterprise bean na aplicação. Em contraste, o modelo de programação web Java EE já provê esta tipo de capacidade através de um objeto ServletConfig. Na EJB 3.1, esta omissão foi resolvida com a introdução dos singleton beans, também conhecidos como singletons.

Um singleton é um novo tipo de session bean que garante que haverá apenas uma instância para uma aplicação na JVM. Um singleton é definido usando a anotação Singleton, como mostrado no seguinte exemplo:
@Singleton
public class PropertiesBean {
    private Properties props;
    private int accessCount = 0;

    public String getProperty(String name) { ... }

    public int getAccessCount() { ... }
}
Por ser somente outro tipo de session bean, um singleton pode definir a mesma client view, local ou remoto, como stateless e stateful bean.Clientes acessam os singletons da mesma maneira que acessam stateless e stateful bean, isto é, através de uma referência EJB. Por exemplo, um cliente pode acessar o singleton PropertiesBean, como segue:
@EJB
private PropertiesBean propsBean;
   ...
   String msg = propsBean.getProperty("hello.message");
Aqui, o container assegura que todas as invocações para todas as referências PropertiesBean na mesma JVM são servidos pela mesma instância de PropertiesBean. Por default, o container força a mesma garantia de threading como para outros tipos de componentes. Especificamente, não mais que uma invocação é permitida para acessar uma instância particular do bean, a qualquer momento. Para os singletons, isto significa bloquear qualquer invocação concorrente. Entretanto, este é somente o comportamento concorrente padrão. Existem opções de concorrência que permitem acessos concorrentes mais eficientes para uma instância singleton.

Application Startup/Shutdown Callbacks
A introdução dos singletons também provê uma forma conveniente para as aplicações EJB receberem callbacks durante a inicialização ou finalização da aplicação. Por default, o container decide quando instanciar o singleton. Entretanto, você pode forçar a instanciação do singleton pelo container durante a inicialização da aplicação, usando a anotação @Startup. Isto permite ao bean definir um método @PostConstruct que garante ser chamado em tempo de inicialização. Adicionalmente, qualquer método @PreDestroy para um singleton será chamado na finalização da aplicação, independentemente se um singleton foi instanciado usando lazy instantiation ou eager instantiation. Em uma lazy instantiation, o singleton não é instanciado até seus métodos serem necessários. Na eager instatiation, o singleton é instanciado na inicialização, não importando se será ou não usado.

Aqui está um exemplo que mostra uma parte de um singleton que inclui uma anotação @Startup, assim como métodos @PostConstruct e @PreDestroy:
@Singleton
@Startup
public class PropertiesBean {
     @PostConstruct
     private void startup() { ... }
 
     @PreDestroy
     private void shutdown() { ... }

  ...
}
Aplicação exemplo
O Java EE 6 SDK Preview release inclui uma aplicação que usa cada uma das funcionalidade da EJB 3.1 cobertas neste tutorial. A aplicação é composta de um servlet, um singleton session bean e de um stateless session bean. Cada session bean expõe uma no-interface view. O singleton define um callback que é chamado pelo container durante a inicialização da aplicação. Ambos, o servlet e o stateless bean, usam o singleton para acessar informações comuns de configuração da aplicação. Quando o servlet é acessado, invoca ambos session beans e imprime algumas mensagens contendo os valores retornados.

A aplicação inteira é empacotada em um arquivo .war, sem nenhum arquivo .xml.

Para rodar a aplicação de exemplo, faça o seguinte:
  1. Se você ainda não fez, baixe a Java EE 6 SDK Preview. Tenha certeza, também, de ter a Java Platform Standard Edition (Java SE) 6 SDK instalada.
  2. Baixe a aplicação exemplo, ejb31-war.war.
  3. Inicie o servidor de aplicações GlassFish V3 Prelude, que está no Java EE 6 SDK, digitando o seguinte comando:
javaee_home>/bin/asadmin start-domain
onde <javaee_home> é onde o Java EE 6 SDK está instalado.
  1. Faça o deploy a aplicação exemplo, copiando-a parao diretório <javaee_home>/domains/domain1/autodeploy.
  2. Execute a aplicação, abrindo o browser e acessando a URL http://localhost:8080/ejb-ejb31-war
Você deverá ver a seguinte saída aparecendo no seu browser:
ejb31-war Servlet
HelloBean says : Hello, world
Singleton property access count = 2


Você pode ver o código fonte da aplicação em <javaee_home>/samples/javaee6/ejb/ejb31-war/src.

Leituras adicionais

quarta-feira, 29 de julho de 2009

Princípios de projeto - Parte IX - Relacionamento entre classes

Aproveitando o meu post nesta thread do JavaFree.org, vou desenvolver aqui um pouco mais o relacionamento entre classes.

As decisões quanto a esse aspecto, podem levar a sua aplicação a ter um bom ou um mau design. Alguns conceitos, como os que abordam a questão da coesão, são decisivos para uma boa escolha para o relacionamento entre classes.

Existem quatro tipos principais de relacionamento, a saber:
  1. Herança: Relacionamento caracterizado pela expressão "é um". Ex: Vendedor - Pessoa
  2. Associação Simples: É a forma mais fraca de relacionamento, onde as partes podem existir independentemente. Ex: Pessoa - Cachorro
  3. Agregação: Relacionamento mais forte que associação simples, onde a parte é necessária ao todo, mas não indispensável. Ex: Pessoa - Braco
  4. Composição: É o mais forte relacionamento entre classes, onde nem o todo e nem a parte podem existir separadamente. Ex: Pessoa - Coracao
Alguém pode dizer, que no exemplo da associação, Pessoa pode conter, por exemplo, um List<Cachorro>, mas teríamos um bom problema de design, já que a classe Pessoa estaria sofrendo de mixed-role cohesion. Em linhas gerais:
Uma classe contém um elemento que faz parte do domínio, mas não faz parte da abstração dessa classe.
O exemplo do Cachorro e Pessoa, inclusive, é o exemplo de Page-Jones no seu livro.

Isto é, para o domínio da aplicação atual, uma Pessoa terá sempre um Cachorro, mas, se em uma nova aplicação, não houverem Cachorros e você quiser (e deve) reusar a classe Pessoa? A solução para esse problema de design é a criação de uma classe intermediária que fará o relacionamento entre Pessoa e Cachorro.

Até aqui, nenhuma novidade com relação a thread do JavaFree.

Entretanto, depois que formulei a resposta, uma pulga ficou atrás da minha orelha. Os exemplos de agregação e composição, funciona em termos acadêmicos, pois, no mundo real propriamente dito, uma pessoa não vive sem um coração, mas, normalmente, quando estamos modelando um sistema de vendas, por exemplo, para o domínio do cliente, esta composição é falsa, já que não precisaríamos modelar um coração e, claramente, quando fossemos reusar a classe pessoa, notaríamos um grave problema de mixed-role cohesion. Certamente, seria difícil reutilizar a classe Pessoa, em uma aplicação que não fosse, por exemplo, de doação de órgãos.

Este post marcará também a minha primeira exemplificação baseada em Scala. Então, vamos lá.

Usarei o exemplo da composição, que necessariamente implicaria em atributo.

Primeiro a classe Pessoa:
class Pessoa {
  private var age = 0
  
  def addAge(amount: Int) { age += amount }
}
Agora a classe Coracao:
class Coracao {
  private var beatMinute = 0
  
  def accelerate(amount: Int) { beatMinute += amount }
  def decelerate(amount: Int) { beatMinute -= amount }
  def getBeat(): Int = { beatMinute }
}
Na explicação sobre composição, o que eu disse é que, obrigatoriamente, teríamos algo assim:
class Pessoa {
  private var age = 0
  private var coracao = new Coracao
  
  def addAge(amount: Int) { age += amount }
}
Entretanto, como eu disse anteriormente, esta modelagem possui uma "doença" de coesão: mixed-role cohesion, o que impossibilitaria a reusabilidade sem alterações no código. Neste caso, a alteração seria remover a dependência de Coracao com Pessoa.

A solução, neste caso, seria criar uma classe intermediária, Corpo que teria a dependência com Coracao. Algo como:
class Corpo (coracao: Coracao)
Pronto, já alocamos a classe Coracao, e estamos livres de problemas de coesão. Mas, agora, falta modelar o relacionamento Pessoa - Corpo. Inserir um atributo Corpo em Pessoa, pois, no mundo real Pessoa tem Corpo, resultaria no mesmo problema de coesão, pois a classe Pessoa só serviria em uma aplicação médica, por exemplo.

Neste caso, a OO nos permite fugir um pouco do mundo real, pois sua definição diz "que o desenvolvimento OO aproxima a aplicação do mundo real" e não que reflete exatamente. A solução, sob meu ponto de vista, é simplesmente colocar um atributo Pessoa em Corpo, já que Corpo está representando o relacionamento. Dessa forma, nossa modelagem resultaria nisso:
class Pessoa {
  private var age = 0
  
  def addAge(amount: Int) { age += amount }
}
class Corpo (pessoa: Pessoa, coracao: Coracao)
class Coracao {
  private var beatMinute = 0
  
  def accelerate(amount: Int) { beatMinute += amount }
  def decelerate(amount: Int) { beatMinute -= amount }
  def getBeat(): Int = { beatMinute }
}
Existem vantagens e desvantagens nessa abordagem. Uma desvantagem é o aumento da granularidade da aplicação, significando que existem mais classes para dar manutenção, não significando, necessariamente, em aumento da dificuldade de manutenção. E as vantagens são: responsabilidades das classes bem definidadas, facilitando a manutenção; e baixo acoplamento, facilitando o reuso. Na minha opinião, a desvantagem é muito pequena se comparada com as vantagens.

Mas no novo modelo, onde a composição? Simples, entre Corpo e Coracao. Não estamos contando nenhuma mentira para o mundo real, já que não é possível existir um Corpo sem Coracao, pelo menos vivo.

Um ótimo exemplo de composição, muito mais próximo ao mundo do densenvolvimento de sistemas, é o relacionamento entre Pedido e ItemPedido. Não é possível conceber um sistema de pedidos em que estes não sejam compostos por itens. E é impossível imaginar um ítem de pedido que não tenha pedido. Neste caso, as classes Pedido e ItemPedido estariam em um pacote e seria fácil a reutilização em qualquer sistema que necessite de pedidos.

segunda-feira, 27 de julho de 2009

Como usar Scala no Eclipse

Neste artigo, mostrarei como usar o Eclipse como sua IDE para desenvolvimento em Scala.

Desde o meu post comentando o artigo do James Strachan, meu interesse na linguagem Scala só cresceu. Iniciei meus estudos, como todo bom aprendiz, com um editor de textos. Depois dos primeiros "Hello Words", resolvi buscar uma IDE e encontrei uma forma de usar o Eclipse para desenvolver com Scala. O processo é muito simples.

Requisitos recomendados:
  1. Java versão 1.6, update 14 ou superior (versão 5 no mínimo);
  2. Distribuição standard do Eclipse 3.5 ou superior.

Instalação: A IDE do Scala para Eclipse é melhor instalada (e atualizada) através do próprio Eclipse.
  1. Selecione Help -> Install new software
  2. Clique no botão Add Site...
  3. Entre com esta URL, http://www.scala-lang.org/scala-eclipse-plugin, na caixa Location
  4. Depois de clicar em OK, você deve ver "Scala Eclipse Plugin" como opção de instalação
  5. Clique no botão "Install..." e siga as instruções a partir daqui.

Terminada a instalação, você já será capaz de criar projetos Scala no Eclipse.

Veja abaixo um exemplo:

Links relacionados:
Tutorial em inglês: http://www.scala-lang.org/node/94
Site oficial: http://www.scala-lang.org/
 
Tema para Blogger Denim 233 por Darren Delaye
Modificado por :: Blogger'SPhera ::
| Copyright © 2008 |