Orientação a objetos é fácil, as pessoas é que complicam

A idéia de escrever este post veio desta discussão no GUJ, que começou falando de testes unitários e terminou sobre orientação a objetos.
Então seguem as minhas opiniões.


As linguagens de programação mais modernas, ou pelo menos as mais utilizadas de hoje em dia são Orientadas a Objeto, as famosas linguagens OO, mas mesmo assim, a grande maior parte dos desenvolvedores parece não conseguir entender direito a tal da Orientação a Objeto.
Resolvi escrever este este post porque do alto do meu ego inflado, acredito conseguir entender corretamente OO e poder ajudar um pouco.
Então, leiam o post até o final, e depois se quiserem tirar dúvidas ou me xingar, é só deixar um comentário …

O primeiro erro que todos cometem ao iniciar em OO é achar que Orientação a Objetos é sobre classes, isto não faz nenhum sentido, Orientação a Objetos como o próprio nome diz, é sobre Objetos, então, qualquer coisa que não seja um objeto não é realmente importante quando se fala em Orientação a Objetos.
OK, mas por que todos caem no mesmo engano então? porque a grande maior parte das linguagens de programação orientadas a objeto, utilizam classes como moldes para objetos, e durante o desenvolvimento se cria os moldes, ja que os objetos só existem em tempo de execução nestas linguagens.
Quais linguagens não funcionam assim? Bom, agora me vem a cabeça SmallTalk, IO e Ruby, mas devem ter outras.
SmallTalk porque não existe realmente distinção entre “tempo de desenvolvimento” e “tempo de execução” em SmallTalk, tudo esta sempre executando.
IO porque não utiliza o conceiro de classes (a não ser que eu tenha entendido a linguagem errado) e sim objetos template.
E Ruby porque as classes em Ruby são objetos também, mas das três é a que mais se aproxima do “padrão” que citei antes.

Outro erro bastante comum, desta vez quando se utiliza alguma tecnologia de mapeamento Objeto/Relacional, é achar que objetos são tabelas, mapeamento Objeto/Relacional serve para salvar o estado de um objeto em um banco de dados relacional, apenas isto, um objeto do tipo Usuario por exemplo, não possui um atributo “grupo_id”, mas pode possuir um relacionamento com um objeto do tipo Grupo. Percebam que eu escrevi atributo e não campo, pois tabelas tem campos e linhas, objetos possuem atributos e métodos.

Uma coisa bastante comum, ainda utilizando mapeamento O/R é achar que um objeto possui os mesmos atributos que a tabela correspondente, mas neste caso até os nomes são diferentes, infelizmente nestes casos, um objeto precisa ter um atributo “id” que mapeia para a chave primária da tabela, mas um objeto não tem uma chave primária, ele tem apenas atributos.

Então, como solucionar estes problemas?
Bom, no geral, um objeto tem comportamento, e alguns atributos também, mas o importante em um objeto é o que ele faz e como ele faz.
Claro que existem objetos que não tem comportamento, objetos em um sistema são a representação binária de alguma coisa do mundo real, e existem coisas no mundo real que não tem comportamento, tem apenas atributos, como por exemplo mesas e cadeiras, mas exceto se você estiver mapeando um destes objetos no seu sistema, todos os objetos tem um comportamento.
Por exemplo, se você criar um objeto do tipo Usuário, se ele não possuir nenhum comportamento, com certeza o seu sistema esta construído de forma errada, pois pelo menos eu, não conheço nenhum usuário que fique parado como uma estátua o tempo todo, e se este for o caso, com certeza ele não é usuário de sistema nenhum, portanto ele não deveria existir no seu sistema.
A mesma coisa se aplica a um carro, você conhece algum carro que não se move? Que não tenha comportamento algum? A única desculpa para um carro que não tem comportamento algum é um sistema para um museu de carros, onde só importa a carcaça do carro e os atributos dele, principalmente o ano de fabricação.

Outra coisa que todos entendem errado é o padrão MVC (Model, View, Controller).
Na definição do padrão, o controlador esta la apenas como ponto de entrada, ele passa parâmetros para um método de um Model, pega o resultado disto e passa para uma View, se ele estiver fazendo mais do que isto, ele possui parte do código que deveria estar dentro do Model, por tanto, o seu Controller esta errado!

Beleza, mas se eu estou dizendo que todos cometem os mesmos erros, como eu posso dizer que OO é fácil então?
Porque a maioria aprende primeiro a programar de forma estrutural, e depois passa para orientação a objetos, e como as pessoas aprendem coisas novas utilizando como base suas experiências anteriores, utilizam os paradigmas procedurais para tentar programar orientado a objetos, esta é basicamente a raiz do problema.
Para tornar a vida de todos mais fácil, o primeiro contato com programação nos cursos e faculdades deveria ser com SmallTalk e não com portugol ou pascal.
Se você aprender primeiro orientação a objetos, conseguira passar para programação procedural com uma facilidade muito maior do que alguem que aprende primeiro programação procedural tentando aprender orientação a objetos.

O pior é que as linguagens de programação que não são 100% OO contribuem ainda mais para aumentar este problema, vamos pegar o Java como exemplo de uma linguagem não 100% OO.
“Mas me disseram que java era uma linguagem de programação OO”
Bom isto também é verdade, eu disse não 100% OO, não disse que não era OO.
Exemplos de coisas que não são OO em Java: tipos primitivos e métodos estáticos
Basicamente eu acho que na linguagem é só isto que não é OO, mas isto ja causa problemas o suficiente confundindo a cabeça de muita gente.
“Perai, métodos estáticos ficam dentro de classes, como podem não ser OO?”
Mérodos estáticos são uma forma porca de programação procedural dentro de uma linguagem OO que teve uma linguagem procedural como origem, como por exemplo o Java e o C++.
Métodos estáticos não fazem parte de uma classe, utilizam a classe apenas como namespace, o que é diferente de fazer parte.
Em um método estático, não é possível nem saber a qual classe ele pertence, como é possível tanto em object pascal quanto em Ruby, ja que estas não possuem métodos estáticos e sim métodos de classe.
E os tipos primitivos estes sim, não tem relação nenhuma com orientação a objetos, só estão la porque quando a linguagem foi criada não era possível fazer uma classe ter a mesma performance do que um tipo mapeado diretamente do processador da máquina, eles existem em Java por problemas de performance e não por serem Orientados a Objeto.

Alguns design patterns foram criados apenas para contornar limitações da pataforma (Exemplo prático, com um banco de dados OO decente não seria necessário criar o pattern DTO), da mesma forma algumas das regras sobre a utilização de OO foram criadas apenas porque a maioria das pessoas não entende OO, como a regra que diz favoreça composição em vez de herança.
Este é um engano terrível cometido por muitas pessoas que eu não consigo entender.
Muita gente acha que estender uma classe é uma forma de compartilhar código, por exemplo:
Existe uma entidade no sistema de nome Cliente, e em algum momento é necessário criar um ClienteDependente que vai possuir todos os mesmos atributos de cliente mais um que aponta para o responsável, não faz sentido algum fazer ClienteDependente estender Cliente para compartilhar este código, porque o comportamento deles não é o mesmo, por exemplo, ClienteDependente não paga a conta, mas Cliente sim, neste caso seria melhor refatorar o sistema e criar uma entidade que pudesse realizar compras (Ou criar objetos do tipo Compra se o sistema foi bem modelado), e fazer com que Cliente e ClienteDependente estendessem desta, pois neste caso elas estariam realmente compartilhando o comportamento e não apenas evitando algum código aparentemente repetido.
Estender uma classe é estender o comportamento, ou seja, só faz sentido estender o comportamento se a classe “filha” tiver todo o comportamento da classe “pai”, ou seja, é um relacionamento o tipo “é um”. Mas como quase ninguém consegue entender que estender uma classe estende o comportamento (não me parece uma coisa tão complexa assim para se entender), foi criada esta regra que diz: Não use herança, use composição. Simplesmente para evitar que pessoas façam porcaria por não entender conceitos que são estupidamente simples, mas que todos tem mania de complicar.

Outro erro bastante comum é tentar colocar em uma classe apenas o comportamento de todo o sistema, se for para fazer isto, utilize programação procedural, pois você vai estar utilizando a classe apenas como namespace mesmo, não vai nem lembrar que em tempo de execução estara trabalhando com diversos objetos criados a partir daquela forma.

Orientação a objetos é simples, é um paradigma de desenvolvimento que modela um sistema transformando conceitos do mundo real como objetos que colaboram entre si para atingir um objetivo.
Acho que o nome Objeto pode ajudar a confundir boa parte das pessoas, pois em um sistema OO, Compra pode ser um tipo de Objetos, mas no mundo real, compra não é um objeto. Mas para resolver isto eu simplesmente assumo que qualquer um que queira ser um programador precisa ter capacidade para trabalhar com abstrações, não tenho uma explicação melhor para alguem que não consegue entender que Compra pode ser um tipo de Objeto em um sistema OO, assim como Viajem também pode ser um tipo de Objeto (estou utilizando “Tipo de Objeto” em vez de classe porque o que importa em um sistema OO são as instâncias e não as classes) dependendo do problema a ser resolvido.

Acho que são estes os erros mais comuns na orientação a objetos, lendo isto você não concorda comigo? OO é simples, as pessoas é que complicam!
Você lembra de algum outro erro muito comum em OO? deixe um comentário.
Se eu lembrar de mais coisas simples que as pessoas tem mania de complicar eu escrevo outro post.

Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!

Gravando ScreenCasts no Linux(Ubuntu/Kubuntu)! E rodando em qualquer PC ou disponibilizando via WEB.

Bom, tem bastante gente que quer criar ScreenCasts no linux mas tem não faz a menor idéia de como fazer isto, segue um passo a passo para fazer isto no Ubuntu/Kubuntu!
E vocês vão ver que nem são tantos passos assim :D

ffmpeg-logo.png flv-75.jpg
logo-name.png tux-director-t2.gif
  1. para instalar os comandos que utilizaremos utilize o seguinte comando
  2. $sudo apt-get install gtk-recordmydesktop mplayer mencoder ffmpeg
  3. para gravar o screencast, basta abrir o gtk-recordmydesktop e seguir as informações na tela
  4. O video gravado se estiver muito grande (resolução alta da tela, como no meu caso 1280×800), apenas o mplayer vai conseguir reproduzir, parece que o theora tem problemas para gerenciar memória
  5. O video gerado estara no formato Ogg Theora, que apenas funciona em linux, e tem 1 encoder para windows, então vamos transformalo em algo utilizável
  6. $mencoder [arquivo].ogg -o [arquivo].avi -ovc lavc -oac lavc
  7. Pronto, agora possuímos um video que poe ser visualizado em qualquer plataforma :D
  8. Quer ainda colocar ele na web como um screencast? como o deste post?
  9. $ffmpeg -i [arquivo].avi [arquivo].flv
  10. pronto, agora possuímos um video em flash, falta só o player

Se você trabalha com flash pode fazer um quando quiser, acredito que não seja complexo, como este não é o meu caso, este player open source faz o trabalho muito bem! JW FLV Player

Prontinho, ja pode encher o seu site de screencasts :D

Acho que este foi o passo a masso mais simples e direto para criaçao de screencasts no linux que eu ja vi até gora :D

Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!

Implementando Login com Ruby on Rails (exemplo simples)

Bom, ja que fui criticado por “incentivar a utilização de JSF”, vou fazer mais alguns pequenos tutoriais de como implementar um login com outros frameworks, e este sim é para incentivar a utilização, ja que estou gostando bastante do Ruby On Rails :D

Antes de comparar os dois exemplos, lembre-se de que o Ruby On Rails te da uma estrutura pronta de aplicação, por tanto não vou precisar mostrar como configurar a base de uma aplicação como foi feito no outro exemplo

Comecemos criando uma aplicação Ruby On Rails:

$rails nomeDaAplicação

Depois, vamos criar um controller para a autenticação:

$script/generate controller login login

Isto vai criar um controller de nome login, e uma view de nome login também.

O código do login_controller.rb vai ficar mais ou menos assim:

class LoginController < ApplicationController
def index
render :action => 'login'
end
def login
end
def do_login
username = params[:username]
password = params[:password]
if username.nil? || password.nil? || username==password
redirect_to :action => "login"
flash[:notice] = 'Usuário ou senha incorretos'
else
session["user_id"] = username
redirect_to :controller => "secure", :action => "index"
end
end
end

Basicamente o controller tem implementado apenas o método do_login, que vai fazer uma validação bem complexa, de o usuário e a senha terem sido fornecidos e não serem iguais, você pode adaptar isto a sua aplicação mais tarde …

A view de login, vai ficar assim:

<% form_tag :action => 'do_login' do %>
<table align="center" class="loginForm">
<tr>
<td>
<%= image_tag "botao_login.png" %>
</td>
<td>
<input type="text" name="username"/>
</td>
</tr>
<tr>
<td>
<%= image_tag "botao_senha.png" %>
</td>
<td>
<input type="password" name="password" />
</td>
</tr>
<tr>
<td colspan="2">
<%= image_submit_tag "box_avancar.png", :style => 'width:75px;height:25px;' %>
</td>
</tr>
<table>
<% end %>

É uma view simples, apenas com um formulário e dois campos …

Ok, beleza, e como é que eu uso isto?

Vamos começar alterando application.rb, o código vai ficar assim:

class ApplicationController < ActionController::Base
# Pick a unique cookie name to distinguish our session data from others'
session :session_key => '_untitled6_session_id'
before_filter :authorize
protected
# Override in controller classes that should require authentication
def secure?
false
end
private
def authorize
if secure? && session["user_id"].nil?
session["return_to"] = request.request_uri
redirect_to :controller => "login", :action => "login"
return false
end
end
end

O que fizemos foi adicionar um filter a todos os métodos de todos os controllers, que vai interceptar a chamada a todos os métodos, e por padrão não vai fazer nada (o método secure? retorna false por padrão), caso o controller sobreescreva este método e faça-o retornar true, o filtro vai verificar se existe um user_id na sessão, se existir segue o processamento normal, caso contrário redireciona para o login.

E como utilizamos isto? vamos fazer um exemplo de um controller que vai precisar de segurança …

$script/generate controller seguro index

Para gerar um controller de nome seguro, e com uma ação de nome index.

Agora vamos alterar o código do securo_controller.rb

class SeguroController < ApplicationController
def index
end
protected
def secure?
true
end
end

Sobre escrevendo o método secure? para retornar true, fizemos com que todos os métodos deste controller precisem de autenticação para permitir o acesso.

E se quisermos que apenas alguns métodos precisem de autenticação?

Podemos utilizar algo parecido com este código:

protected
def secure?
["metodoSegro","outroMetodoSeguro"].include?(action_name)
end

Tudo pronto, login implementado …

Mas como no exemplo com JSF, ainda podemos melhorar esta implementação, por exemplo, armazenando na sessão os grupos do usuário para poder fazer uma melhor verificação dentro dos métodos …

Outra possível melhoria, seria aproveitar o atributo: session["return_to"] dentro do método do_login para redirecionar o usuário para a URL que ele tentou acessar originalmente ...

E como no último post, deixo algumas perguntas para vocês:

  1. Quais outras possíveis melhorias vocês vêem neste exemplo?
  2. Quais problemas vocês vêem nesta implementação?

Para quem estiver interessado em mais detalhes sobre Ruby On Rails, podem dar uma olhada no tutorial que eu traduzi:

Quatro dias de Ruby On Rails - Primeiro dia, Quatro dias de Ruby On Rails - Segundo dia,

Quatro dias de Ruby On Rails - Terceiro Dia, Quatro dias de Ruby On Rails - Quarto Dia

A próxima implementação de login, acho que vai ser com o Wicket, até para eu aprender um pouco sobre ele :D (seufagner, não se anima a escrever este para postar aqui?)

Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!

Implementando Login com JSF (exemplo simples)

English Version Here

Bom, uma das perguntas mais frequentes de quem esta começando a estudar JSF é como implementar um Login, e esta foi uma das perguntas mais frequentes que vi no GUJ e em comentários aqui no blog também …

Antes de começar, quem quiser usar JSF com JPA é só dar uma olhada neste post que escrevi a algum tempo.

Agora vamos dar uma olhada rápida em algumas formas de implementar login com JSF.

A primeira abordagem é uma implementação manual, que nesta versão só verifica se o usuário ja esta logado, mas é possível estende-la facilmente para utilizar grupos.

Primeiro vamos começar com a configuração do web.xml …

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<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>/faces/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<error-page>
<exception-type>java.lang.SecurityException</exception-type>
<location>/login.jsf</location>
</error-page>
</web-app>

Como podem ver, eu criei uma aplicação WEB com servlets 2.5, estou utilizando JSF 1.2, mas para este exemplo a versão não faz muita diferença, e configurei o servlet container para que no caso de uma java.lang.SecurityException ele redireccione para a página de login da aplicação.

Depois disto, vamos começar a escrever alguns beans, vou utilizar dois beans simples, um para gerenciar o login:

package br.com.urubatan.jsfjpasec;
public class Login {
private boolean loginOk;
private String userName;
private String password;
public boolean isLoginOk() {
return loginOk;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String validateLogin(){
if(userName!=null && password!=null && !userName.equalsIgnoreCase(password)){
loginOk = true;
return "secpage";
}else return "login";
}
}

É uma classe bastante simples, ele tem 3 propriedades, o nome e senha do usuário, e uma propriedade dizendo que o login esta OK, este é o ponto de extensão para adicionar suporte a grupos mais tarde se quiserem.

E este bean que vai conter todos os dados da aplicação (neste exemplo, dados estáticos), ele tem duas propriedades que possuem dados estáticos apenas para este exemplo, se quiserem utilizar JPA basta misturar com este exemplo ou com um destes.

package br.com.urubatan.jsfjpasec;
import java.util.List;
import java.util.ArrayList;
public class SomeData {
private List<String> data = new ArrayList<String>();
private List<String> securedData = new ArrayList<String>();
private boolean loginOk;
public SomeData() {
for(int i=0;i<10;i++){
data.add("Dados Simples " + i);
securedData.add("Dados Seguros " + i);
}
}
public void setLoginOk(boolean loginOk) {
this.loginOk = loginOk;
}
public List<String> getSecuredData() {
if(!loginOk)
throw new SecurityException();
return securedData;
}
public List<String> getData() {
return data;
}
}

Como podemos ver, ele possui apenas os getters dos dados, e o método de leitura dos dados seguros, verifica a propriedade loginOk que deve ter sido fornecida pelo bean de login, vamos configurar isto no faces-config.xml a seguir.

Caso o usuário não tenha se identificado ainda, apenas geramos uma SecurityException e o container cuida de mandar isto para a página de login, como foi configurado no web.xml.

Agora um pouco mais de XML, vamos configurar os navigation cases necessários para a aplicação e os relacionamentos entre os beans ja criados, no caso, configurar a propriedade loginOk do bean de dados com a mesma propriedade do bean de login.

<?xml version='1.0' encoding='UTF-8'?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
version="1.2">
<managed-bean>
<managed-bean-name>login</managed-bean-name>
<managed-bean-class>br.com.urubatan.jsfjpasec.Login</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>mdata</managed-bean-name>
<managed-bean-class>br.com.urubatan.jsfjpasec.SomeData</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>loginOk</property-name>
<property-class>java.lang.Boolean</property-class>
<value>#{login.loginOk}</value>
</managed-property>
</managed-bean>
<navigation-rule>
<from-view-id>/login.jsp</from-view-id>
<navigation-case>
<from-outcome>
login
</from-outcome>
<to-view-id>
/login.jsp
</to-view-id>
<redirect/>
</navigation-case>
<navigation-case>
<from-outcome>
secpage
</from-outcome>
<to-view-id>
/secureView.jsp
</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
</faces-config>

Os casos de navegação nesta aplicação bastante complexa são utilizados apenas pelo bean de login, no método que valida o login (baita validação, apenas verifica se foram informados um nome e uma senha e se os dois não são iguais, mas este é outro problema :D )

Com isto toda a lógica necessária para a aplicação esta pronta, falta apenas criarmos as páginas utilizadas, então segue o código delas:

login.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<html>
<head><title>System Login</title></head>
<body>
<f:view> <h:form>
<h:panelGrid columns="2">
<h:outputLabel value="User Name" for="un"/>
<h:inputText id="un" value="#{login.userName}"/>
<h:outputLabel value="Password" for="pw"/>
<h:inputText id="pw" value="#{login.password}"/>
</h:panelGrid>
<h:commandButton value="Login" action="#{login.validateLogin}"/>
</h:form>
</f:view>
</body>
</html>

Como podemos ver é apenas uma página JSF simples com um formulário e dois campos, chamando o método vaidateLogin de um bean de nome login.

dataView.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<html>
<head><title>Unsecured Data Page</title></head>
<body>
<f:view>
<h:dataTable value="#{mdata.data}" var="v">
<h:column>
<f:facet name="header">
<h:outputText value="Data List"/>
</f:facet>
<h:outputText value="#{v}"/>
</h:column>
</h:dataTable>
<h:panelGrid columns="3">
<h:outputLink value="dataView.jsf">
<h:outputText value="Data that every one can access"/>
</h:outputLink>
<h:outputLink value="secureView.jsf">
<h:outputText value="Data that you can view after login"/>
</h:outputLink>
<h:outputLink value="login.jsf">
<h:outputText value="Login"/>
</h:outputLink>
</h:panelGrid>
</f:view>
</body>
</html>

Como podemos ver também é uma página bem simples, com apenas uma dataTable listando os dados da propriedade data de um bean de nome mdata.


secureView.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<html>
<head><title>Secured Data Page</title></head>
<body>
<f:view>
<h:dataTable value="#{mdata.securedData}" var="v">
<h:column>
<f:facet name="header">
<h:outputText value="Data List"/>
</f:facet>
<h:outputText value="#{v}"/>
</h:column>
</h:dataTable>
<h:panelGrid columns="3">
<h:outputLink value="dataView.jsf">
<h:outputText value="Data that every one can access"/>
</h:outputLink>
<h:outputLink value="secureView.jsf">
<h:outputText value="Data that you can view after login"/>
</h:outputLink>
<h:outputLink value="login.jsf">
<h:outputText value="Login"/>
</h:outputLink>
</h:panelGrid>
</f:view>
</body>
</html>

Esta também é uma página simples, praticamente igual a anterior, mas desta vez, lendo a propriedade securedData do bean mdata, nesta propriedade o bean verifica se o usuário tem acesso, caso contrário gera uma excessão.

por último temos a página index.jsp que apenas possui um link para a página dataView.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Entry Page</title></head>
<body>Entry Page, this could redirect to the JSF Index, but for now, click here: <a href="dataView.jsf">JSF Index</a>
</body>
</html>

com isto temos uma implementação bem simples de um login em uma aplicação JSF, bom para quem esta começando a estudar a tecnologia.

Como melhorias poderíamos mudar a propriedade loginOk para um Map<String,Boolean> tendo como chave os nomes dos possíveis grupos e como valores veradeiro se o usuário pertence aquele grupo.

Outra melhoria interessante seria utilizar um h:inputSecret para a senha em vez de um inputText como estou utilizando no exemplo.

Outra possível melhoria seria utilizar uma combinação de anotações e AOP como esta implementado no Spring-Annotations. (se quiserem posso postar outro dia um exemplo de implementação de segurança com o SA).

Uma outra possível alteração seria utilizar JAAS para a segurança declarativa e deixar isto por conta do container.

Agora algumas perguntas para vocês:

  1. Quais outras possíveis melhorias vocês vêem neste exemplo?
  2. Quais problemas vocês vêem nesta implementação?
  3. Vocês gostariam de outros exemplos deste estilo aqui no blog?
  4. Vocês já estão utilizando JSF?

Acho que era isto, espero que o exemplo seja útil para alguém :D

PS.: para os que forem rodar a aplicação, são necessários apenas os jars: jstl.jar, jsf-api.jar e jsf-impl.jar (se forem utilizar a JSF-RI como eu).

Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!

O filtro do tato (por que nerds/geeks tem problemas de relacionamento com outras pessoas)

Bom, eu sou um exemplo vivo, pelo menos eu acho que sim, de que nerds, geeks ou como preferirem ser chamados, tem problemas no trato com outras pessoas.
Sempre acham que eu sou direto demais, ou que sou grosso, ou qualquer coisa do gênero.
Na verdade, eu concordo que sou direto demais, não com a parte de ser grosso.
Eu acredito que se eu penso alguma coisa, eu posso dizer aquilo, e azar é de quem estiver ouvindo, mas isto ja me trouxe muitos problemas.
Mesmo, pelo menos na minha opinião, eu sendo um dos melhores na parte técnica do que eu faço, eu acabo sempre me prejudicando por falar o que eu penso e outras pessoas não gostarem de ouvir isto, o que prejudica inclusive o crescimento profissional …
Eu ja tentei ser gerente de projetos, e tenho a consciência de que pelo menos por enquanto não seria um bom gerente …
Em empresas que eu trabalhei, ja houveram casos em que mesmo sabendo que eu tinha a resposta, colegas de trabalho evitavam perguntar alguma coisa para mim.

Bom, eu ja melhorei muito neste ponto, acho que hoje sou razoavelmente conhecido na “comunidade java” aqui no Brasil, e cheguei a ouvir de um gerente: Bahh, legal, não sabia que tu era “O Urubatan”.
Mas melhorei isto com muito custo, e não foi muito fácil …

Mas voltando ao assunto deste post, eu encontrei um texto excelente que explica muito bem, na minha opinião, por que a maioria dos Nerds tem problemas no relacionamento com outras pessoas “Não Nerd”.
O texto original é este: “Tact Filters“.

A baixo segue uma tradução livre deste excelente texto.


Filtros de tato

Todas as pessoas possuem um “filtro de tato”, que aplica um filtro de “trato social” em uma direção há tudo que passa por ele. A maioria das “pessoas normais” tem este filtro posicionado para filtrar tudo o que elas falam ou fazem. Então toda e qualquer coisa que as “pessoas normais” dizem, tem a quantidade ideal de “filtro para trato social” aplicado, antes de elas realmente falarem. Isto normalmte acontece por que quando eles estavam crescendo, os seus pais continuamente diziam para eles coisas como: “Se você não pode dizer algo de bom, não diga nada!”, ou então “Não diga este tipo de coisa, vai fazer com que eles se sintam mal!”.

“Nerds”, por outro lado, tem este filtro, aplicado na posição contrária, ou seja, tudo o que eles ouvem é filtrado. Então, qualquer coisa que qualquer um diz para eles, tem a quantidade adequada de “filtro social” aplicado quando eles ouvem. Isto normalmente é por que quando eles estavam crescendo, as outras crianças ficavam incomodando e dizendo coisas desagradáveis, e os seus pais diziam o tempo todo: “Eles estão dizendo estas coisas só por que eles estão com ciúmes”.

Quando “pessoas normais” conversam entre si, elas normalmente aplicam a quantidade apropriada de “tato social” para tudo o que eles dizem, e ninguém sai com os sentimentos feridos. Quando “Nerds” conversam entre si, eles normalmente aplicam a quantidade adequada de “tato social” a tudo o que eles ouvem, e ninguém sai com os sentimentos feridos. Entretanto, quando pessoas normais, falam com “Nerds”, os “Nerds” ficam frustrados com freqüência, por que as “pessoas normais” parecem estar sempre evitando de dizer o que eles realmente querem. E pior ainda, quando “Nerds” falam com “pessoas normais”, estas com freqüência saem com os sentimentos feridos, por que os nerds não aplicam o filtro ao que eles estão falando, esperando que o ouvinte o faça.

Então, os “nerds” precisam entender que as “pessoas normais”, precisam aplicar este filtro para tudo o que eles dizem, eles ficam desconfortáveis se eles não puderem fazer isto. “Pessoas normais” precisam entender que fora o fato de os nerds normalmente não possuirem “tato”, as coisas que eles dizem quase nunca devem ser tomadas como pessoais. Ambos os tipos de pessoas precisam ter uma quantidade extra de paciência quando estiverem lidando com alguém que possua o “filtro de tato” na direção oposta a sua.



Acho que este texto explica mais ou menos bem, os motivos destes “conflitos” entre os “nerds” e as outras pessoas.
É possível para um nerd amenizar bastante este problema, acho que na maior parte das situações eu ja melhorei muito, mas eu continuo achando irritante quando as pessoas ficam cuidando o que vão falar, ou até mesmo falando claramente algo diferente do que estão pensando apenas para não “ferir os sentimentos” de quem esta ouvindo.
As vezes eu até encaro isto como um pouco de hipocrisia.
Mas quem sou eu para querer mudar o mundo …Então, o que vocês acham deste texto, não é mais ou menos isto o que acontece? mesmo os motivos originais mudando bastante de uma pessoa para outra …
Eu acho que entender esta “teoria” tem me ajudado bastante, e um exercício de paciência de vez em quando ajuda muito também :D

O texto original é de autoria de: Jeff Bigler.
Todos os outros comentários e tradução são de minha autoria :D

Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!

Quatro dias de Ruby On Rails - Quarto e último dia

Quatro dias de Ruby On Rails - Primeiro dia, Quatro dias de Ruby On Rails - Segundo dia,

Quatro dias de Ruby On Rails - Terceiro Dia

Vamos começar agora o quarto e último dia de nosso tutorial …

A tela de Notas

Claro que o Scaffold daentidade Notes, ja cria uma estrutura completa CRUD para as notas, mas não queremos que o usuário acesse isto diretamente.

Queremos poder linkar uma nota a uma tarefa ja existente.

E caso ja exista uma nota para esta tarefa, precisamos poder editar ou remove-la.

Primeiro, vamos dar uma olhada novamente na tela de edição de tarefas. Atualmente ela ja ajusta os botões caso exista ou não uma nota para esta tarefa.

<% @heading = "Edit To Do" %>
<%= error_messages_for 'item' %>
<%= start_form_tag :action => 'update', :id => @item %>
<table>
<%= render_partial "form" %>
<tr>
<td><b>Notes: </b></td>
<% if @item.note_id.nil? %>
<td>None</td>
<td><%= link_to_image "note", :controller => "notes", :action => "new", :id => @item.id %></td>
<% else %>
<td><%=h @item.note.more_notes %></td>
<td><%= link_to_image "edit_button", :controller => "notes", :action => "edit", :id => @item.note_id %></td>
<td><%= link_to_image "delete_button", {:controller => "notes", :action => "destroy", :id => @item.note_id }, :confirm => "Are you sure you want to delete this note?" %></td>
<% end %>
</tr>
</table>
<hr />
<%= submit_tag "Save" %>
<%= submit_tag "Cancel", {:type => 'button', :onClick=>"parent.location='" + url_for( :action => 'list' ) + "'" } %>
<%= end_form_tag %>

A tela de edição de notas.

Editar uma nota é bastante fácil, segue o template:

<% @heading = "Edit Note" %>
<%= start_form_tag :action => 'update', :id => @note %>
<%= render_partial "form" %>
<%= submit_tag "Save" %>
<%= submit_tag "Cancel", {:type => 'button', :onClick=>"parent.location='" + url_for( :controller => 'items', :action => 'list' ) + "'" } %>
<%= end_form_tag %>

E o Partial Correspondente:

<table>
<tr>
<td><label for="note_more_notes">More notes</label></td>
<td><%= text_area 'note', 'more_notes' %></td>
</tr>
</table>

Assim que o update ou destroy de uma nota é completado, precisamos voltar a tela de listagem de tarefas.

def update
@note = Note.find(params[:id])
if @note.update_attributes(params[:note])
flash[:notice] = 'Note was successfully updated.'
redirect_to :controller => 'items', :action => 'list'
else
render :action => 'edit'
end
end
def destroy
Note.find(params[:id]).destroy
redirect_to :controller => 'items', :action => 'list'
end

Lembrem-se que as regras de integridade referencial, ja definidas no model e estas vão garantir que caso removamos uma nota, as referencias para a mesma serão removidas automaticamente.

A tela de criação de Notas.

Criar uma nova nota é um pouco mais complicado. O que queremos fazer é:

  • Armazenar a nota na tabela notes.
  • Localizar o ID da nota recem criada.
  • Armazenar o ID da nota recem criada no campo note_id da tarefa associada.

Variáveis de sessão são uma ótima forma de armazenar valores entre telas, vamos utilizar esta abordagem para armazenar o ID da tarefa associada a nova nota.

Documentação: ActionController::Base

Primeiro, quando clicamos no link para criar uma nova nota, nos passamos o ID da tarefa associada:

app\views\items\edit.rhtml (excerpt)

<td><%= link_to_image "note", :controller => "notes", :action => "new", :id => @item.id %></td>

O método “new” no controller de notas armazena este ID na sessão:

app\controllers\notes_controller.rb (excerpt)

def new
@session[:item_id] = @params[:id]
@note = Note.new
end

O template de “New Notes” não tem nenhuma novidade:

<% @heading = "New Note" %>
<%= start_form_tag :action => 'create' %>
<%= render_partial "form" %>
<%= submit_tag "Save" %>
<%= submit_tag "Cancel", {:type => 'button', :onClick=>"parent.location='" + url_for(:controller => 'items', :action => 'list' ) + "'" } %>
<%= end_form_tag %>

O método “create” pega o ID novamente da sessão, utiliza o mesmo para buscar a tarefa do banco e atualizar o campo “note_id” na tabela items, e novamente redireciona a tela para a listagem de tarefas.

app\controllers\notes_controller.rb (excerpt)

def create
@note = Note.new(@params[:note])
if @note.save
flash['notice'] = 'Note was successfully created.'
@item = Item.find(@session[:item_id])
@item.update_attribute(:note_id, @note.id)
redirect_to :controller => 'items', :action => 'list'
else
render_action 'new'
end
end

Algumas alterações na tela de categorias.

Não sobrou muita coisa para fazer no sistema agora, alem de pequenos ajustes nas telas criadas no primeiro dia para que tenham o mesmo esquema de navegação por botões.

app\views\categories\list.rhtml

<% @heading = "Categories" %>
<form action="/categories/new" method="post">
<table>
<tr>
<th>Category</th>
<th>Created</th>
<th>Updated</th>
</tr>
<% for category in @categories %>
<tr>
<td><%=h category["category"] %></td>
<td><%= category["created_on"].strftime("%I:%M %p %d-%b-%y") %></td>
<td><%= category["updated_on"].strftime("%I:%M %p %d-%b-%y") %></td>
<td><%= link_to_image 'edit', { :action => 'edit', :id => category.id } %></td>
<td><%= link_to_image 'delete', { :action => 'destroy', :id => category.id },:confirm => 'Are you sure you want to delete this category?' %></td>
</tr>
<% end %>
</table>
<hr />
<input type="submit" value="New Category..." />
<input type="button" value="To Dos" onClick="parent.location='<%= url_for(:controller => 'items', :action => 'list' ) %>'">
</form>

app\views\categories\new.rhtml

<% @heading = "Add new Category" %>
<%= error_messages_for 'category' %>
<%= start_form_tag :action => 'create' %>
<%= render_partial "form" %>
<hr />
<input type="submit" value="Save" />
<input type="button" value="Cancel" onClick="parent.location='<%= url_for( :action=> 'list' ) %>'">
<%= end_form_tag %>

app\views\categories\edit.rhtml

<% @heading = "Rename Category" %>
<%= error_messages_for 'category' %>
<%= start_form_tag :action => 'update', :id => @category %>
<%= render_partial "form" %>
<hr />
<input type="submit" value="Update" />
<input type="button" value="Cancel" onClick="parent.location='<%= url_for( :action=> 'list' ) %>'">
<%= end_form_tag %>

Navegação pelo sistema

O grafo final de navegação pelo sistema é mostrado na imagem a baixo. Qualquer código redundante gerado pelo scaffold pode ser removido sem problemas (por exemplo show.rhtml). Esta é a beleza do scaffold, ele não te custa nada, então pode ser simplesmente excluido quando não for necessário.

Configurando a página inicial da aplicação.

Primeiro renomeie o arquivo pub.ic/index.html para public/index.html.orig

E edite o arquivo:

config\routes.rb (excerpt)

map.connect '', :controller => 'items'

Pronto, agora a tela inicial da aplicação é a listagem de tarefas.


Então era isto, fica faltando apenas o último post com os apendices.
Se tiverem duvidas é só entrar em contato :D

PS.: agradeço se os leitores que estão gostando do tutorial colocarem links em seus blogs para o tutorial, indicando para seus amigos.

Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!

Quatro dias de Ruby On Rails - Terceiro Dia

Quatro dias de Ruby On Rails - Primeiro dia, Quatro dias de Ruby On Rails - Segundo dia

Seguindo com a tradução do tutorial, vamos ao terceiro dia (desculpem pela demora, mas não andava com muita vontade de escrever :D )

Agora é hora de começar o “coração” da nossa aplicação. A tabela Itens contem a lista de “Tarefas”. Cada item pertence a uma categoria das que criamos no Segundo Dia, cada Item pode opcionalmente possuir uma nota, criada em uma tabela separada, mas esta vamos deixar para o próximo dia de Rails. Cada tabela possui uma chave primária chamada “id” que é utilizada também para fazer o link entre as tabelas. Read the rest of this entry »

Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!

Java on Rails - Produtividade em Java (Parte 3 - Grails)

Eu fiquei em duvida sobre o titulo deste artigo, achei que deveria ser Groovy On Rails, mas eu resolvi seguir a linha “Java On Rails” que eu vinha escrevendo a algum tempo atras (aqui, aqui) e quando eu mencionei o Grails no ano passado.

O Grails é a coisa mais parecida com o Java On Rails que eu encontrei até agora, Grails é um Groovy On Rails que foi escrito em Groovy, uma linguagem dinamica derivada do Java, e que roda na JVM.

Ele foi bastante inspirado no Rails mesmo, e tem inclusive algumas coisas que eu achei mais inteligentes que o proprio Rails (eles poderiam copiar de volta :D ). Read the rest of this entry »

Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!

Quatro dias de Ruby On Rails - Segundo dia

Quatro dias de Ruby On Rails - Primeiro dia

Seguindo com a tradução do tutorial, vamos ao segundo dia.

Para prosseguir alem do ponto onde ja chegamos, precisaremos olhar com maiores detalhes o que acontece por traz dos panos, principalmente o código gerado pelo scaffold.

Com a ação “scaffold :entidade” o rails gera o código necessário dinamicamente, mas podemos também gerar o código para que possamos ler e alterar … Read the rest of this entry »

Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!

Produtividade com JSF + JPA sem nenhum outro framework, com DI e edição via GET em vez de POST

Bom, eu vi hoje em um post em outro blog, que o JSF-RI 1.2 possui suporte para anotações e DI, então resolvi fazer um pequeno teste de uma APP apenas com a JSF-RI e a RI do JPA para ver no que da, e até que ficou bem legal …

Deem uma olhada nisto, o JSF RI tem suporte a injeção de dependencias plugavel, ja tem suporte a GlassFish, Tomcat6 e Jetty6 de fabrica, e como veremos é bem fácil de extender isto …

A DI segue o mesmo estilo do Servlet 2.5, e EJB 3, ou seja, é feira via as anotações:

@PostConstrut, @PreDestroy, @PersistenceContext, @Resource, @EJB, …

Por padrão no tomcat, é sempre feito um lookup JNDI para buscar os objetos, mas vamos deixar os detalhes sórdidos para mais tarde …

Criei uma aplicação simples, sem nenhum framework adicional alem de JSF (1.2_04) e JPA (toplink), estou rodando com Java 6 e Tomcat 6.

Os unicos jars no classpath da aplicação são:

  • jsf-impl.jar
  • jsf-api.jar
  • jstl.jar
  • toplink-essentials-agent.jar
  • toplink-essentials.jar

Read the rest of this entry »

Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!

Quatro dias de Ruby On Rails - Primeiro dia

Bom, este post é uma tradução, adaptação e compactação do excelente tutorial de RoR que eu acabei de ler, para a versão original é só acessar este site.

Quatro dias de Ruby On Rails - Primeiro dia

4daysonrails.jpg

Introdução

Existem muitos anúncios extravagantes sobre o Rails por ai na internet. Por exemplo um artigo no OnLAMP.com dizendo que “você pode desenvolver aplicações web 10 vezes mais rápido com Rails do que com um framework padrão Java …”, depois disto o artigo passa a descrever como instalar Ruby e Rails em um PC criando uma aplicação padrão com “scaffold”, com nenhuma codificação.

Enquanto isto e impressionante, desenvolvedores “de verdade” sabem que isto não passa de “fumaça e espelhos”. Aplicações “reaid” não são tão simples assim. O que esta realmente acontecendo por baixo dos panos? Quão dificil é criar aplicações reais?

Nestas perguntas é que mora o perigo. Rails é extremamente bem documentado, provavelmente bem documentado demais para alguem que quer começar, são mais de 30.000 palavras de documentação online, no formato de um manual de referencia. O que esta faltando é um guia de por onde começar, apontando as páginas mais importantes para quem quer começar a desenvolver alguma coisa com rails.

Este tutorial serve para preencher este vazio. Ele assume que você ja tem o Ruby e o Rails ja instalado.
Read the rest of this entry »

Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!

Produtividade em Java em X passos Simples (Sera que desta vez eu termino de escrever?)

Seguinte galera, pela enézima vez, eu acho que vou escrever um livro, e para evitar de jogar trabalho fora, queria uma opinião de vocês …

Vocês leriam um livro com este titulo, e mais importante, que começasse mais ou menos assim:

Read the rest of this entry »

Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!

Tutorial: Google Guice - Injeção de dependencias by Google

Um pouco antes de ser anunciada a colaboração do google para o Hibernate, o Google lançou como open source, o Guice, um framework de injeção de dependencias que eles utilizavam internamente …

Mesmo ja fazendo algum tempo que o Guice foi lançado, eu ainda não tinha tirado algum tempo para testar o framework, então resolvi fazer isto hoje, e estou postando aqui as minhas primeiras impressões sobre ele em formato de mini tutorial …

O Guice é um framework de injeção de dependencias apenas, diferente do spring, que tem como base a injeção de dependencias, mas os outros recursos é que fazem realmente valer a pena a utilização dele … Read the rest of this entry »

Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!

Java on Rails - Produtividade em Java (Parte 2 ? J2EE Spider)

Pessoal aqui quem “fala” é o Bruno Braga, e fui convidado pelo Rodrigo para falar do J2EE Spider nessa série de posts sobre Produtividade em Java. Antes de começarmos, parabéns para o Rodrigo por posts de excelente qualidade e obrigado pelo espaço disponibilizado =)

Acredito que esse tema (produtividade) seja extremamente interessante para a maior parte dos desenvolvedores JEE. Uma grande coincidência é que entreguei há pouco um artigo para a revista Mundo Java justamente sobre esse tema (abordando a geração de código e o SPIDER). Veremos aqui um pouquinho do que vocês vão encontrar nas bancas em abril. Na verdade bem pouquinho mesmo, o artigo está imperdível.

Citando e concordando com o Urubatan: ?Um dos grandes problemas do Java EE como eu falei em outro post, é a necessidade de configurar tudo, a possibilidade de configurar é uma das maravilhas do Java, mas eu acho que a obrigação de configurar é um dos grandes problemas??. Read the rest of this entry »

Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!

Java on Rails - Produtividade em Java (Parte 1 - JBoss Seam)

Ok, tudo bem, não é exatamente um Rails da vida, mas tem uma grande vantagem, roda perfeitamente em servidores Java EE, que são ótimos em escalabilidade, na verdade muito melhores do que a maioria das plataformas que eu conheço.

Um dos grandes problemas do Java EE como eu falei em outro post, é a necessidade de configurar tudo, a possibilidade de configurar é uma das maravilhas do Java, mas eu acho que a obrigação de configurar é um dos grandes problemas …

Partindo disto, vou escrever uma pequena sequencia de posts (ainda não sei quantos), sobre formas de ser mais produtivo em Java EE com geração de código, e outras técnicas bastante interessantes, e frameworks mais modernos …

O primeiro da lista é o JBoss Seam, que tira bastante proveito de diversos recursos do Java EE 5, mas não obriga a aplicação a rodar em um servidor Java EE 5 completo (a configuração se torna um pouco mais complicada neste caso). Read the rest of this entry »

Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!