Pesquisar

sexta-feira, 30 de novembro de 2007

Fluent Interface ...

Primeiro a definição depois os exemplos.

*DSL ==> *é uma linguagem (mini liguagem) projetada para um tipo especifico de tarefa, isto é justamente o contrário de linguagens para proposito geral como Java, C ou C#.
*Fluent Interface (Interface Fluente)* ==> objeto que é capaz de deixar as suas responsabilidades mais expressivas a linguagem. (:S confuso, mas o exemplo ajudará)

Para se aprender algo nada melhor do que exemplos./ (aprender com exemplos não dá sono de acordo com Fowler, eu acho que ele está certo)/
Irei apresentar aqui dois exemplos: um simples e outro mais interessante.

*Exemplo Simples*

Supondo que tenho um objeto que representa o conceito Carro.

public class Carro{
private String nome;
private String marca;
private int portas;
public Carro(){
}
// métodos de acesso as propriedades encapsulados...
}

Quando fossemos "usar" esse objeto fariamos...

//***
Carro fusca = new Carro();
fusca.setNome("fusca");
fusca.setMarca("VW");
fusca.setPortas(2);
//***

Tentando aplicar o conceito de Interface Fluente, definiriamos uma Interface

public interface ICarro{
ICarro setNome(String nome);
ICarro setMarca(String nome);
ICarro setPortas(int nome);
}


//classe que implementa essa interface.
public class Carro implements /ICarro/{
private String nome;
private String marca;
private int portas;
public Carro(){
}

public ICarro setNome(String nome){
this.nome = nome;
return this;
}
public ICarro setMarca(String nome){
this.nome = nome;
return this;
}
public ICarro setPortas(int numero){
this.portas = numero;
return this;
}

}

*Agora nosso mesmo exemplo.( O simples ainda )*

//** ANTIGO
Carro fusca = new Carro();
fusca.setNome("fusca");
fusca.setMarca("VW");
fusca.setPortas(2);
//**

//** COM O CONCEITO DE INTERFACE FLUENTE
Carro fusca = new Carro();
fusca.setNome("fusca")
.setMarca("VW")
.setPortas(2);
//Note como cada método de set retorna o objeto aplicando outro método,
dando mais expressividade
//a linguagem.
//**

Isso parece meio bobo, mas para um *exemplo inicial* é até "bonzinho".


*Exemplo Interessante

*Outro possível exemplo, um criador de sql. Em tempos que o padrã JPA está se consolidando, se trata de exemplo não muito usual (sem bem que se pode usar-lo para criar as JPQL)... mas ao exemplo.
Se quiser "conversar" com o SGBD expresse em SQL. Uma consulta SQL é
similar ao exemplo abaixo:*

SELECT* campo1,campo2, campo4 (ou * para todos)
*FROM* tabela1
*[INNER | OUTER ...] JOIN* tabela2 *ON*
*WHERE* condicao1
*AND *condicao2
*OR* condicao2
*ORDER BY* campo1, campo2 ....

O exemplo acima não mostra todas as potencialidades da linguagem SQL mas serve para o propósito do exemplo.

1º A criação da Interface

public interface IConsultaSql{
IConsultaSql select(String campos);
IConsultaSql from(String tabela);
IConsultaSql innerJoin(String tablea);
IConsultaSql outterJoin(String tablea);
IConsultaSql on(String condicao);
IConsultaSql where(String condicao);
IConsultaSql and(String condicao);
IConsultaSql or(String condicao);
IConsultaSql orderBy(String campos);
}

Logo após a criação da classe que implementa a interface.

public class ConsultaSql implements /IConsultaSql/{
private StringBuilder construtor = new StringBuilder();
//note que o próprio StringBuilder aplica conceitos de interface fluente.
public ConsultaSql(){
}

public IConsultaSql select(String campos){
construtor.append("SELECT ")
.append(campos);
return this;
}

public IConsultaSql from(String tabela){
construtor.append(" FROM ")
.append(tabela);
return this;
}

public IConsultaSql innerJoin(String tabela){
construtor.append(" INNER JOIN ")
.append(tabela);
return this;
}
public IConsultaSql outterJoin(String tabela){
construtor.append(" OUTTER JOIN ")
.append(tabela);
return this;
}
public IConsultaSql on(String condicao){
construtor.append(" ON ")
.append(condicao);
return this;
}
public IConsultaSql where(String condicao){
construtor.append(" WHERE ")
.append(condicao);
return this;
}
public IConsultaSql and(String condicao){
construtor.append(" AND ")
.append(condicao);
return this;
}

public IConsultaSql or(String condicao){
construtor.append(" AND ")
.append(condicao);
return this;
}
public IConsultaSql orderBy(String campos){
construtor.append(" ORDER BY ")
.append(condicao);
return this;
}

public String getSql(){
String retorno = construtor.toString();
return retorno;
}
}

*Veja o uso.*

ConsultaSql con = new ConsultaSql();
con.select("nome,telefone")
.from("pessoa_fissica pf").innerJoin("contatos ct").on("pf.id=ct.pf_id")
.where("pf.nome like %?%")
.and("pf.idade>18").orderBy("nome,idade");

*Bem mais expressivo... mais flexível*

Senão engano o Hibernate está implementando [ou tem implementado] algo assim para criar os
objetos Criteria.

public String getSql() throws SqlIncorretoException{
String retorno = construtor.toString();
Sql.valida(retorno);
return retorno;
}


Uma nova característica do java 5, o varargs também pode ajudar a aplicar "esses novos conceitos" de interface fluente.

*TRADICIONALMENTE*
Produto bola;
Produto cafe;
Produto monitor;
Compra compra = new Compra(cliente);
compra.adicionarItem(bola);
compra.adicionarItem(cafe);
compra.adicionarItem(monitor);

*COM USO DE VARARGS
*
Produto bola;
Produto cafe;
Produto monitor;
Compra compra = new Compra(cliente);
compra.adicionarItem(bola,cafe,monitor);

Enfim são todos conceitos muito abstratos e ainda em discussão, logo "nada" é certo sobre esse tema. No mínimo o assunto é interessante e intrigante para os desenvolvedores e clientes (quem realmente interessa). Se acostume com esse novo paradigma /expressividade no desenvolvimento. (tudo mais perto da linguagem de
domínio do sistema)

/ps: perdoem os erros de português.
/Links interessantes sobre os assuntos/.

* _http://www.fragmental.tw_ (Blog sobre pesquisa em DSL)
* _http://martinfowler.com/bliki
/FluentInterface.html_ (Fowler
"ditando" sobre o que é uma Interface Fluente)
* _http://www.infoq.com/presentations/domain-specific-languages_
(Vídeo com uma introdução sobre DSL)

Da arte de integrar sistemas algo é certo... (um pouquinho de S.O.A.)

Integrar sistemas --> Pode ser entendido como a "arte" de interligar diversos sistemas que precisam de SERVIÇOS (não somente dados, além disso é necessário inteligência) dos demais. Essa interligação pode ser feita de diversas formas [implementadas] por exemplo:
Usando WebServices.
Usando RCP. (RMI, COM+ ...)
Usando Tabelas Corporativas.
Usando outros sistemas como "ponte". (sistemas para integração de aplicações)
...

Premissas
É dever do "artista" notar onde há (ou haverá) convergência ou necessidades dos vários sistemas se integrarem. Projetar aplicações já prevendo possíveis integrações é uma ótima e difícil tarefa.

Eis o problema.... (integração via Tabelas Corporativas)
Numa empresa Xyz (empresa de três letrinhas http://blog.fragmental.com.br/2007/06/07/3-letrinhas/) o parque de sistemas conta com aproximadamente 8 grandes sistemas.

Sistema 1 - Recursos Humanos (S1)
Sistema 2 - Capacitação dos Recursos Humanos (S2)
...

O S1 trata do domínio de recursos humanos da empresa, nele há uma tabela corporativa denominada rh_pf para manter informações das várias pessoas fisícas. O S2 no momento de analise percebeu que existiria um conceito de aluno que necessitaria de uma validação (+ que isso um pouco de inteligência) de dados contidos no S1, logo prevendo uma integração futura às aplicações os projetistas tiveram a idéia de usar a mesma tabela [rh_pf] para se resolver este "pequeno problema". (1º tiveram que entender o esquema rh_pf)
Com essa solução houveram outros problemas, quando alguém fosse gerenciar os alunos existentes teria que realizar uma consulta a rh_pf... e agora? voltam todos os registros? {informações sigilosas não podem ser mostradas} E quando fosse alterar, outro sistema iria ter o direito de alterar dados que não pertencem ao contexto do mesmo?!
E as "ligações obrigatórias" {leia-se constraints} contidas em rh_pf como ficariam?

E os projetistas...
Sugeriram outra solução, criar uma coluna na tabela rh_pf chamada sistema, onde poderia se "controlar" quem é dono desses dados, e para as "ligações obrigatórias" resolveram tirar tal integridade (nesse momento o S1 - RH é informado que deverá realizar a verificação da integridade na própria aplicação... mais mudanças...).

Conseqüências...
Dor de cabeça, tempo gasto com outros projetos....
Um ano se passa e outro sistema S3 é obrigado a integrar-se {suas regras de negócio possivelmente necessitam de serviços de outros sistemas}... E a bola de neve cresce...
A computação neste local começou a se tornar centralizada. Se houver um desejo de mudança da tabela rh_pf com certeza vários sistemas irão ter que ser modificados. {Acoplação Extrema entre Sistemas}

Um possível solução
Uma solução seria cada um [dos sistemas] disponibilizar seus serviços... e os demais sistemas aproveitarem esses serviços. Novos sistemas poderiam utilizar os serviços já existentes para desenvolvimento dos mesmos. {conceito próximo a arquitetura S.O.A.}

Conclusão
Algo que eu, particularmente, percebo e que integrar sistemas "via tabelas corporativas" não parece uma boa solução pois os diversos sistemas se tornam muito dependentes uns dos outros, se grandes sistemas [como o dos correios] em uso já descobriram que centralizar não é um bom negócio e que distribuir tem mostrado melhores resultados, pra que centralizar?. [Alias essa é a afirmação da qual deu o título ao post]

sexta-feira, 22 de junho de 2007

Abstrair é preciso

Para que haja o entendimento global de um problema, devemos esquecer as especificidades. Ter uma visão macro é essêncial para um bom projeto. Logicamente o detalhamento também é importante, porém no momento certo senão pode atrapalhar o andamento.

Um problema clássico e do "analista-desenvolvedor", ele faz a analíse já pensando na linguagem, o que ocorre como o processo? Simplesmente trava.

Resolver grandes problemas requer todos os minímos detalhes, todavia para um inicio de solução é necessário ver bruscamente "como se estivesse num avião".

Imagine um programador solitário e um analista querendo entender, na sua totalidade, um S.O., como por exemplo um GNU/Linux. Com certeza iriam passar anos e mais anos e nada aconteceria.

terça-feira, 19 de junho de 2007

De quem é este método?




Um amigo lendo a apostila de Java e Orientação a Objetos da Caelum(r) - por sinal ótima apostila -, me questionou sobre como saber de quem é a responsabilidade de um método. (como atribuir e distribuir as responsabilidades entre as classes)

Mais especificamente, tem-se dois objetos Conta e Pessoa. Ele me disse:
- Mas quem saca dinheiro não é a pessoa?
- Porque que conta é que está com esse método?
- Não temos que "imitar" o mundo real?

Tentei explicar para que devemos chegar o mais perto do mundo real, não completamente igual ao mundo real. Sobre atribuir responsabilidades existem padrões (ou regras) e também vale o bom senso, existem padrões como o GRASP - Expert.

Padrão Expert
"Atribuir uma responsabilidade ao expert de informação - a classe que possui a informação necessária para preencher a responsabilidade"



Conta ou Pessoa preenchem a necessidade de sacar o dinheiro?
Quem é o expert da informação envolvida na responsabilidade, Conta ou Pessoa? (saldo,limite...)
Eu acredito que seja a Conta. O objeto Conta que conhece qual o limite, para não ultrapassar, e autualiza o saldo. Ou seja, a Conta é o Expert.

sexta-feira, 15 de junho de 2007

Relacionamentos em Diagramas de classes UML

Um relacionamento em UML nada mais é do que uma forma de expressar como um objeto poderá referenciar o outro.
Abaixo seguem dois diagramas de classes equivalentes.

A figura 1 e a 2 modelam o mesmo conceito uma Pessoa, porém a figura 1 é bem mais complexa de se entender do que a figura 2.
Note que cada relacionamento (agregação, composição...) pode ser criado com o uso de uma varivel de classe.

Porém quando se tem um problema um pouco mais complexo do que modelar um simples conceito como uma pessoa ai se tornar melhor o uso do estilo da primeira figura melhor.

Um modelo deve ser encarrado como algo que deve facilitar o entendimento, independe do diagrama, a figura deve ser clara para o entendimento do que se queria expressar.
Então quando for criar modelos não pense em apenas uma documentação mas sim um facilitador de problemas.

Favor não considerar essa modelagem como uma modelagem exemplo a ser comprida, tente entender apenas o conceito relacionamento entre classes.

Dicionário de sinônimos, siglas & afins

A área de TI troca constantemente o jeito de se expressar e "inventa" novas siglas a cada mês, o pior é que muitas dessas siglas já tem três, quatro ou mais sinônimos.
...
TDD= Desenvolvimento Guiado por Testes
DDD= Desenvolviemnto Guiado pelo Dominio
MDA = Arquitetura Guiado pelo Modelo
SOA=Arquitetura Orientada a Serviços
IoC==AOP==Injeção de Dependências é apenas uma forma de IoC, não são sinônimos
MVC=Model Vision Controller=Modelo Visão Controle
XP=eXtreme Programming=Uma metodologia ágil
DESIGN PATTERNS=Padrões de projeto
....

Isso sem descer para uma área especifíca como a plataforma Java, ai vem mais uma enxurrada: JCP, JSF, JDBC, JSP, JSR, EJB...

Devemos tomar cuidado para não cair no "geralzão" e perceber quando pessoas que dizem siglas ou palavras sem ao menos entenderem qual o significado.

Uma das palavras que acho mais interessante no mundo dos sistemas é componente,,, a definição de componente é ampla para entender que até mesmo um formulário pode ser um componente, e ao mesmo tempo tão restrita que é fica difícil entender o que é e o que não é um componente.

"Componente um agregado de software projetado para ser usado, sem modificação, por uma aplicação que está fora do controle dos criadores do componente. Por ' sem modificação ', eu quero dizer que a aplicação não altera o código-fonte dos componentes, apesar dela poder alterar o comportamento do componente extendendo-o de alguma maneira permitida pelos criadores do componentes." [Martin Fowler]

Com a ajuda de Philip Shoes, houve alguns ajustes.

quinta-feira, 14 de junho de 2007

Definir responsabilidades em orientação a objetos é tão importante quanto os relacionamentos.

Hoje , a pedido de um amigo, fui revisar (refatorar, manter,revisar...) códigos de uma "pequena parte" de um sistema de RH - bem básico feito dentro da própria empresa. Chegando lá fui informado que eu deveria olhar somente a "classe" chamada PessoaFisica.java, e que ele nela e somente nela que o problema estava. Me tranquilizaram, disseram que era para eu ficar calmo porque o sistema havia sido construído sobre OO e que tinha toda a "documentação".

Quando abri esta classe no Eclipse, tive uma tremenda surpressa, a classe tinha 6415 linhas de códigos. Assustado perguntei posso ver o "erro" acontecendo, bem descobri como consertar tal erro, porém aquela minha manutenção corretiva deveria ser feita em todas as partes da classe que tivessem um comportamente parecido, quer dizer consertei um problema e arrumei uns novos problemas.

Posso estar errado mas não tenho coragem de chamar aquilo de classe no máximo de um grande modulo de software, e nem aceitar tanta responsabilidade (mesmo que baseado somente no número de linhas de código) numa única classe. Aquele é um dos casos em que a Refatoração é mais (ou talvez) complicada do que um construção de uma classe nova.

sexta-feira, 1 de junho de 2007

Tudo bem, vou começar um projeto de software orientado a objetos

Pense no projeto em andamento, 'pule' a analise vá direto para a 'fase' de projeto.
Se está com dúvida sobre qual seria a modelagem melhor (ou mais correta) a ser feita em primeiro lugar...
Então, faça primeiro a modelagem das classes depois faça a modelagem de dados.
Outro tópico que pode ser interessante é o mapeamento entre o objeto e a tabela, relação que hoje está 'facilmente' resolvido com esses vários frameworks para mapeamento, jpa, NHibernate... mas isso é assunto para outro tópico.
Experimente isso - se nunca assim fez - !

quinta-feira, 31 de maio de 2007

Inicio do aprendizado

Espero com este blog, aprender muito e tentar passar o que aprendi e estou aprendendo no mundo da criação de software.
Com certeza terá alguns posts diferentes do assunto central.
Tentarei escrever e atualizar o blog em pequenos espaços de tempos.