Como já devem saber o MiddleHeaven está sendo utilizado para suportar o site www.javabuilding.com o que significa que funciona
O mecanismo de processamento de requisições HTTP é abstraido das classes de servlets e utilizado por um mecanismo baseado em ação. Devido à injeção de dependência e injeção de parâmetros apenas precisamos escrever uma classe que atua como controlador/presenter e configurar quais url ela irá responder. Todas as configurações são feitas em código. A razão para isto é que são configurações dos mecanismos que não mudarão no deploy, por isso não ha necessidade de as deixar em arquivos separados. Uma possivel futura é utilizar scripts groovy e javascript para as configurações mantendo o melhor dos dois mundos.
O foco do MiddleHeaven para GUI é prover um mecanismo comum para web e desktop orientado a componentes, mas enquanto isso não fica pronto com a toolbox de processamento e o processador baseado em ações já dá para fazer alguma coisa.
Junto com isso temos algumas tags próprias para ajudar a criar as páginas, em particular o forEach que aceita qualquer Iterable e não apenas List.
Entretanto o storage toolbox continua sendo remodelado. O problema é a utilização transparente em ambiente multi-thread e a possibilidade de utilizar o hibernate por detrás dos panos. A realidade é que esse não era o objetivo inicial, mas o mecanismo genérico está atrazado. Além disso é um exercicio para o design do toolbox já que será, provavelmente, o mais usado de todos é necessário que esteja bem solto para evoluir.
Por fim , queria deixar um pedido de comentário sobre as toolbox existentes e quais features seriam interessantes, como por exemplo, se deveria mesmo haver suporte ao hibernate.
O projeto Middleheaven continua a passo curtos. Muita gente tem demonstrado o seu apoio. Obrigado.
A identidade do projeto talvez esteja um pouco nebulosa porque até agora o que ha para mostrar é apenas o código e um conjunto esparso de texto falando de umas coisas chamadas toolboxes. Toolboxes são como pedaços da API, como no JSE temos o JCF , I/O e Threads que na realidade se encaixam mas as vemos como partes separadas.
O projeto começou por ser apenas um repositorio de código que eu utilizava repetidamente. Coisas como copia de arquivo e utiltários vários. Depois passou a ser um framework. Um conjunto de coisas prontas, mas complexas. À medida que construia outros frameworks mais simples eu pensava em poder levá-los até ao limite e incorporá-los no framework. Hoje, o MiddleHeaven não é mais um framework e sim uma plataforma de desenvolvimento. Uma arquitetura e design padronizada com partes extensiveis e plugáveis e um conjunto de plugins e extensões já preparadas.
O MiddleHeaven pode-se comparar ao Spring no espirito de facilitar a programação e conexão de partes da aplicação. Tal como o Spring o MiddleHeaven conta com um motor de injeção automática, mas à diferença do Spring ele não tem definição baseada em XML. Na ralidade não tem porque não foi implementado. O MiddleHeaven delega essa parte a um objeto especifico que pode ser implementado de muitas formas. Por agora, anotações são a base – pode escolher entre as do próprio MiddleHeaven ou as padrão como @Resource.
Ao contrário do Spring que utiliza directamente outros frameworks e não oferece nenhum encaspulamento – no sentido que você ainda tem que saber usar esse outro framework – o MiddleHeaven oferece as suas próprias estruturas e design que pode ser extentido com implementações diversas baseadas em diferentes frameworks de terceiros. Enquanto que no Spring estes frameworks são le reason de être do motor de injeção, no MiddleHeaven eles são apenas detalhes de implementação que podem mudar ou ser substituidos.
Um outro framework com que poderiamos traçar um comparativo é o JCompany. O JCompany é um framework proprietário com uma versão livre que vai um passo além do Spring oferecendo um certo encapsulamento em torno de APIs de terceiros visando o máximo possivel aderir a padrões de mercado. O JCompany oferece muito já pronto e está mais para aplicação costumizável do que para framework propriamente dito. Contudo o conceito por detrás é muito semelhante ao do MiddleHeaven. A grande diferença é que – além da licença – o MiddleHeaven não corre atrás dos padrões de mercado. Esse é um objetivo explicito. Os padrões serão incorporados quando necessário e normalmente por debaixo dos panos já que todo o conceito do MiddleHeaven é exatamente abstrair toda essa parafernália de padrões e tecnologias que mudam constantemente.
O MiddleHeaven é fortemente baseado, não apenas em padrões , mas também em conceitos. As abstrações do MiddleHeaven tendem a ser ir o mais longe possivel para que possam ser reutilizadas o máximo possivel. Em alguns pontos isso pode significar menor performance ou uma complexidade extra que o programador considera desnecessária, contudo, é sempre possivel não utilizar o modelo do Middleheaven ou usá-lo parcialmente. O desafio é que o programador goste de usar o modelo do MiddleHeaven porque ele é natural.
Embora eu tenha começado dizendo que o MiddleHeaven está caminhando a passos curtos isso é porque estou me referindo a todas as capacidades que foram sonhadas para ele. Contudo ele já faz muita coisa. Já é possivel desenvolver uma aplicação web no estilo do Spring MVC , o ponto que falta para fechar o ciclo e poder libertar uma versão beta ( ou talvez 0.2-alfa) é a persistencia; que está sofrendo uma remodelação. Depois vem a parte de interação com o usuário que permitirá aplanar a diferença entre o mundo web e o desktop. Esta é a funcionalidade realmente nova do MiddleHeave,n mas para chegar lá o básico tem que estar no lugar e ser sólido.
A primeira release do MiddleHeaven se aproxima. Faltam apenas duas toolboxes para poder utilizar o MiddleHeaven como plataforma para aplicações web simples. Neste estágio o MiddleHeaven seria equivalente ao Spring e a outros action-drivenweb-controlers.
Essas toolboxes são a de Storage e a de Security. A de Storage espera apenas por um lifting na questão do modelo de dominio vs modelo de persistência. Por agora o esforço nisso não é muito já que estou usando o storage baseado em banco OO para os testes e desenvolvimento de protótipos. Seria possivel liberar a release apenas usando essa feature se o tempo não ajudar.
Agora, uma toolbox que não pode faltar é a de segurança. O MiddleHeaven terá um toolbox especifica para lidar com licenças e o mecanismo de segurança tem que ser conciso com o modelo web e o modelo dektop. A principal concorrência é o Spring Security que é muito focado na parte web e deixa um pouco a desejar na forma de delegação e o JAAS que é padrão mas não é muito util na prática porque lhe falta uma ultima milha de integração com o dominio de segurança da aplicação final.
Algumas ideias já estão alinhadas mas está faltando um modelo coerente para o ambiente web e desktop que facilite a implementação de features de login/logout. 99% das aplicações* provávelmente usa a dobradinha username-password , mas isso não é sufientente hoje em dia para sites. captcha é quase que obrigatório em sites publicos.
Tudo isto para pedir a sua opinião sobre quais features seriam legais e mais importante quais seriam indesejáveis de lidar. Deixe um comentário.
* “Oh, as pessoas inventam estatisticas para provar qualquer coisa, Kent. 14% das pessoas sabem disso.” – Homer Simpson
O MiddleHeaven caminha a passos largos para um release que possa ser utilizado para fazer aplicações web basedas em JSP.
Foi adicionada a antevisão da toolbox de bootstrap para que se entenda como o MiddleHeaven carrega e se mantem a sua aplicação isolada. Foi adicionada também a antevisão da toolbox de critérios. Quanto a mim uma das preciosidades do MiddleHeaven que o diferencia de todos os outros frameworks e API por ai. Um cutucada ao Hibernate está inclusa (pun intended).
A mudança de layout é devida à falha do anterior em mostrar o menu ao lado quando na área de páginas.
Enquanto o MiddleHeaven não tem uma nova release, vá absorvendo todos os novos (novos?) conceitos que ele trás.
A plataforma java oferece uma vasto suporte ao conceito de conjuntos (coleções e mapas), mas não tão vasto quanto poderia ser.
A limitação à API de coleções atual é o uso da classe Colections para coisas avanaçadas como ordenação e a falta de suporte a Closures pelo Java. Mesmo se o Java tivesse suporte, depois das discussões para o Java 7 – a closures não ha garantia de que a API de coleções seria alterada.
Mesmo com o suporte a coleções da plataforma falta suporte a outras estruturas - que não sendo coleções – estão relacionadas a teoria de conjuntos como intervalos.
Intervalo
O MiddleHeaven dá suporta a intervalos pela classe Interval definida conjunto de elementos ordenável. Elemento ordenável é todo aquele que implements Comparable ou a que se possa associar um Comparator. Um intervalo pode ser fechado ( tem principio e fim) , aberto ( sem principio ou sem fim) ou vazio ( o principio e o fim são iguais).
A classe Interval suporta várias operações que podem ser feitas sobre ou com intervalos, tais como interseção, união ou verificar se um elemento está no intervalo.
Era importante incluir conceito de intervalo. Isso é especialmente relevante o dominio de tempos e datas (Time Toolbox) onde é comum definir intervalos de tempo. O MiddleHeaven define TimeInterval como uma extensão de Interval aplicada a TimePoint e adiciona operações relacionadas a tempo como a conversão para Period
Range
Um intervalo não é iterável porque ele pode ser aberto. Para ter um objeto semelhante a um intervalo mas que é iterável temos o Range. O objeto Range parece-se muito com um intervalo, mas podemos iterar os elementos através de um Incrementator. Um incrementador permite passar de um elemento ao próximo de uma forma controlada. Por exemplo, para passar de 1 a 2 adicionamos 1, mas para passar de 2009-09-10 a 2009-09-11 temos que obter a proxima data. Não podemos simplesmente adicionar 1.
O incrementador é especialmente relevante para elementos de um conjunto ordenável e denso como os numeros reais, já que para estes tipos de conjunto não podemos determinar qual é o proximo elemento a partir de um elemento dado. Por exemplo, nos numeros reais, a seguir a 1 existe um numero, mas não é 2, nem 1.5, nem 1.1, nem 1.0000001 , nem … Por causa desta impossibilidade matemática, ao criar um Range sobre um conjunto denso é necessário estabelecer o passo através de um incrementador. Por exemplo de 1 em 1, poderiamos iterar de 2 a 5 e teriamos [2, 3 ,4, 5] , mas como passo de 0.5 teriamos [2, 2.5 , 3 , 3.5 , 4 , 4.5 , 5].
Caminhando sobre o conjunto
A API de collections é muito boa usando o padrão Iterator ( um dos padrões GoF) mas falha usando o padrão Visitor (também do GoF) . O padrão visitor é muito util para fazer passar um objeto por todos os elementos da coleção. Assim, a coleção recebe um objeto que visita todos os elementos para um determinado fim. O padrão visitor é muito util porque esconde a iteração do for ou do while e desta maneira deixa a coleção fazer a caminhada pelos elementos como ela quiser ( em tese da forma mais eficiente). O padrão Visitor é aquele que seria utilzado por closures, caso elas existissem para aplicar uma certa logica a cada elementos do conjunto. O MiddleHeaven suporta o conceito por detrás do padrão visitor e introduz as interfaces Walkable e Walker. Um Walkable é um objeto que pode ser “caminhado” por um “caminhante” (Walker) em analogia a que um objeto Iterable pode ser iterado através de um Iterator.
A interface Walker apenas define um método genérico doWith() que pode ser usado para qualquer coisa. Embora o método não defina um retorno explicito, é possivel implementar uma outra classe que implemente esta interface e permita o acesso a um resultado através de outro objeto. Esse é o caso, por exemplo, de NumberAcumulator que extend Acumulator e implementa Walker e permite somar valores continos na coleção.
1 2NumberAcumulator<Real> acumulator = NumberAcumulator.instance(); 3 4Range range = Range.over(Real.valueOf(1), Real.valueOf(6),Real.ONE()); 5// calcula a soma de 1 até 6 6range.each(acumulator); 7 8assertEquals(Real.valueOf(21), acumulator.getResult()); 9
Código 1: Exemplo de uso de acumulador
Aqui utilizámos a classe Real porque NumberAcumulator precisa de um objeto que implemente a estrutura matemática GroupAditive. Real implementa uma forma especial de criar Range O código ficaria assim:
1 2NumberAcumulator<Real> acumulator = NumberAcumulator.instance(); 3 4// calcula a soma de 1 até 6 5Real.ONE().upTo(6).each(acumulator); 6 7assertEquals(Real.valueOf(21), acumulator.getResult()); 8 9
Código 2: Simplificação para criar um Range
Imprimir os numeros de 1 a 6 mostra um uso mais tradicional do Walker
Em java puro não teria muito ganho porque este Walker é muito simples. Mas se o Walker executar operações complexas (mais de 5 linhas) escrever isso dentro de um for é confuso. colocando isso em uma objeto é possivel definir a logia à parte e de forma genérica. Este é o objetivo, entre outros, de trazer closures para Java. Segundo as tendencias qualquer interface poderia ser substituida por uma closure. Embora closures não venham na versão 7 do Java é quase certo que virão em algum ponto. Enquanto não, as classe anónimas internas terão que servir.O ganho real viria da simplificação da sintaxe com o uso de Closures. Se um dia elas vierem vc poderia escrever assim:
Código 4: Exemplo de como seria o uso de Closures em futuras versões do Java
Um outro tipo de Walker importante é aquele que caminha sobre uma arvore. Para este tipo de objetos o MiddleHeaven introduz a interface TreeWalkable que extende Walkable com os métodos eachRecursive() e eachParent(). O método eachRecursive aplica o Walker ao objeto, depois aos filhos e depois aos filhos dos filhos, etc.. O método eachParent() é aplicado ao pai do objeto corrente e depois ao desse , assim até à raiz. TreeWalkable é especialmente útil para estruturas como o sistema de arquivos. ManagedFile da Managed File Toolbox implementa esta interface.
Enumerable
A classe utilitária Collections permite utilizar vários métodos sobre objetos que estendam Collection ou Map. Isso é feito para que os mapas e coleções em Java não tenham que implementar um numero elevado de métodos assim diminuindo a sua área de superfície. Isto é considerado uma boa prática. Contudo é estre,amente chato e ineficiente já que cada implementação não pode otimizar o processo definido pelo contrato do método. Além disso a chamada dos métodos é pouco encadeável o que confunde os programadores iniciantes e frustra os experientes.
Um outro problema com os mapas e coleções em java é a fala de uma interface comum para coleções e mapas.
O MiddleHeaven introduz a interface Enumerable (enumerável). Esta interface serve dois propósitos: 1) o de prover uma interface comum para mapas e coleções e extender o numero de métodos directamente invocáveis sobre os conjuntos.Um Enumerable é uma expanção do conceito de Iterator. Todos os Enumerable são Iterator mas têm mais coisas a oferecer.
A maior parte dos métodos de Enumerable recebem implementações de Classifier. Este é um objeto que dado um objeto de um tipo retorna outro objeto do mesmo ou de outro tipo. Em particular pode retornar um objeto do tipo Boolean. A maior parte dos métodos de Enumerable usam classificadores para boolean excepto map que usa classificadores para qualquer outro objeto. O objeto Classifier pode ser usado como filtro ou como transformador. Por exemplo, usando o método find() é possivel encontrar um objeto que passe no teste do classificador passado como argumento. Tudo isto sem ter que escrever nenhuma instrução for.
Enumerable implementa Walkable e todas as operações com Classifier geram novos conjuntos após aplicar o classificador a todos os elementos do ocnjunto. Os métodos que usam Classifier implementam o padrão Visitor de forma semelhante a Walker, a diferença é que o resultado obtido pelo Walker não é convertido para um outro conjunto, enquanto que os que usam Classifier são.
Com isto o MiddleHeaven extende as interfaces Collection,Set, List e Map implementando Enumerable e mais alguns métodos interessantes. Estes conjuntos são chamados de coleções aumentadas (enhanced) e implementam as interfaces EnhancedCollection, EnhancedSet , EnhancedList e EnhancedMap respectivamente. Para os obter basta invocar CollectionUtils.enhance(). O uso deste método é inivitável em Jaa devido ao fato de não ser possivel adicionar este método nas interfaces já existentes. Criar uma coleção aumentada é muito simples:
1 2List<Integer> lista = Arrays.asList(1,2,3,4,5,6); // lista na plataforma Java 3 4EnhancedList<Integer> elista = CollectionUtils.enhance(lista); 5 6
Código 5: Aumentando (enhancing) uma lista
Enumerable permite enumerar e iterar sobre um conjunto em uma certa ordem. Mas e que tal obter um elemento aleatóriamente de uma lista ou coleção ? O MiddleHeaven inclui a interface RandomEnumerable. Esta interface define o método random() que seleciona um elmento aleatóriamente da coleção. Isso permite o sorteio de numeros em uma linha de codigo. Por exemplo para sortear os numeros de um dado fariamos:
Muitos já tentaram criar bibliotecas alternativas para coleções. A Apache Commons Collections existia mesmo antes da API ser padrão na plataforma Java. Trabalhar com conjuntos é realmente uma facilidade que permite ao mesmo tempo tipagem forte, algoritmos eficientes e simplicidade para trabalhar com muitos objetos simultaneamente. O MiddleHeaven não poderia,portanto, se escusar que dar algum suporte a coleções.
Com o olho no Java 7 e a suposta introdução de closures, as coleções aumentadas teriam um uso mais simples e omnipresente mas mesmo sem a funcionalidade de closures ha muita coisa que é mais fácil de ser feita com o uso destas coleções. Por outro lado, devido à necessidade de suportar intervalos (sobretudo os de tempo) era necessário introduzir classes diferentes mas de forma compatível. Mas um intervalo não é iterável, então foi criado o objeto Range.
Converter qualquer conjunto da plataforma padrão para a biblioteca aumentada é muito simples. Aliás , à exceção de EnhancedArrayList que pode ser usada independente, aumentar uma coleção já existente é a única forma de obter uma coleção aumentada.
Quem segue o meu blog sabe do projeto MiddleHeaven. Este é um projeto bastante grande e complexo e que até agora ainda está apenas em uma versão pré-alfa.
Até a presente data, embora o blog tenha sido muito visitado por pessoas em todo o mundo, não está tendo a participação que desejo. Enquanto o projeto não está instalado em um servidor próprio, o blog deveria funcionar para aprender e comentar de forma semelhante a um fórum. Contudo, parece que a barreira da língua atrapalha a maioria dos interessados, que ao julgar pelas estatísticas de visita, são pessoas que utilizam o português.
Assim, decidi criar este blog em português. Agora a barreira da língua deve cair. É claro que para mim também é mais rápido escrever em português e com isso o material disponível deve também aumentar.
A ideia deste de blog é levar as pessoas a entenderem a ideia por trás do projeto e levá-las a usá-lo para os seus projetos e quem sabe a participar do seu desenvolvimento.