Discutiremos aqui os próximos passos a serem dados, como a normalização de endereços, aumento(substancial) do pack de métricas e a inclusão de novas features a serem propostas(e discutidas) nesse tópico.
Lembrando que todas as features/sugestões que forem enviadas DEVEM vir acompanhadas de um testcase(JUnit) e comentadas com as explicações necessárias.
bom, então vamos lá …
Eu acessei o codigo da api e tenho algumas duvidas/perguntas/sugestões.
Primeiro que tudo a padronização de nomes. O ideal é programar usando inglês porque facilita a criação de nomes compostos , mas por outro lado existem coisas muito especificas para as quais não existe uma tradução direta. Eu gostava de saber qual é a directriz: se se deve preferir o ingles ou não. Em qualquer dos casos a API pecisa de uma refactoração geral relativamente a isso. sugiro que se use Ingles e que se traduzm ou abreviem os nomes especificos. Exemplo Inscrição Estadual = IE
Mas o javadoc acho que deveria ser primeiramente em portugues uma vez que o publico alvo é o brasileiro e todos sabemos como nem todos os programadores dominam o ingles.
Depois existe a falta de aplicação de design patterns e os aplicados nem sempre estão bem aplicados. Por exemplo , o chain of responsability não se aplica da forma que está sendo aplicada à logica de validação. O padrão que se deveria aplicar era Composite. Depois ha uma violação grave de separação de responsabilidade. Objectos como cnjp não se devem validar a si mesmos. Eles deveriam atuar como VO e ter objectos especiais para a validação. A minha proposta é que se implemente a seguinte estrutura
interface Validator
public boolean isValid(Object obj) throws ClassCastException
Este objeto faz validações. Se o objecto passado não puder ser validado por ete validador uma ClassCastException acontece. (por exemplo, tentar validar CEP com o validador de CPF )
Com isto é simples criar um
class CompositeValidator implements Validator
addValidator(Validator v)
Este objecto permite adicionar vários validadores que se encadeiam na validação do mesmo objeto.
Isto permite também que sejam criados validadores de negocio e acidionados à regra. Por exemplo, o Endereço tem que ser válido E ser de São Paulo
A interface AutoValidatable com o unico método isValid() marca objetos que se podem auto validar. Mas na reaidade o que eles farão é invocar o validadadro certo.
Outra coisa são os numeros de identificação como CNPJ, CEP , etc…
Eles representam códigos alfanumericos, normalmente apenas numericos.
Eles não representam as entidades Cadastro Nacional de Pessoa Juridica, e apenas o numero do cadastro. então sugiro que os nomes sejam alterados para CNPJNumber , CPFNumber e assim por diante. A exceção é o CEP porque ele representa reamente um codigo (Codigo de Endereçamento Postal).
Em relaçao a isto tenho outro ideia. Definir uma interface marcadora chamada CodeNumber que implementa CharSequence e representa codigos alfanumericos com métodos utilitários como asDigits() que retorna um int[] com os digitos nos lugares certos e digitAt(index)
Isto facilita imenso na hora da validação pq a transformação para int é muito usada. CharSequence tem o método length tb muito util na hora de fazer validações. Todos este codenumber são imutáveis e aceita uma string no cosntrutor. Esta strng sempre será desformatada e guardada internamente desse jeito.
Depois , a classe Brazil . esta classe tem metodos estáticos utilitários para as operações mais comuns como por exemplo Brasil.cnpj(“0099843747”).isValid()
isto poupa o utilizador de ter que criar um monte de objeto vara fazer algo simples. Mas, pode se quiser, criá-los. Isto é apenas para ajudar.
Existe a classe UF com várias instancias estáticas.
Esta classe tem dois problemas: 1) cada UF contem uma inscriçãoEstadual.
Isto não é necessário e obriga a construção de objectos que podem não vir a ser usados. A UF deveria ter apenas o nome e sigla. Esta sigla é na realidade um codigo curto para o estado o codigo mesmo é “BR-SP” como definido pela ISO . Acho que isso deveria ser tomado em conta colocando os métdos getCode() e getShortCode().
A lista de estados é obtida com o metodos estático values() ,mas internamente ele cria um colection. Isto poderia ser feito via reflection e usar um cache. O retorno deveria ser um array para evitar alterações ou um unmodifiableCollection.
Esse objects Inscriçãoestadual são na realidade validadores misturados com VO. como sugeri , o ideial é separar isso. Um objeto IENumber heradsndo Codenumber para colocar os numeros e Objectos validator para o validar. Os validadores obdecem a uma naumenclarura exemplo IEValidatorForSP com o UF no fim. Desta forma é possivel obter os validadores por reflection e ter o metodo estático IEValidator.getInstance(UF) que obtem o validador correcto para a UF. Dessa forma é simples criar o método Brazil.ie(“numero”).isValidFor(UF)
Isto, junto com o CompositeValidator permite fazer validações em cadeia de forma simples e permite o codigo dos validadores e dos codenumber ser muito simples. ao contrário do que é agora com métodos estanhos que dizem servir para encadear as validações (?!)…
Eu criei este códigos mas estão noutra máquina, eu deixarei eles aqui assim que possivel. Mas enquanto isso aqui ficam as sugestões para discussão. (tenho mais sugestões, mas fica para depois)
Na minha opinião a padronização e aplicação dos desing paterns só ajuda o desenvolvimento e o uso da API. E ainda estamos a tempo de marcar deprecated ou até mesmo remover métodos e objectos que não cumpra seu papel
outro assunto é relatiamente a casos de uso. Em que cenário, por exemplo, eu iria querer validar uma Inscrição Estadual em vários Estados?
Uma lista deste casos, traduzida numa unidade de teste seria tb util.
Boa pergunta. Vai saber… Mas se quisesse, poderia validar uma incrição estadual para um ou n estados, de forma orientada a objetos.
Dificilmente um sistema lida com IE de apenas um estado. Quando tiver que lidar com n estados, isso já estará pronto. É só pegar e usar, e vai evitar que muita gente use laços for para validar uma IE.
[quote=sergiotaborda]
o chain of responsability não se aplica da forma que está sendo aplicada à logica de validação. O padrão que se deveria aplicar era Composite[/quote]
Sério? Como assim não se aplica? O que se quer é que cada objeto cuite de sua própria responsabilidade (validar a IE para um estado) e, caso não consiga, delegue a tentativa para o próximo.
Por que deveria usar Composite? Não entendi sua preferência. Os dois padrões têm suas semelhanças. Entre as diferenças fundamentais, Composite é padrão estrutural, tem o foco em processar coleções de objetos primitivos ou compostos. Veja aqui.
Eu usaria Composite, por exemplo, se precisasse calcular o valor do salário de todos os empregados de uma empresa. Chain é muito melhor para delegar responsabilidades, permitindo que cada objeto faça apenas o que foi desenvolvido para fazer.
Deve-se preferir o inglês.Talvez a dica de abreviação de IE e outras seja válida.Mas cuidado para não termos um JanuaryRiver ou coisas do gênero! :shock:
Eu já falei para o Rafael, e vou falar para você(Sérgio):Cuidado ao usar patterns numa API de validação.Ainda mais usando java 1.4.A BU, é um “cinto de utilidades” do programador.NÂO devemos abrir mão do desempenho para programar de forma mais elegante.Por enquanto isso não ocorre, mas depois que ela estiver inchada, poderá ser difícil o refactoring.
Chain of Responsabiliy = Cadeia de Responsabilidade , como foi dito quando um objecto não sabe/pode/quer fazer o que tem a fazer ele delega ao próximo. Próximo é um conceito relativo, não significa que ha uma arvore, nem que o proximo existe.
Exemplo do padrão CoR são os Filter da tecnologia de servelt e os proprios servelet em si. Filter é mais obvio pq vc pode encadear os filtros quando o request vai para o servelet e na volta
Isto é CoR.
Os servelet usam o mesmo pattern através de RequestDispatcher. Aqui a delegação é explicita, o servelet escolhe outro servlet para delegar o trabalho. Nos filtros ela é implicita, fica denifia no web.xml.
Pq este padrão é ruim ? Ele não é ruim. ele é otimo, mas para aquilo que se pretende. Existe uma diferença fundamental entre um objecto Request/Response e um objecto como CNPJ. A diferença é que a cada passo cada membro é livre de ler e escrever no objecto que lhe foi passado. É como aquelas brincadeiras que uma pessoa fala algo no ouvido da outra e assim por diante e no fim o que a ultima pessa fala é diferente do que a primeira disso. Isso se deve a que os membros da cadeia mudaram (ou não) a mensagem. É um padrão para processamento de mensagens. Ora, CNPJ não é uma mensagem, ele não pode ser manipulado.
Composite é muito simples de implementar e usar. Um Validador que é composto de outros validadores. A ordem não é pre-estabelecida e com uma interface como validator é muito simples o usuário criar outros validadores para coisa mais especificas ou de negocio.
Exemplo: a API aceita 00000000 como um cpf válido. possivelmente o programador que a usar não vai querer isso. Ele pode introduzir um validador na cadeia para não permitir isso, mas é opcional. claro que a API irá prover um validador mais restrictivo (espero que vá) ,mas o seu uso é opcional.
Poderia ser criado tb um validador complementar ou seja, ele aceita o valor se algum dos seus validadores o aceita (OR). Este conceito é diferente do outro que só aceita se todos aceitam(AND). Desta forma
por exmeplo uma string poderia ser aceite como CNPJ ou CPF desde que fosse válido para um dos dois.
embora as classes de validação sejam para simplificar as classes e os mecanismos ela servem para uso da API, o usuáro não é obridado a usá-las. Como eu falei antes ele irá usar Brasil.ie(“83857475”).isValidFor(UF).
MAS uma API é melhor quando dá mais liberdade ao usuário.
Vejam a diferença
Agora:
InscricaoEstatual rj = new InscricaoEstadualRJ();
InscricaoEstatual rs = new InscricaoEstadualRS();
InscricaoEstatual sp = new InscricaoEstadualSP();
rs.set("12345678998");
rs.addValidador(rs)
rs.addValidador(sp)
rs.isValid();
O que eu estou fazendo no primeiro codigo ? Estou adicionando inscrções estatuais umas às outras ?! e pq coloco o numero em rs ? poderia ser rj ?
Fora isso , o codigo tem comentários assim “isto é necessário para a validação em cadeia funcionar” … meio estranho , não é ?
E na segunda forma ? Estou criando um validador, composto de vários validadores e pedindo que seja validado uma inscrição estadual que não sei a que estado pertence.
Vcs que digam qual acham mais simples.
Por que deveria usar Composite? Mas hei, nada disto impde que exista um IENumber.isValidFor(UF uf). so que ele irá usar o validador internamente e não ele mesmo processar a validação.
Sim, mas qual objecto ? Um objecto InscriçãoEstatual pode validar-se a si mesma ? Isso é como eu dizer que sou otimo jogador de futebol. Eu, sobre mim, digo o que quiser. A responsabilidade tem que ser de um validador, certo ? (é o treinador/olheiro que avaliaria se sou bom ou não, não eu mesmo). Até porque existe uma razão muito simples para que o objecto não se possa validar: validação pode ter muitas regras , nem todas préviamente conhecidas pela API. Imagina um email Ele pode ser validado com base na mascara, mas tb com base no dns do servidor e até mesmo enviando um email para o endereço, e ainda fazendo todas ao mesmo tempo. O ponto é que a validação que a API se propoe é apenas uma das muitas possiveis.É a validação padrão.
Não segundo a diretiva chamada de Separação de Responsabilidade (Separation of Concerns , cuja tradução literal é Separação de Preocupações). O objecto CodeNumber deve preocupar-se em tranportar os dados e fornecer operações simples com eles, como asDigits() , o validador preocupa-se em validar o CodeNumber e o formatador em formatar e desformatar o Codenumber de uma string. Compara isso com
Number e NumberFormat , Date e DateFormat. E para validação veja a API de validação usada no JGoodies.
Porque é mais simples de entender , usar e implementar. Reduz código nos objectos de numeros , centraliza a validação e sua regras e é mais flexivel para futuras alterações/extenções. Facilita tb o teste de uniddae pq se limita o dominio de objetos a testar por vez
quanto ao desempenho… as implementações que eu vi não sao failfast. Por exemplo a de CNPJ calcula os dois digitos verificadores e depois testa os dois. Ela tem que testar o primeiro, se der errado já retorna false e pronto. Isso é Failfast e é mais rápido. imagine validar 1000 CNPJ tendo que calcular sempre os dois digitos verificadores… Outras coisas o uso de coleções em vez de arrays e coisas assim , menos preocupantes… mas que limitam o desempenho da mesma forma.
Programar de forma elegante é importante, sobretudo num projeto opensource porque:
simplifica o codigo quase sempre caido no paradoxo do inventor (quando vc tenta fazer mais generico vc resolve mais problemas de formas mais simples)
É mais facil as outros programadores entender sem ter que ler comentários e ao usuario final de usar.
É normalmente mais eficiente e extensivel.
Evita refactoring constante e quando necessário ele é minimizado.
Os programadores aprender mais sobre design e patterns.
Mas eu sugiro que você estude um pouco mais a API da BrazilUtils, e depois estude como funciona a implementação. Ninguém utilizou Chain para validar CNPJ ou CPF. Você confundiu tudo. Depois, veja como funcionam as classes de validação de Inscrição Estadual.
Não, não está! Como eu disse, estude um pouco mais a biblioteca e suas classes.
Composite seria útil se eu tivesse uma série de objetos Inscrição Estadual e tivesse que realizar processamento em cima de todos eles. Não é isso o que acontece. O que temos é uma Incrição Estadual e várias classes esperando pela chance de lidar (validar) com essa Inscrição Estadual.
A validação para CPF e CNPJ ainda não está pronta. É a única API lançada na versão 0.1 que talvez sofra alteração. Certamente levaremos suas idéias em consideração.
Eu entendi o seu ponto.E é por isso que o Rafael disse que essa parte ainda não está pronta.Não sei se vc sabe, mas o Douglas(outro Owner) trabalha no Serpro, e parece que está perigando mudar a forma de cálculo/ou ter mais números CPF/CNPJ, por isso ainda teremos que ver o que faremos sobre isso.
[quote]Programar de forma elegante é importante, sobretudo num projeto opensource porque:
simplifica o codigo quase sempre caido no paradoxo do inventor (quando vc tenta fazer mais generico vc resolve mais problemas de formas mais simples)
É mais facil as outros programadores entender sem ter que ler comentários e ao usuario final de usar.
É normalmente mais eficiente e extensivel.
Evita refactoring constante e quando necessário ele é minimizado.
Os programadores aprender mais sobre design e patterns.[/quote]
Vc tocou num ponto chave aqui.Programar de forma elegante não implica em necessariamente usar DP para tudo. Implica em aplicar corretamente os conceitos OO, usar Herança com cuidado, programar por interfaces…
O problema que eu vejo as vezes com tanto DP,é IMHO, que eles muitas vezes atendem corretamente a UMA solução de programação, e são aplicados a finalidades distintas aos quais foram projetados. Singleton que o diga…
Mas e sugestões de features, tem alguma(s) em mente?Tempos atrás, o Meyer ficou de me enviar uns detalhes de um pack de Datas, algo que é deficiente pacas na API da JDK.
É bom iniciar um novo tópico pra tocar o projeto. Vamos aproveitar este tópico do BrazilUtils e otimizar as discussões sobre a API. Devo lembrar a todos que o objetivo desse tópico é fazer o código, bem como o trabalho da API como um todo, evoluir. Sempre vamos encontrar críticas e isso é normal. O código sempre poderá melhorar e isso também é normal.
Várias vezes no outro tópico algum membro do fórum postava várias boas idéias apontando vários erros/equivocos no código proposto. Muitas vezes eu já tinha visto esses erros e na maioria delas eu até concordava com a crítica. Não corrigir ou não ter feito da melhor forma da primeira vez pode simplesmente ser falta de tempo e/ou disponibilidade pra se dedicar ao código.
Se vocês procurarem no outro tópico vão ver que eu mesmo critiquei a forma como está a parte de Cpf/Cnpj, mas esta é a forma como já está lá e funcionando. Espero melhorar e fazer o melhor possível. Sempre procuro trabalhar assim, mas vamos ter em mente que este é um projeto open source. Nos últimos meses tenho tido quase nenhum tempo e não pude fazer nem um décimo das alterações que eu gostaria de ter feito antes de soltar a primeira versão. Na verdade, só deu pra passar o código pra 1.4 e olhe lá. O pacote de endereço nem saiu.
Uma das funções de um projeto como este é que quem participa aprende. E aprender errando faz parte do aprendizado. No outro tópico tá cheio de exemplos onde a API foi pra berlinda (pra usar um termo leve) e eu e Ironlyx nunca deixamos isso nos afetar. Quando pudemos fizemos o que pudemos.
Há alguns meses eu assumi a liderança de um projeto enorme e prá lá de complicado pela natureza política. Hoje eu tenho clareza que o BrazilUtils precisou de mais planejamento. Os objetivos não foram bem traçados e a coisa foi andando sempre meio sozinha e com esforços heróicos (louváveis). Eu e Ironlynx sempre dissemos que precisávamos de um gerente pois nenhum de nós tinha experiência nisso. Precisamos dividir algumas tarefas básicas como, por exemplo, alguém pra gerar as distribuiçoes. Fizemos de uma forma a aprendemos com ela o que funciona e o que não funciona.
Ao pessoal que está chegando ou simplesmente fazendo uma crítica eu peço um pouco de paciência e compreenção sobre como funciona esse tipo de trabalho. Muitas vezes vocês vão estar fazendo uma crítica à alguém mais experiente e com mais conhecimento mas que, por algum motivo, não fez o melhor código. Muitas vezes será o inverso, alguém com pouca experiência mas que precisa de incentivo pra melhorar.
Ao pessoal que está fazendo código e participanto eu peço que se preocupem mais com o conteúdo técnico das críticas que com a forma como ela foi feita. Isso é uma coisa produtiva pra vocês mesmos. Eu recomendo que vocês leiam o tópico antigo e vejam como foram feitas as críticas sobre Regex que não estávamos usando onde poderíamos (eu nem sabia o que era). Não foram nada simpáticas. Hoje em dia, aqui no projeto (trabalho), sempre sou eu que faço códigos com Regex e muitas vezes um código horroroso é trocado por uma Regex que simplifica bastante. Isso porque, ná época, eu me preocupei com o conteúdo técnico das críticas feitas, por mais sarcásticas e até pessoais que tenham sido. Comprei um livrinho de Regex e todo mundo saiu ganhando.
Bom trabalho a todos. As críticas são sempre bem vindas.
Como havia dito deixo aqui o codigo que baixei do CVS junto com o que adicionei. Eu tentei adicionar tudo em pacotes separados para vcs verem a diferença. Existem alteraçoes que eu ainda nao comentei.
Fora a inclusao de uma sub’API especifica para validaçao e a inclusao de interfaces e classes abstractas para facilitar o trabalho de validacao , existe um outro ponto mais …
Procurem em http://en.wikipedia.org/wiki/ISO_3166-1 procurem pelo brasil e cliquem em SO 3166-2:BR. Aqui sao apresentados os codigo completos dos estados e DF. Isso é um padrão internacional e não apenas do brasil.
A duvida é a seguite : não sei até que ponto a API deve ficar amarrada a consideracoes apenas brasileiras. Parece-me que sendo uma API de localização de aplicações ela tem que ser especifica, mas isso não significa que não se possam deixar ganchos para facilitar o trabalho de extençao e mesmo a compreencao da API. Com vista isto introduzi dois conceitos o t
de Unidade Territorial (TU) e o pais (Country)
TU tem dois atributos : codigo do pais e codigo de TU que seria o codigo da ISO 3166-2 , que no caso do brasil são as siglas dos estados.
FIz a UF herdar de TU por uma questão para que de certa forma se possa ser compativel com a ISO e ao mesmo tempo poder diferenciar explicitamente as UF . A UF tem um nome em protugues que a TU não tem ( e não teria como ter) . A classe Brazil que falei antes é um Country. e as UF são TU. à primeira vista isto é inutil ,mas serve para deixar claro o que Brazil e UF são , assim como compatabilizar isso com a ISO e possivelmente depois com as API de Locale e TimeZone (trabalho futuro)
Isso me leva a outro ponto: parece que estão querendo incluir uma sub-API para tratamento de datas. Isso é muito complicado e parecer ser a reinvenção da rda, já que a PI joda Time está ai … mas eu não li nada sobre quais as intenções de ter mais uma API para isso… Contudo, mesmo que fossemos fazer essa sub API sugiro que seja apenas uma fachada para a api JODA -TIme, que no futuro possamos substiturir pela Date and Time API que será o padrão logo, logo.
Em relação ao que vc escerveram:
Com o modelo de CodeNumber e VAlidator a transição para um outro modelo de numeros e valdiaçoes é simples. Podemos ter o validador CPFValidator e CPFValidator2007 (supondo que o novo padrão entre em 2007) e com compositeValidator poderemos validar os dois simultanemante. Acho que isso não será um problema se usarmos esta estruttura.
Defacto eu não tivemuito tempo para estudar a API, isso devendo-se principalmente ao fato de que ela é dificil de ler e ao facto de que não domino algumas partes, como a barcode API. O meu aport neste momento
vai mais na organização e estrutura do codigo, por isso realmente não me prendi com a implmentação (aliás, pq estou propondo outra) Mas tentei implementar o algoritmo de validação de CNPJ e IE de são paulo para demonstrar as vantagem do novo modelo que proponho. Deem uma olhada por favor. A minha procupação com a API é que ela parte de conceitos muito simples que são tratados -não se ofendam - de forma simplista, mas que não são tão simples assim porque envolvem internacionalização. (como telefone, por exemplo, mas falarei disso outra hora). VC poderão argumentar que o objectivo não é fazer uma API válida para outros paizes que não o brazil, mas ai eu teria de invocar o paradoxo do inventor e o facto de que se api é compativel com outros paizes poderiamos ver, no futuro, algum grupo extendê-la para o seu ppr pais sendo uma mao na roda para quem trabalho com expostações/importações.
Quanto ao texto extenso, vcs vao desculpar mas eu não tenho muito tempo e tenho que deixar bem claro o que proponho para minimiar duvidas e portanto futura escrita. Nas próximas semanas não vou poder usar o meu computador de desenvolvimento por isso apenas estarei conversando com vcs sobre a API, mas assim que me for possivel estou disponivel para codificar mais coisas.
P.S: Deem uma olhada no pacote adress onde tem um esboço do uma api para endereços Uma outra coisa que parece simples, mas não é.
Para os próximos lançamentos, temos que deixar mais claro o que exatamente foi lançado, o que está por vir, qual o estado das coisas no repositório no Java.net. Enfim, todas aquelas decisões que fazemos via Skype ou e-mail.
Isso vai ajudar quem quiser colaborar e nos ajudar também. Por exemplo, não adiata criticarem código para normalização de endereços ou telefone, simplesmente porque vamos mudar tudo aquilo que está lá. Tanto que essas features não saíram na versão 0.1.
Agora, como é que as pessoas vão saber disso se nós não publicamos nada a respeito? :roll:
Aliás, Douglas, Ironlynx, aproveitem e deixem claro quais as principais atividades de vocês na BrazilUtils no momento, quais as features esperadas para a versão 0.2, onde precisam de ajuda, pedidos de sugestões, etc.
Eu começo!
[color=darkblue] [/color]
Os meus maiores esforços vão para a normalização de endereços, que segundo o Douglas, será refeita totalmente.
Além disso, terminar o tutorial sobre as features da BrazilUtils 0.1 - faltam CPF/CNPJ e código de barra - e deixar o código do que já lançamos mais “parrudo”, com ajuda de ferramentas.
Bom, quanto as features, eu vou prosseguir com o pack de métricas(já tem umas centenas para entrar), e eu estava esperando idéias do pessoal principalmente na parte de Datas(que muitos reclamam, reclamam, mas não dizem direito o que querem) e talvez, Criptografia(ago + ou - básico).
Vou deixar aqui um aviso(já mandei por email):
Todos os usuários NÂO ativos com roles diferentes de Observer serão devidamente “EXONERADOS”, por isso quem quiser participar, que entre selecionando a role Observer.Há mais de uma centena de Developers/ContentDeveloper que nunca disseram nem um oi.Isso dá uma falsa grandeza ao projeto que não temos.
Isso de datas vai mesmo entrar ? Qual seria a vantagem/diferença para as outras API de data ?
A meu ver a vantagem seria se focasse o calendário usado aqui , possivelmente com hipotese de consultar feriados e funcionalidade de dias úteis/ de trabalho
Algumas ideias seria:
o)Uma classe genérica chamada Interval para trabalhar com intervalos de qualquer classe que seja comparable ou tenha um comparator. Esta seria util em geral tb para a parte de moeda e de quantidades/métricas
Interval
start():Object
end():Object
construtor Interval(Object a, Object b , Comparator)
construtor Interval(Comparable a, Comparable b)
contains(object)
isEmpty();
intersect(Interval) Interval
union(Interval) Interval
o) Um TimeInterval que herde de Interval para intervalos de tempo em especifico. TimePoint para pontos no tempo que seria as estremidades do intervalo.
o)Depois classe para data sem hora, hora sem data e hora com data.
o)Conversão fácil para objetos do pacote sql.
o) class Month e Year que seriam TimeInterval e a classe Day
o) Month e Year seriam iteraveis Year itera os meses e Month os seus dias
o) permitir calculos de datas/ horas
// formato iso ano-mes-dia
CalendarDate aniversario = new CalendarDate(2008,1,1);
Quanto falta para o aniversário a contar de hoje ?
Period period = CalendarDate.today().until(aniversario).toPeriod();
System.out.println(period.toString()); // P0000-07-01T12:23:14
P0000-07-01T12:23:14 <- padrão iso para periodos que significa que falta 7 meses , 1 dia , 12 horas , 23 minutos e 14 segundos para o dia 2008-01-01 à meia-noite.
Para criptografia algo simples como
byte[] hash = CriptoUtils.md5("stringdeteste");
e
String hashbase64 = CriptoUtils.md5AndBase64("stringdeteste");
O primeiro devolde o hash propriamente dito, o segundo devolde o hash codificando em base64. Este é muito usado para passwords por exemplo.
claro que teriamos tb CriptoUtils.base64(byte[] bytes);
Dinheiro
Vamos trabalhar com várias moedas ou só reais ?
Money
ammount
java.util.Currency
// operações de soma etc…
// operações de divisão inteira e parcelada.
java.util.Currency é importante se for para várias moeda, porque contém a informação de quantas casas decimais a moeda aceita (nem todas as moedas tem centavos… algumas tem milésmos e algumas não tem parte decimal)
O truque do Money é usar um long internamente e não um BigDecimal que junto com Currency mantém tudo ok. E a importancia dele é na hora da divisão porque não pode desaparecer/ser criado dinheiro durante a operação.
uma classe abstrata para conversão entre moedas seria interessante tlv possamos fazer uma implementação simples com JDBC (tabela de cotações) para exemplificar. Ou lendo de um xml que seria bom para teste.
Teriamos tb Money m = Brasil.reais("124587") e Money m = Brasil.reais(1458,87) para facilitar as construções.
Formatação já existe com CurrencyFormat
pack de metricas: o que é isso a final ?
Pelo codigo parece-me que é conversão de unidades, mas é só isso ?
Espera-se poder converter todas as unidades para todas as outras da mesma especia ? qual é o objetivo e a necessidade aqui ? envolve calculos também ?
É esse o ponto.Não temos por objetivo concorrer com Time and Money ou Joda.
São apenas coisas específicas que o pessoal pede.
O Philip e o Fernando se não me engano tinham idéias sobre isso também.
Para datas me parece perfeito.
Eu já tinha exposto aqui outrora(ná época pensei até em Bouncy Castle), e eu acho essa abordagem mais simples melhor.
É inegável a preferencia por reais, mas se alguém tiver algo pronto para implementar, não vejo o porquê de não fazê-lo.
No que tange a conversão, sim é só isso, até pq a API mais completa existente nisso é feita em javascript.Não existe nada disso em Java. Isso é uma feature que pode parecer imbecil(até pq é um mero conversor), mas todas o são até a necessidade de usá-las.
A maioria das pessoas não sabe por exemplo, que não existe KMH ou km/hora e sim km/h.
[quote]qual é o objetivo e a necessidade aqui ? envolve calculos também?
[/quote] Poderá envolver, mas não no momento.É apenas um simples conversor de unidades relacionadas.
Nós não julgaremos as features(o q é idiota para um, é útilpara alguém) eu por exemplo, poucas vezes precisei de algo relacionado a datas, no máximo:
SimpleDateFormat formatoData = new SimpleDateFormat("dd/MM/yyyy");
Date data = new Date();
System.out.println(formatoData.format(data));
ou
Date d = new Date();
PreparedStatement pstmt = consulta;
pstmt.setDate(1,new java.sql.Date(d.getTime()));
Mas sei q muitos precisam de coisas mais sofisticadas do que isso.
Sérgio, você gostaria de implementar algumas dessas suas idéias para nosso projeto? Como Criptografia ou datas para os dias úteis?
É esse o ponto.Não temos por objetivo concorrer com Time and Money ou Joda.
São apenas coisas específicas que o pessoal pede.
O Philip e o Fernando se não me engano tinham idéias sobre isso também.
[/quote]
Se o objetivo não é “concorrer” , então qual seria ?
Para o básico que vc exemplificou o java base chega e sobra…
Concerteza. Conto em pode enviar alguma coisa no fim de semana, baseado na estrutura que mostrei,mas até lá esperava por sugestões/criticas/ ideias e mais informação sobre o objetivo dessa parte da API.
Essas API´s são focadas só nisso(datas), por isso serão sempre muito mais especializadas.A função da BU é ser um “cinto de utilidades” do programador.É ajudar no dito “trabalho de corno” do dia-a-dia.
O objetivo é podermos prover soluções simples para problemas cotidianos(e outros nem tanto) para o dia-a-dia de um javaman.No fim de semana eu dou uma olhada na sua estrutura, reinstalei meu eclipse só agoradepois de uns bugs com o 3.3M3…
Essas API´s são focadas só nisso(datas), por isso serão sempre muito mais especializadas.A função da BU é ser um “cinto de utilidades” do programador.É ajudar no dito “trabalho de corno” do dia-a-dia.
[/quote]
O qual seria esse “trabalho de corno” do dia-a-dia ? Eu queria exemplos do que está falando, pq não tou entendendo a diferença / utilidade dessa API