Douglas, estive pensando numa forma de usar suas classes para validar o cadastro de uma inscrição estadual e percebi que é interessante usar Chain of Responsability. Veja só:
[code]
String[] ufs = {“RS”, “SC”, “PR”, “SP”, “RJ”, “MG”, “ES”};
String ie = aJTextField.getText();
UF uf;
public boolean validateIE(String ie) {
for (int a = 0; a < ufs.length; a++) {
uf = UF.valueOf(ufs[a]);
if (uf.getInscricaoEstadual().setNumber(ie).isValid()) {
return true;
}
}
return false;
}[/code]
Acima temos a forma “tradicional”, mais procedural do que orientada o objetos. Usando Chain, fica só um pouco mais complexo, mas bem mais flexível, com as classes mais desacopladas, sabendo menos uma sobre as outras. Primeiro é preciso criar a interface:
public inteface chain {
public void addChain(Chain chain) ;
public void sendMessage(String inscricaoEstadual);
}
Daí, cada classe InscricaoEstadual implementa a interface Chain. Isso é bem simples. Cada InscricaoEstadual tem uma referência para a próxima classe da cadeia, estabelecida por addChain(). Se ela puder validar a inscrição estadual ela retorna true, senão encaminha para a próxima classe na cadeia através de sendMessage(), assim por diante até chegar na última. Se a última IncricaoEstadual não conseguir validar, ela finalmente retorna false.
O que acha?
Não vou dizer nada útil aqui… Era só pro número de mensagens não ser igual a 24! :lol:
Hehehe, essa foi boa…
Mas sobre a corrente ali, nunca tinha visto isso, achei interessante até! Só não sei se a complexidade que é introduzida aí compensa… se bem que não sei o quanto de complexidade seria colocada, já que lendo assim parece fácil de fazer até. Inclusive, todas as classes de validação podem usar esse mesmo esquema quando houver diferença pra cada UF como nesse exemplo.
Flw…
ps: ainda não comecei a ver as classes, estou um pouco enrolado com o serviço por aqui, mas se der um tempo eu dou um jeito aqui e faço uns testes beleza?
Chain é um dos padrões catalogados pela GoF.
Não é difícil implementar nese caso. O método addChain(Chain chain) só ajusta a propriedade nextChain, enquando o sendMessage(String inscricaoEstadual) encaminha a mensagem “valide essa inscrição estadual” para a a próxima classe da cadeia (nextChain) caso ela não tenha sucesso na validação. Assim por diante, até encontrar alguém que consiga validar ou até chegar no fim da cadeia.
Mais algumas vantagens para implementar as classes de validação usando Chain of Responsability, ao invés do modo “tradicional” que é mais procedural:
- O uso das classes não vai ficar mais difícil, e iniciantes em Java não terão problemas, já que a forma mais tradicional também é possível. Esse foi um questionamento que o Iron fez.
- Usuários avançados vão ter bastante flexibilidade no uso das validações, podendo adicionar e retirar classes de validação até em runtime, algo impossível usando loop ou if/else.
- O uso pode até ficar mas fácil para todos. É possível criar e instanciar uma classe de validação, através de um método factory getInstance(), com toda a cadeia já configurada, pronta para uso através de um método valideEssaIncrEstadual(String inscricaoEstadual)
//Instancia-se todas classes de validação de incrição estadual
InscricaoEstadualSP inscricaoEstadualSP = new InscricaoEstadualSP();
InscricaoEstadualRJ inscricaoEstadualRJ = new InscricaoEstadualRJ();
InscricaoEstadualAM inscricaoEstadualAM = new InscricaoEstadualAM();
InscricaoEstadualGO inscricaoEstadualGO = new InscricaoEstadualGO();
// ...
// Assim por diante
// Não liguem para o nome da classe tosco!
private ValidadorDeInscricaoEstadual () {
//Configura a cadeia, inclusive colocando os estados mais utilizados
// na frente para fim de otimização
inscricaoEstadualSP.nextChain(inscricaoEstadualRJ);
inscricaoEstadualRJ.nextChain(inscricaoEstadualAM);
inscricaoEstadualAM.nextChain(inscricaoEstadualGO);
}
// Factory
public static ValidadorDeInscricaoEstadual getInstance() {
return new ValidadorDeInscricaoEstadual;
}
public boolen valideEssaIncrEstadual(String iE) {
// Só encaminha a mensagem para o primeiro da cadeia e espera
// a resposta.
return inscricaoEstadualSP.sendMessage(iE);
}
Ou, ao invés de ter um factory para instanciar um objeto dessa classe para só então usar o método valideEssaIncrEstadual(String inscricaoEstadual), esse método poderia ser static.
Corrigindo a interface Chain:
public inteface chain {
public void addChain(Chain chain) ;
public boolean sendMessage(String inscricaoEstadual);
}
Douglas, você tinha pedido sugestões porque está para fazer mudanças nessas classes. Não tinha pensado em nada ainda. Já faz um tempinho que estava pensando numa ótima maneira de usar as classes de validação e acho que essa pode ser uma delas.
T+!
Dudaskank, quando vc “desafogar” o serviço me dá um toque por email que eu quero discutir um pouco o pack de métricas com você.
RafaelRio, vá pensando/reformulando o que vc tá fazendo, pois essa discussão com o Douglas vai ter que esperar.Ele está lá nas praias do Nordeste curtindo as férias até fins de outubro…
2 exemplos de implementação de chain:
-
o mecanismo de herança (procura por um método na classe mais abaixo na hierarquia, subindo até encontrá-lo, ou não);
-
e a implementação dos filters para servlets:
doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
RafaelRio, o douglas té lendo o tópico espero que ele responda suas dúvidas logo.
Thingol, gostaria que vc botasse aqui, os detalhes básicos sobre como implementar criptografia com Bouncy Castle.O Rafael vai estudar a viabilidade de fazer uma classe assim.Se vc tiver algo/idéia pronta pode postar também.
[b]Fernando Meyer/b até hoje vc não me deu por escrito como seria aquela sua idéia sobre classes de datas.Poste os detalhes aqui.
Vamos tentar dar um gás agora, e fazer um mini-release no próximo mês, já atrasamos demais, parece a linha 3 do metrô do rio! :lol:
Companheiros,
Pesquisei neste tópico se já havia post de código de formatação de CEP. Como não encontrei estou enviando. Espero ser útil.
Ah, ele vai junto de um teste de aceitação.
[code]package br.com.lello.test.vo;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
import junit.framework.TestCase;
public class TestFormatador extends TestCase {
public void testFormataCEP1() {
assertEquals(frmt("4304-10"), "04304-010");
assertEquals(frmt("04304-210"), "04304-210");
assertEquals(frmt("4-8"), "00004-008");
assertEquals(frmt("04304-010"), "04304-010");
assertEquals(frmt("504304-010"), "504304-010"); //invalido, mas passa
assertEquals(frmt("04304010"), "04304-010");
assertEquals(frmt("0430401"), "04304-001");
assertEquals(frmt("01"), "00001-000");
}
private String frmt(String s) {
String r;
Double c1, c2;
String [] splitted;
DecimalFormat df1 = new DecimalFormat("00000",
new DecimalFormatSymbols(new Locale("pt", "BR")));
DecimalFormat df2 = new DecimalFormat("000",
new DecimalFormatSymbols(new Locale("pt", "BR")));
if (s == null) {
return "";
}
if (s.indexOf('-') == -1) {
int tam = s.length();
int i1 = (tam > 5 ? 5 : tam);
int i2 = (tam > 8 ? 8 : tam);
c1 = Double.valueOf(s.substring(0, i1));
if (i2 > 5) {
c2 = Double.valueOf(s.substring(6, i2));
} else {
c2 = new Double(0);
}
} else {
splitted = s.split("-");
c1 = Double.valueOf(splitted[0]);
c2 = Double.valueOf(splitted[1]);
}
r = df1.format(c1);
r += "-";
r += df2.format(c2);
System.out.println(s + "\t -> " + r);
return r;
}
}[/code]
[quote=RafaelRio]Chain é um dos padrões catalogados pela GoF.
Douglas, você tinha pedido sugestões porque está para fazer mudanças nessas classes. Não tinha pensado em nada ainda. Já faz um tempinho que estava pensando numa ótima maneira de usar as classes de validação e acho que essa pode ser uma delas.
T+![/quote]
Pessoal, perdoe a minha ausência nesse período, já nem sei mais que dia da semana é pq estou trabalhando direto. Vou tentar dar uma atenção maior ao projeto.
Rafael,
Eu entendi o que é o padrão, mas acho que você poderia colocar um exemplo usando as próprias classes que estão no pacote de inscrição estadual. Acho que a utilização desse padrão não inviabiliza o que já está lá. Só tenho uma questão: como uma classe de IE vai saber que um número de IE é inválido por não se daquele estado ou porque é inválido mesmo? Se eu entendi bem, um número de IE só será considerado inválido após ser invalidado pelas 27 classes. Correto?
[quote=felipesp]Companheiros,
Pesquisei neste tópico se já havia post de código de formatação de CEP. Como não encontrei estou enviando. Espero ser útil.
[/quote]
Felipe,
Existe uma classe chamada Cep no pacote org.brazilutils.br.endereco.
Não entendi exatamente o que significa formatar 4-8 para 00004-008. Normalmente eu vejo muito em sistemas formatação de 5 para 8 caracteres, o que normalmente se faz adicionando três zeros ou consultando alguma base de dados.
Em que casos se usa essas formatações que você postou? Pode-se adaptar a calsse de Cep adicionando parte desse código que você fez.
Douglas, beleza? Quanto tempo!! Deu até saudades! :lol:
A idéia não é inviabilizar o que já está feito, de forma alguma. É acrescentar ao que você já fez. Não postei nenhum exemplo com base direta nas suas classes porque queria ouvir a sua opinião antes.
Tinha pedido pro Iron me adiantar alguma tarefa pro BrazilUtils a umas duas semanas atrás, já que estava meio parado (eu e o BU! hehe). Assim que tiver um tempinho de novo, posto aqui alguma coisa.
Não vai saber. A palavra chave desse padrão é delegação. Não cumpriu sua tarefa (nesse caso a validação) manda pro próximo da cadeia.
Depende. É por isso que existe o método addChain (vide exemplo acima). Se eu colocar apenas duas classes de validação na cadeia, se a IE for inválida para os dois estados representados pela classe, ela será invalidada após ser testada apenas pelas duas classes.
Se colocar seis classes (São Paulo, Rio, Paraná, Amazonas, Ceará, Mato Grosso), se a IE for inválida para todos os estados, retorna após a execução do teste pelas seis classes que estão na cadeia.
Ok ?
[quote=RafaelRio]
Depende. É por isso que existe o método addChain (vide exemplo acima). Se eu colocar apenas duas classes de validação na cadeia, se a IE for inválida para os dois estados representados pela classe, ela será invalidada após ser testada apenas pelas duas classes.
Se colocar seis classes (São Paulo, Rio, Paraná, Amazonas, Ceará, Mato Grosso), se a IE for inválida para todos os estados, retorna após a execução do teste pelas seis classes que estão na cadeia.
Ok ?[/quote]
Acho que compreendi como usar o padrão. A delegação fica a cargo do usuário da API não da própria API. Vc cria umas IEs e junta as que vc precisar. Passa um número pra primeira e as outras são acionadas em seguida. Mas a fila de IEs é definida pelo uauário através de addChain() ou coisa do tipo.
Exato.
Note que as classes de validação ainda poderão ser usadas sozinhas, sem fazer parte de uma corrente.
E deve ser tranqüilo implementar a Chain nesse caso. O mais difícil você já fez, que é a lógica de validação.
É só defenir e implementar a interface chain, e colocar uma condicional no método de validação da classe.
Conseguiu validar? Se sim, retorna ok. Se não conseguiu, verifica se tem alguém na corrente. Tem alguém na corrente? Delega então para essa classe. Caso contrário, retorna IE inválida.
A interface:
public inteface chain {
public void addChain(Chain chain) ;
public void sendMessage(String inscricaoEstadual);
}
O que acha?
Com polimorfismo isso fica fácil, fácil.
Por que não usar o commons-chains?
Porque, nesse caso, seria como querer matar uma mosca com um canhão. 
Não acho que o commons-chains seja tão grande ou complexo assim.
Pq seria um canhão?
Veja bem, eu não julguei o Commons-Chains.
Não vejo vantagem alguma em usá-lo nesse caso. E quanto mais simples a forma de se resolver um problema, melhor.
Mas, flaleite, se você estiver disposto a argumentar sobre as vantagens de se usar Commons-Chains nas classes de validação de IE e, se possível, ainda mostrar algum código de exemplo, por favor fique a vontade.
Isso só vai somar, seria muito bom!
flaleite,
o problema de começarmos a usar APIs anexas a nossa(criar dependências), é que isso pode virar uma bola de neve, e isso é um perigo numa API de validação como a nossa!
Até então, a única que eu tinha idéia de usar é a BouncyCastle, mas não estou seguro…
desculpe a pergunta, mas como faco pra chamar uma classe deste pacote pra validacao de cpf …
to usando o eclipse e ja dei um import externals jar no meu projeto e um import org.brazilutils.* no meu fonte …
tem que passar algum parametro ???
porque tenho o que o usuario digitou num jtextfield (no caso, o cpf) com a mascara numa string …