quinta-feira, 18 de junho de 2015

Abstract Editor - Parte III

Ok, até agora entendi como o Abstract Editor  funciona, tambem compreendi como posso colocar os elementos na interface, controlando a largura e altura, e agora a pergunta que não quer calar: quais são os recursos de controles que tenho a minha disposição para montar minha interface?  Quais são as pecinhas que tenho a minha disposição para montar o quebra cabeças do layout proposto.

E para você que ainda não viu os artigos anteriores segue os links abaixo.


Vamos estudar um pouco a respeito dos controles disponibilizados no editor abstrato, mais especificamente os que são chamados de containeres, ou seja, controles que podem agrupar outros.

Table x Responsive Table

Veja que mesmo neste modelo de layout responsivo temos espaço para encaixar as tabelas tradicionais, Table é o controle usado para isso (disponibilizado desde as versões anteriores do Genexus), e cujo código final gerado é definido por <table><tr><td> conteudo </td></tr></table>.

Seu uso encontra-se dentro do escopo que já conhecemos, ou seja,  normalmente determina um organizador de elementos na interface. A questão é que certo conjunto de controles organizado por <table> não terá característica responsiva, ou seja, não alterará a forma na medida em que a resolução da interface mudar.  Em outras palavras, você pode montar com <table> um conteúdo que sempre deve ser apresentado na forma original, e isto em qualquer dispositivo, a idéia é que a forma e apresentação seja igual em qualquer lugar.

O controle Table não oferece a opção Responsive Sizes para determinar as dimensões do controle no Grid System.

Responsive Table agrega a capacidade de organização de controles e, ao mesmo tempo, inclui os recursos sensíveis de dimensionamento conforme o dispositivo, em outras palavras, disponibiliza o Responsive Sizes.

Podemos incluir uma Table ou outra Responsive Table dentro de uma Responsive Table?
A resposta é sim, neste caso as células responderão à programação responsiva podendo se ajustar conforme a dimensão do dispositivo, menos o conteúdo definido dentro de Table, que sempre ficará fixo.  Na imagem a seguir temos uma Responsive Table 1 (RT1) com um Responsive Sizes, em seguida na primeira célula, outra Responsive Table (RT2), com uma Table também na primeira célula.


Cada Responsive Table possui uma interface Responsive Sizes para se determinar a dimensão de cada controle.

TabPage

Naturalmente TabPage é um agrupador de controles, que embute uma Responsive Table, ou seja, o conteúdo de cada aba poderá responder diferente para os ajustes dimensionais.


Nas abas poderão ser incluídos quaisquer outros controles como botões, textos, tabelas, webcomponents.

Grid e FreeStyleGrid

Os dois grids tradicionais são incluídos no design de interfaces responsivas, mas nenhum dos dois incluem propriedades responsivas, a não ser a nova propriedade Cell Class.  O FreeStyleGrid, por exemplo, é montado sobre um controle Table e não Responsive Table.


O FreeStyleGrid pode ser convertido para Responsive Table, bastando executar a opção Convert to Responsive Table, a partir do botão direito do mouse sobre o Grid.

Como os grids podem ser influenciados pelo Responsive Web Design?
A principio não podem, ou seja, todos os atributos e variáveis incluídas nos dois grids são sempre apresentadas. Então como fica? para se ocultar colunas desnecessárias é necessário: (1) definir o Theme Flat, (2) Programar nas colunas ocultáveis a classe WWColumnWWOptionalColumn

Modelos Padrões de Layout

Uma vez conhecidos os containeres principais, podemos começar a trabalhar sobre os modelos de layout que determinam a dimensão das colunas e seus efeitos sobre dispositivos distintos. Estão rolando por ai vários 'padrões' que determinam bons designs, isso porque já tem muita gente planejando os formatos de Grid System que possa atender aos diversos dispositivos.  É uma opção para se tomar a decisão de quantas colunas e também os dimensionamentos que as mesmas devem possuir, e a menos que você seja um expert em web design, talvez adotar um padrão seja uma boa.

A seguir apresento dois desses padrões.

Exemplo 1: Mobile & Desktop
Neste primeiro exemplo se programa para ExtraSmall (xs) e Medium (md), tem como característica principal, definir colunas que se alinham no momento em que ocorre a redução do layout para dispositivos móveis. Na imagem temos a definição dos dois modelos, e em seguida temos a apresentação do layout para Medium (md) e em seguida para Extra Small (xs)


A partir da definição, o que temos é o resultado em Medium e Extra Small, dos percentuais definidos.  Observe que temos em Medium um modelo bastante conhecido de uma coluna a direita, ou a esquerda, e uma área maior destinada a conteúdo, e uma barra inferior igualmente espaçada.

Para Extra Small temos uma barra superior (normalmente destinada a botões) e áreas inferiores no formato de um freestyle.

Tecnicamente este modelo é bastante plausível.

Exemplo 2: Mobile & Tablet & Desktop
Neste segundo exemplo programa-se para Extra Small (xs), Small (sm) e Medium (md). E igualmente ao exemplo anterior temos a definição e em seguida o resultado para Small(sm), para Medium (md) e finalmente para Extra Small (xs).


Existe muita informação por ai que trata a respeito desses modelos padrões, a seguir apresentamos o link de um desses sites, caso tenha interesse em aprender um pouco mais a respeito de Grid System.

Para saber mais:



Creio que com isso podemos dizer que concluímos o assunto do Abstract Editor, novamente um excelente recurso nos foi entregue, agradecemos aos Einsteisn da Artech pelo excelente aporte tecnológico, com certeza teremos ótimos programas sendo desenvolvidos nesta estratégia.


terça-feira, 16 de junho de 2015

Abstract Editor - Parte II

Pela primeira vez na história do Genexando tive que quebrar um artigo em pedaços, isso por conta da sua dimensão e complexidade, desta vez não teve jeito, falar sobre o Abstract Editor e Design Responsivos requerem não apenas um mas vários distintos.  Se você perdeu o primeiro clique Abstract Editor - Parte I.

Discutimos no artigo anterior como o Abstract Editor agrupava os controles em linhas e com isso, como poderíamos definir nosso conjunto visual. Agora precisamos assumir o controle do dimensionamento dos objetos envolvidos, e para isso precisamos entender um pouco sobre os conceitos originais de Responsive Web Design.

O que é Responsive Web Design?

Pode parecer estranho abordar esse assunto somente agora, mas se parar para pensar não precisamos muito para produzir coisas no Genexus, basta arrastar e soltar.  Creio, porém, para avançarmos um pouco mais na questão das dimensões será necessário entrar um pouco mais nos conceitos envolvidos.

Em termos bem simples, design responsivo significa que a interface deverá responder de maneira diferente de acordo com o dispositivo, situação bastante confortável para os usuários visto que atualmente os sistemas podem ser executados em muitas arquiteturas distintas.  Não se esqueçam que nosso sistema pode até ser apresentado em uma TV de 50", por exemplo.  O que devemos fazer é formatar o conteúdo de acordo com o tamanho.

 Como fazemos isso?  Grid Systems.

Grid Systems

O framework Bootstrap, utilizado pelo Genexus, prove um layout responsivo baseado em uma tabela dividida em 12 colunas. Ao incluirmos um elemento nesta tabela determinamos quantas colunas o mesmo consumirá neste conjunto.


As linhas não precisam ser iguais, ou seja, os controles podem variar em termos de dimensões e também em quantidade a cada linha, o que importa é o fato de que a soma de colunas não pode ultrapassar '12 colunas'.

Evidentemente que a largura desta tabela não é fixa, pois depende da resolução dos diversos dispositivos, e assim temos um modelo que gera proporcionalidade, ou seja, existirá uma excelente coerência entre a apresentação em um sistema de maior com um outro menor dimensão.

Sendo assim, o primeiro ponto a se levar em conta é que normalmente os controles nesta linha não possuem suas dimensões medidas em pixels (modo utilizado nos layouts tradicionais), e a medida normal neste ambiente é o %.

Abstract Editor e Grid System

Genexus prove uma propriedade Width que possibilita informar a largura percentual do controle na linha. Observe inclusive na imagem a seguir como os objetos são arranjados, na primeira linha temos os itens 1.1, 1.2 e 1.3 respectivamente com 33% de largura.  Na segunda linha temos os itens 2.1 e 2.2 ambos com 50% e finalmente, na terceira linha o item 3.1 com 100% de largura.  O mais interessante é que só percebemos isso quando olhamos para o Responsive Size, no Abstract Editor (em rosa) não temos essa visão e não dá para perceber que o item 6, por exemplo, ocupará o mesmo espaço que as linhas anteriores.
 

Para uma dimensão menor de dispositivo, o Extra Small, por exemplo temos um arranjo completamente diferente, no qual cada componente ocupara uma linha particular, e cada um com 100% de largura.

Levando-se em conta o modelo de coluna, chegamos a algumas medidas % fixas, outra característica deste framework, pois se observar o Width verá que existem algumas larguras padrões definidas. Não é uma dimensão livre.  Porque? exatamente devido ao Grid System de 12 colunas.  A figura a seguir oferece uma visão percentual relacionada ao numero de colunas que cada uma representa.


Ou seja, 8% equivale exatamente a dimensão de uma coluna, 17% equivale a duas colunas, 25% equivale a três colunas, 33% a quatro colunas, e assim por diante.

Se quiser fazer uma operação mais precisa envolvendo pixel, e considerando que a resolução do navegador no momento é 1000 pixel, teríamos uma coluna equivalendo a 1000/12 = 83,3 pixel, se o componente ocupa três colunas temos 83,3 x 3 = 250 pixel.  Em termos percentuais chegamos ao mesmo resultado, três colunas equivale a um percentual de 25%, desta forma 1000 * 25% = 250 pixel.

O problema aqui é que não temos controle algum sobre a largura do dispositivo, lembre que tudo é relativo, e poderemos ter, por exemplo o design tendo que ser montado em uma largura de 500 pixels. A forma mais simples de ver isso é buscar não se fixar na largura em pixel dos objetos, a menos que se tenha uma imagem com largura fixa, por exemplo.  Se a questão envolve apenas arranjo dos controles e textos, a medida percentual é eficaz.

Uma observação importante: Você não precisa definir as 12 colunas na linha do Grid System, se quiser colocar único controle com 8%, ou seja uma unica coluna na linha, isso será possível.

Larguras Padrões

O framework Bootstrap fornece um conjunto de quatro larguras (relativas também) para determinar quatro categorias de dispositivos.


O Genexus prove um mecanismo interessante na montagem da tabela responsiva, pois seguindo exatamente o modelo do Bootstrap, define a largura do controle para cada uma dessas quatro categorias, gerando um controle DIV determinando o numero de colunas que o mesmo ocupará de acordo com o 'dispositivo'.  O interessante é que utiliza o texto registrado na Class CSS para indicar as dimensões.

<div  class="col-sm-4 col-md-6 col-lg-5"  style="">
   <span class="BlocoTexto1"  id="TEXTBLOCK1" >1</span>
</div>

O controle neste exemplo possuirá três definições de dimensão:


Agora deve ter ficado claro, não? Percentual é mais fácil para entendermos, enquanto que colunas é mais simples para o browser calcular.

Offset

Ja estava me esquecendo de falar sobre Offset, que é a medida de deslocamento à esquerda de um controle no Grid System.  Isso significa, por exemplo que podemos deslocar um certo controle no grid determinando quantas colunas queremos que o mesmo pule antes de ser apresentado.

Na imagem a seguir, definimos que o controle 1.2 possui um Offset de 25%, significando que o mesmo será apresentado somente a partir da terceira coluna do Grid System.


Cada controle pode ter seu Offset definido, permitindo que os mesmos sejam espaçados horizontalmente.

Height

Não sei se você percebeu, mas até agora não entramos no assunto da altura do controle, apenas tratamos da largura.  Isso tem uma razão simples, pois a mesma quantidade de texto apresentado em uma largura de 25% possuirá uma altura diferente se apresentado em uma largura de 50%, exatamente a metade da altura.

Desta forma Height é também um conceito relativo no Responsive Web Design, e a menos que seu design exija que certo controle tenha uma dimensão fixa, como por exemplo um botão, não deveremos nos preocupar com isso.

E quando precisamos definir uma altura (e largura) fixa? a saída será recorrer as propriedades max-width e max-height do CSS. Ou seja, será necessário criar uma classe para dimensionar o controle e indicá-la na propriedade Cell Class no Abstract Editor.

Por exemplo, se temos um botão com dimensão 100x100, e queremos que a célula em que o mesmo se encontra se fixe na dimensão exata do mesmo.


Devemos: 1) criar uma classe e 2) associar a mesma ao botão.  Na classe criada programar o valor do max-width e max-height:


E em seguida associar esta classe a imagem no Abstract Editor, na propriedade Cell Class.

Observe que existe a propriedade Class no controle, porém esta não vai afetar a definição responsiva, somente surte efeito se for programada em Cell Class.

Do Fixo ao Relativo

Ok, estamos chegando ao final deste artigo, mas antes, já que estamos lidando com dimensões percentuais, vamos trabalhar um pouco na questão da conversão do dimensionamento pixel para %, simples não se preocupe, não temos muita matemática nisso.

Como já vimos anteriormente, no modelo responsivo buscamos trabalhar nos controles de forma percentual, e se tivermos uma definição semelhante a apresentada a seguir, duas colunas sendo a esquerda com 360px e 600px à direita, a conversão percentual seria algo como: 360px / 960px = 0.375 = 37,5%, na coluna esquerda.  Na coluna da direita teríamos  600px / 960px = 0,625 = 62,5%


A questão é que para convertermos para o Responsive Design, não teríamos como definir essas dimensões percentuais diferentes (37,5% e 62,5%), lembrando que dispomos de um conjunto fixo de opções (8%, 17%, 25%, 33%, 42%, 50%, 58%, 67%, 75%,, 83%, 92%, 100%).  Uma saída de contorno seria definir 12 frações da dimensão máxima definida, ou seja, 960 px / 12 = 80 px, e com essa fração poderíamos chegar a um numero aproximado de colunas da nossa célula a esquerda: 360 px / 80 px = 4.5 colunas. Portanto poderíamos definir que esta poderia ter 4 ou 5 colunas, respectivamente 33% ou 42%.  Ambos os valores não representam fielmente a dimensão fixa de 360 px originais, visto que 33% equivale a 316.8px e 42% equivale a 403.2px.

Infelizmente esta é uma situação que leva a uma perda para menos ou para mais da definição inicial, mas tratando-se de um modelo flexível perdemos na correspondência mas ganhamos na possibilidade da manutenção do design nos diversos dispositivos.

Melhor se as propostas básicas de design já levarem em conta o conjunto fixo percentual para criar os elementos.

Conclusão

Bom pessoal, creio que podemos encerrar por hoje, mas não o assunto, pois temos muitas coisas para aprender. Te vejo no próximo artigo.


Para saber mais:



segunda-feira, 15 de junho de 2015

Abstract Editor - Parte I

Esquentemos nosso cérebro um pouquinho, mas cuidado se estiver meio enferrujado melhor fazer um alongamento antes... Pois, entre alguma novas maluquices do tal Design Responsivo temos algumas que de fato complicam, ou talvez, assustam um pouquinho. Tableless já era um desafio para quem respirava Tables, Rows, Cels, então como desenvolver uma interface em um modelo onde células, dimensões, pixels, deixam de existir... Alguns dizem que devemos pensar relativamente. Que eu me lembre Einstein já fazia isso, porém o único problema é que não temos o cérebro dele, então como fazer para criar nossa própria Teoria da Relatividade Responsiva. Minha resposta: Brincando.

Então deixe de lado os manuais, livros, artigos com toda aquela teoria maluca, cheia de novos substantivos, e partamos para a prática com Genexus, não se esqueça não precisamos de muita coisa para produzir sistemas muito interessantes, apenas um Abstract Editor.

Abstract Editor

Temos dois editores disponíveis para construir interfaces Web, o tradicional (HTML) e o Abstract Editor (Responsive Web Design). Migrar de um para outro é coisa difícil de se fazer, principalmente para quem já desenvolveu muito na Web no modo 'tradicional', porém, brincando um pouquinho com o novo editor, deu para ter uma boa visão da sua funcionalidade e o monstrinho não é tão feinho assim.

Em primeiro lugar o Abstract Editor apresenta um controle chamado MainTable, que a principio não parece uma tabela em si, apenas quando incluímos algum controle qualquer (Button, Textblock, ...) é que aparecem linhas que indicam de fato uma 'tabela'. De fato precisamos desta 'tabela' para poder desenvolver nosso desenho e essa MainTable já é do tipo Responsive Table, um novo tipo de controle que estaremos explorando bastante.

Responsive Table

Podemos entender as Responsive Table como o controle fundamental destinado a se desenvolver um desenho de interface que encaixe nos diversos dispositivos que a mesma será apresentada. Isso mesmo, uma das principais características do tal Design Responsivo é desenvolver uma interface que possa ser apresentada em um navegador de internet em qualquer dispositivo (quer seja um PC, um Smartphone, Tablet). E considerando que cada dispositivo possui dimensões, resoluções, capacidades distintas, o 'framework' deve ser capaz de permitir que em qualquer um deles seja apresentado algo decente para o usuário.


A Responsive Table possui um conjunto de propriedades interessantes, e a que chama mais atenção é o Responsive Sizes, que surge quando pressionamos o botão direito do mouse sobre o controle. Neste controle encontramos os diversos Sizes que vao agrupar os diversos layouts que responderão às mudanças dimensionais dos dispositivos, que quer dizer, a cada dispositivo um novo layout poderá ser aberto, e quem determina isso são os diversos tamanhos pré-configurados neste controle, que são:

  • Extra Small, Phone <768px
  • Small, Tablet >= 768px
  • Medium, Desktop  >= 992px
  • Large, Desktop  >= 1200px

Até aqui, Genexus não inventou nada, esses Sizes são determinados por default no framework Bootstrap.

Layout

Ao se adicionar controles no editor, como por exemplo TextBlocks, cria-se o layout, e para cada Size, pode-se ajustar as dimensões dos controles, em termos percentuais. Desta forma dependendo da dimensão da interface os objetos são reorganizados em posição, veja por exemplo a diferença entre o Large (Desktop) e o Extra Small (Phone), e também na questão da dimensão, referindo-se ao Width programado para cada controle.


Acredito que a principal questão nesta interface Responsive Sizes é aprender a ler as linhas e seu significado, para em seguida aprender a dimensionar os controles.

Como estamos acostumados ao modelo da Table tradicional melhor fazer uma correspondência com este novo modelo para buscar uma melhor compreensão. No tradicional criamos uma especie de prateleira com diversas células dispostas em linhas, e cada linha reproduz a mesma quantidade de células da primeira linha.  Nosso trabalho é organizar os controles nestas células, que podemos juntar na horizontal (collspan) e vertical (rowspan). Na figura abaixo temos à esquerda (a) a tabela tradicional.

No modelo da Responsive Table, coluna a direita (b) na imagem acima, temos uma visão completamente distinta, pois apesar de parecer uma tabela, o que temos na pratica é um conjunto de linhas, e o conteúdo da linha depende do que se inclui e da dimensão de cada controle, e cada linha pode possuir um esquema distinto das demais.  Confuso? aparentemente sim, mas na pratica é mais fácil.  A forma mais simples de entender é você olhar cada linha individualmente, como se não houvesse nenhuma relação com a linha anterior, pois cada linha é criada independentemente da anterior ou da próxima.

Desta forma se olharmos nosso primeiro exemplo teremos, na primeira linha três células definidas (1.1, 1.2 e 1.3), cada qual com um TextBlock.  Na segunda linha temos apenas duas células definidas (2.1 e 2.2).  Finalmente na terceira linha temos apenas uma célula definida (3.3).

Pensando desta forma é mais simples, bastando que sejam definidos os controles necessários em cada linha. Teremos posteriormente o estudo do dimensionamento horizontal e vertical e também o conceito de Offset que desloca o controle na célula.  Mas isso é assunto para outro Post, vamos com calma aqui.

Quanto ao resultado da execução deste painel exemplo, teríamos algo assim:


Não acabou ainda,, temos muito mais detalhes para estudar sobre este assunto, no próximo post a respeito vou falar sobre dimensionamento, offsets e classes responsivas.  Por hoje é só, não vamos forçar tudo de uma única vez né, vamos aquecendo aos poucos.






segunda-feira, 8 de junho de 2015

Falando de Chaves

Você ja estabeleceu este desafio para si próprio, de ficar uma semana sem assistir tv a cabo? Não que tenha sido um desafio mas tive que, infelizmente, assistir aos excelentes canais abertos oferecidos a população brasileira, por total falta de opção, e descobri várias coisas muito interessantes:
  1. Existem pelo menos 5 canais do tipo espreme-sai-sangue e nenhum dá para assistir, aqueles que ficam apresentando as barbaridades cometidas pelos marginais em seus roubos, assaltos, assassinatos, latrocínios, e que agora são pegos pelas câmeras de segurança por ai, enfim, creio que isso é até um sério malefício, acredito que os marginais comemorem quando seus crimes aparecem na tv.  Por outro lado, a existência de tantos leva a crer que muita gente gosta mesmo é de uma confusão policial.
  2. O Silvio Santos esta meio gagá, e o engraçado foi vê -lo apresentar um tal produto milagroso  'Jequiti', ele disse que não acreditava nos resultados do tal creminho que sumia com as rugas, hehehehe...., acho que sua senil sinceridade não vai ajudar a vender muito.
  3. O programa do Gugu não é tão ruim assim, imagina chegar a esta conclusão, a coisa tava ruim mesmo, mas voltando ao tal programa o que pega feio é quando ele dança a tal musiquinha do passarinho que quer voar, dai a coisa é dose.
  4. Os canais de noticias mostram as mesmas coisas, parece que um copia o editorial do outro e nenhum comenta algo relevante que se faça pensar a respeito do que é repetidamente transmitido, e aquilo parece ser embalado em uma capa de seriedade, no final dá muito sono. Não que isso seja ruim, de fato ao final do dia estamos bem cansados mesmo e nada como uma boa oportunidade de ouvir aquela vozinha monótona enquanto dormimos um pouco, e também não perdermos nosso tempo vendo abobrinhas.
  5. Outra coisa irritante no chamado 'horário nobre' são aqueles comerciais chatos de partido politico com aquelas palavras distantes da nossa realidade: democracia, representação, o melhor para o país, ..., e outras papagaiadas que nem mesmo a pessoa que esta lendo o texto sabe o significado, ou mesmo acredita, mas também brasileiro gosta de mentirinha. Alguém ai acredita nessa ladainha? Não dá para acabar com isso? Temos mesmo que ver essas porcarias?
  6. E a conclusão inevitável: o melhor programa do canal aberto continua sendo o Chaves.
Por outro lado, já que não havia outra opção, tive a oportunidade de refletir sobre muitos temas que estavam meio enroscados no Genexando, e inspirado neste 'meu' melhor programa, peguei primeiro porque creio ser importante, então vamos falar de Chaves.

Ta bom, mas não se irrite! Simples ou Composta?

Opinar sobre o uso de chaves simples ou composta nas transações é bisbilhotar demais no problema de modelagem alheio, não se irrite, rs... mas o fato é que quem não ficou pensando um dia 'e se eu tivesse feito diferente...'  isto depois do sistema entregue. Enfim, mudanças estruturais tão profundas quanto redefinição de chaves causa muita dor de cabeça, então melhor pensar um pouco mais nas implicações antes de optar em usa-las.

Chave Simples

PróContra
Unicidade (autonumber)Permite gerar a unicidade do registro sem muito esforço, se for tipo autonumber, nem precisamos esquentar a cabeça e como a principal utilidade de uma Primary Key é gerar unicidade, então este modo é bem interessante. Normalmente quem cuida de gerar o id é o banco de dados.No caso de se utilizar autonumber para gerar a unicidade, temos que ficar atentos ao longo do tempo, quando a tabela ganha uma dimensão suficiente para estourar o limite definido no atributo. Por exemplo, um Numeric(4) somente vai chegar a 9999 registros, e se passar disso, você terá uma bela dor de cabeça e muitas reclamações de usuários insatisfeitos com as travadas estranhas do programa.
Unicidade (randômico)A unicidade do registro no formato GUID ou randômico, é uma boa opção, pois se bem programado não vai causar efeitos colaterais no crescimento da tabela, e o tipo não se repete.

Se for GUID, por exemplo, o atributo será maior que um Numeric(4.0), e muitos desenvolvedores não gostam de chaves muito grandes.
Unicidade (manual)Algumas situações exigem que ao se abrir a interface (WEB) já se tenha previamente o valor da chave, e neste caso temos a possibilidade de programar um sistema gerador de chaves particular.

A programação de um sistema gerador de chaves confiável e que preveja a possibilidade de vários usuários estarem fazendo a inclusão do registro simultaneamente, é custoso e necessita tratar muitas situações estranhas ao uso regular do sistema (WEB), como por exemplo queda da internet, fechamento do browser, isso antes da operação ter sido concluída. Poderá também estourar o limite do atributo.
Chaves EstrangeirasAssim como ocorre com a unicidade, um único atributo para conectar duas tabelas também é muito interessante, gasta-se menos energia para programar a conexão 1-N entre as tabelas.  Outro detalhe muito importante é que podemos simplesmente mudar o valor da chave estrangeira para provocar nova relação de registros. Para uma manutenção, por exemplo, não precisaríamos apagar tudo e recriar novamente, bastaria trocar o valor da chave estrangeira.Não se trata de um problema propriamente dito, mas neste modelo temos a possibilidade de programar Nullable=YES, que faz com que desliguemos a Integridade Referencial entre as tabelas.  Neste caso, as tabelas poderão ficar com 'buracos'.  Teremos neste modelo a questão do relacionamento entre duas entidades fortes cujo relacionamento pode ser enfraquecido.
Pattern Work With
O pattern Work With (Artech) programa a lista de parâmetros passados entre os programas será gerado a partir das chaves. A consequência será a necessidade de enviar outras informações via contexto, ou manualmente via websession.


Muita coisa para se analisar, e com chaves compostas teremos tambem muitos detalhes para se levar em conta.


Chave Composta

PróContra
Unicidade (1)
Chaves compostas normalmente geram mais trabalho para se programar a unicidade. Isso porque temos que trabalhar com o conceito de analise combinatória (difícil né), basicamente gerar um conjunto de valores que não se repetem.  A programação do for each (ou data selector) sempre exigirá varias cláusulas where.
Unicidade (2)
Uma vez definida e gravada a chave não existe a possibilidade de trocar os valores dos atributos, e para se trocar precisa: 1) apagar o registro, 2) criar um novo com a nova composição.  Neste modelo, o sistema fica mais rígido se comparado as Foreign Keys das chaves simples.
Unicidade (3)


Para gerar uma parte randômica da chave composta, necessitamos de alguma procedure que gere autonumeração, que deve ser programado manualmente, ou por meio de uma regra Serial.
Chaves EstrangeirasNão existe a possibilidade de algum elemento da chave ser Nullable=YES, a Integridade Referencial não pode ser desligada.  Neste caso, as tabelas terão maior qualidade neste modelo. Teremos aqui  relacionamento entre uma entidades forte e outra fraca, cujo relacionamento não pode ser enfraquecido nunca.Como todos os elementos estrangeiros normalmente fazem parte da composição da chave, temos que programar a passagem de parâmetros com todos os valores o tempo todo.
Pattern Work With
O pattern Work With (Artech) produz melhores resultados na chamada aos programas quando utilizamos chaves compostas.Temos menos trabalho na programação da comunicação entre os sistemas neste modelo.



Enfim, muitos detalhes que podem influenciar na tomada eficaz de decisão.


Você não vai com a minha cara?

De maneira geral o que temos em resumo é o seguinte, para chaves simples maior flexibilidade porém mais trabalho com o Work With (Artech), enquanto que as chaves compostas geram modelos mais rígidos porem mais eficientes no tal pattern.

Enfim, deixo para vocês complementarem este POST com suas visões deste tema tão polemico.

Ninguém tem paciência comigo.

Eu não entendo nada de IBOPE, não sei o que é levado em conta para manter tanta porcaria junta, nem mesmo o Campeonato Brasileiro salva. Confesso que na TV somente assisto Discovery, a Fox Sports também é muito boa para ver outros campeonatos mais decentes.


Agora entendo porque o Chaves esta a tanto tempo fazendo sucesso (desde 1971 no Mexico), então para comemorar vamos cantar a musiquinha: La vem o Chaves, Chaves, Chaves, todos atentos olhando pra tv, ...


Cale-se, cale-se, você me deixa louco!!!!!

segunda-feira, 1 de junho de 2015

Base TRN, Primeiro Round!


A discussão aqui seria se o Genexus deveria mudar e evoluir ao longo do tempo sua forma de programar ou se mantém sua tradição, ou ainda se deve mudar em um ritmo mais acelerado. Muitos ficam incomodados quando algo radical ocorre, enquanto que outros ficam quando algo radical não ocorre, enfim, a comunidade pede melhorias mas ao mesmo tempo se assusta com as entregas. Particularmente acredito que nada como uma 'evoluidazinha' de vez em quando, mas também me preocupo quando algumas pedem ajustes, senão nos programas existentes, mas pelo menos na maneira que pensamos.

O fato concreto é que Genexus Evolution 3 apresenta alguns recursos novos na linguagem de programação que chamam bastante a atenção, muitas anunciadas a anos nos eventos. BASE TRN é um mecanismo que vai te ajudar a pensar Genexus melhor, mais simples.

CLAUSULA BASE TRN

Comecemos pelo comando for each que agora inclui uma nova cláusula chamada <base trn>, que possibilita indicar qual a transação (ou nível de transação) que será associada ao comando, ou seja que permite definir a tabela base.

Temos nesta nova cláusula um recurso que pode perfeitamente substituir a atual DEFINED BY, permitindo que se aponte para outras tabelas que além de representar melhor o relacionamento gerado entre as tabelas, pode também acelerar o processo de especificação do programa, pois o Genexus não precisa 'calcular' a tabela base, você mesmo indica.

Falando em escolher a tabela base, temos uma situação interessante quando programamos uma relação M-N, como por exemplo, a transação de dois níveis apresentada abaixo (NotaFiscal e Produto), já bastante conhecida e explorada, o que temos é a presença de ProdutoId e ProdutoDescricao nos níveis NotaFiscal.Produto e também na transação original Produto.


O fato é que neste simples exemplo temos duas 'tabelas' que eventualmente terão o atributo ProdutoDescricao, Hummmmm? não entendi, acho que você se enganou! Calma meu amigo, vamos devagarzinho aqui.  A normalização do modelo, que o Genexus vai promover, gerará duas tabelas distintas uma Produto com o atributo ProdutoDescricao gravado fisicamente, e outra chamada NotaFiscalProduto com o atributo ProdutoDescricao alcançável pela tabela estendida, portanto, não se esqueça do poder e da força desta 'tabela'.

FOR EACH ANINHADO

Desta forma se programarmos um  for each do tipo Join (aninhado) poderemos ter a surpresa de ver o Genexus apontar para a tabela Produto, que eventualmente não representa a melhor relação possível.  Seguindo este exemplo, a programação a seguir apontará para a tabela NotaFiscal no primeiro for each e para Produto no for each aninhado, ou seja, teremos ai um péssimo Produto Cartesiano, situação que pode ser comparada a um erro.

(1) for each
        &NotaFiscalId = NotaFiscalId
        for each
            &ProdutoDescricao = ProdutoDescricao
        endfor       
    endfor


Um detalhe interessante desta programação é que o Genexus gera duas queries, uma para selecionar Nota Fiscal e outra para Produto.

(2)
SELECT [NotaFiscalId] FROM [NotaFiscal] WITH (NOLOCK) ORDER BY [NotaFiscalId] 
SELECT [NotaFiscalId], [ProdutoId] FROM [NotaFiscalProduto] WITH (NOLOCK) WHERE [NotaFiscalId] = @NotaFiscalId ORDER BY [NotaFiscalId]

Apesar de estarmos utilizando este modelo em quase 90% dos programas até hoje, o resultado desta programação, sob o ponto de vista do Genexus EV3 deixa de ser interessante, pois é possível alcançar a mesma resposta com apenas uma querie.

BASE TRN

E que quiséssemos apontar para a tabela mais próxima de NotaFiscal, ou seja, para NotaFiscalProduto, temos com a <base trn>, podemos apontar para o nível desejado na transação, bastando incluir no for each o nível da transação que desejamos alcançar, muito simples hein.

(3) for each
        &NotaFiscalId = NotaFiscalId
        for each NotaFiscal.Produto
            &ProdutoDescricao = ProdutoDescricao
        endfor       
    endfor


A query gerada nesta operação e exatamente a mesma dos for eachs aninhados, exemplo (1).

(4)
SELECT [NotaFiscalId] FROM [NotaFiscal] WITH (NOLOCK) ORDER BY [NotaFiscalId] 

SELECT [NotaFiscalId], [ProdutoId] FROM [NotaFiscalProduto] WITH (NOLOCK) WHERE [NotaFiscalId] = @NotaFiscalId ORDER BY [NotaFiscalId]

Um dos detalhes deste novo modelo é a possibilidade de apontar para outras transações do modelo.

(5) for each
&NotaFiscalId = NotaFiscalId
for each Produto
&produtoid = produtoId
load
endfor
    endfor

Evidentemente, o resultado é um produto cartesiano, mas ainda sem mudanças significativas nas queries.

(6)
SELECT [NotaFiscalId] FROM [NotaFiscal] WITH (NOLOCK) ORDER BY [NotaFiscalId] 
SELECT [ProdutoId] FROM [Produto] WITH (NOLOCK) ORDER BY [ProdutoId]

Em outras palavras, quando temos relações M-N sempre teremos duas tabelas que podem ser escolhidas, e em algumas situações não contamos com um atributo secundário para apontar, a nova cláusula oferece uma possibilidade digamos, mais elegante.

ECONOMIZANDO SQL COM BASE TRN

Um detalhe interessante na programação da cláusula <base trn>, é a possibilidade de gerarmos uma lista de transações, gerando, quando for o caso, queries com INNER JOIN.  A vantagem deste modelo é a ausência de for eachs aninhados, mas com resultados semelhantes.

PRODUTO CARTESIANO
A geração de produto cartesiano ocorre quando relacionamos duas tabelas distintas que não se conectam por um filtro implícito, como por exemplo o código apresentado no exemplo (1), em que programamos dois for eachs aninhados para obter um produto cartesiano. O interessante é que com <base trn>, alcançamos o mesmo resultado com um único for each.

(7) for each Produto, NotaFiscal
       msg(NotaFiscalData.ToString()+''+ProdutoDescricao)
    endfor

O melhor disso é que este gera apenas um único SELECT, ou seja, mais rápido e eficiente, portanto, muito melhor que o modelo programado no exemplo (1).

(8)
SELECT T1.[ProdutoId], T2.[NotaFiscalId], T1.[ProdutoDescricao] FROM [Produto] T1 WITH (NOLOCK),  [NotaFiscal] T2 WITH (NOLOCK) ORDER BY T1.[ProdutoId] 

JOIN COM UM FOR EACH
Uma pequena mudança na ordem das transações nesta lista se produz um efeito totalmente diferente, ainda com um único SELECT chega-se a um INNER JOIN nas duas ou mais tabelas envolvidas.

(9) for each NotaFiscal, NotaFiscal.Produto
        &NotaFiscalId        = NotaFiscalId
        &ProdutoDescricao    = ProdutoDescricao
        load

    endfor

SELECT gerado neste caso é similar a pesquisa em tabela estendida, ou seja, um INNER JOIN com as três tabelas envolvidas.

(10)
SELECT T2.[ProdutoId], T1.[NotaFiscalId], T3.[ProdutoDescricao] FROM (([NotaFiscal] T1 WITH (NOLOCK) INNER JOIN [NotaFiscalProduto] T2 WITH (NOLOCK) ON T2.[NotaFiscalId] = T1.[NotaFiscalId]) INNER JOIN [Produto] T3 WITH (NOLOCK) ON T3.[ProdutoId] = T2.[ProdutoId]) ORDER BY T1.[NotaFiscalId]

O resultado da execução deste for each é a mesma executada com dois for eachs aninhados (exemplo 1), porem com melhor performance.

PROGRAMAÇÃO TRADICIONAL
Sem o <base trn>, mas buscando o mesmo apresentado no exemplo (9) , é a programação com um único for each. Neste caso o que se programa é a tabela base NotaFiscal e tabela estendida.

(11) for each
        &NotaFiscalId        = NotaFiscalId
        &ProdutoDescricao    = ProdutoDescricao
        load
    endfor


A querie resultante neste modelo.

(12) 
SELECT [NotaFiscalId], [ProdutoId] FROM [NotaFiscalProduto] WITH (NOLOCK) ORDER BY [NotaFiscalId], [ProdutoId]

Resumo da História

Nas versões anteriores do Genexus tinhamos poucas possibilidades para gerar SELECT nas tabelas do BD, com a versão EV3 e as <base trn> temos situações que seriam resolvidas de formas distintas. Observe, que nesta pequena situação chegamos a seis modos distintos para recuperar informação entre Produto e NotaFiscal.

Outro detalhe muito importante é o especificador do Genexus, lembrando que cada programa a ser gerado em Java, C# ou Ruby, deve passar por ele que defina quais tabelas devem ser alcançadas e a forma de acesso.  O fato é que quanto mais tabelas temos na kb mais lento será o especificador para identificar uma tabela base e estendida que alcance tudo que se deseja no for each<base trn>, é uma forma de turbinar o processo, pois o próprio desenvolvedor define o que o especificador deve fazer.

O ponto mais negativo é que programas em versões anteriores poderão sofrer um pouco nesta nova definição, pois na sintaxe anterior o que tinhamos era for each [atributo order], e agora for each [transacao], portanto, é necessária uma pequena revisão.

Um detalhe para a Artech: o objeto Data Selector não foi influenciado pela <base trn>, creio que precisa.