Olá Pessoal! Esse artigo tem como objetivo propor a solução de um problema no qual deparamos com razoável freqüência, e se você ainda não o teve pela frente, provavelmente ainda o terá especialmente se você desenvolve aplicações comerciais.
Meu grande objetivo com esse artigo, bem mais que propor uma solução, é despertar nos leitores o prazer obtido durante o processo a racionalização e solução otimizada de mais um, dos vários problemas que deparamos em nosso dia a dia.
O Problema
Imaginemos o cenário onde precisamos gerenciar eventos, por exemplo, no desenvolvimento de uma agenda. Uma das características de um evento é sua periodicidade, que pode ser, única, diária, semanal e mensal. Suponhamos que na periodicidade semanal, além de informar a quantidade de semanas de ocorrência do evento, seja necessário especificar os dias da semana que o evento ocorrerá, por exemplo:
. As aulas do curso de C# ocorrerão a partir do dia 30/10/2006, nas próximas 4 semanas às segundas, quartas e sextas-feiras.
. As reuniões de acompanhamento do projeto, ocorrerão a partir do dia 01/11/2006, pelos próximos 4 meses.
. A apresentação do projeto será realizada dia 20/12/2007.
Proposta de modelo de dados
Uma modelagem de dados muito utilizada seria algo semelhante ao apresentado abaixo, ou algo muito próximo disso, com uma tabela somente com os dias da semana relacionada à tabela de eventos.
EVENTO_TIPO_FREQUENCIA
Char
EVENTO_TOTAL_DIAS
Int
EVENTO_TOTAL_SEMANAS
Int
EVENTO_TOTAL_MESES
Int
EVENTO_DIA_SEGUNDA
Bit
EVENTO_DIA_TERCA
Bit
EVENTO_DIA_QUARTA
Bit
EVENTO_DIA_QUAINTA
Bit
EVENTO_DIA_SEXTA
Bit
EVENTO_DIA_SABADO
Bit
EVENTO_DIA_DOMINGO
Bit
Tabela 1- modelo parcial da tabela de eventos
Onde, o atributo TIPO_FREQUENCIA é definido em um domínio pré-estabelecido, por exemplo [1-único, 2 – diário, 3 – semanal, 4 - mensal].
Os atributos TOTAL_DIAS, TOTAL_SEMANAS, TOTAL_MESES, contabilizam o período de ocorrência do evento para cada tipo da freqüência.
E finalmente os atributos DIA_XXX, especificam os dias da semana de ocorrência do evento.
Deficiências
O processo de manutenção dessas informações será deveras penoso sob os seguintes aspectos:
. Temos uma quantidade razoável de atributos, onde sempre haverá desperdício de espaço em nosso repositório de dados.
. A codificação terá que contemplar todos esses atributos [procedures com muitos parâmetros, classes com todas essas propriedades, métodos de validação e operações de CRUD com vários parâmetros].
. Processo de alteração mais complexo – um evento inicialmente cadastrado como semanal, 4 vezes, às tercas, quintas e sábados ao ser modificado para mensal, 2 vezes, serão necessários instruções adiocionais para atualizar todos os atributos.
Sugestão
Nossa solução propõe uma redução drástica na quantidade de atributos na tabela de eventos.
EVENTO_TIPO_FREQUENCIA
Char
EVENTO_QUANTIDADE_FREQUENCIA
Int
EVENTO_DIAS_DA_SEMANA
Byte
Tabela 2- modelo parcial da tabela de eventos - solução proposta
O atributo TIPO_FREQUENCIA mantém a mesma definição da solução anterior.
Aqui, o atributo QUANTIDADE_FREQUENCIA armazena o total de ocorrência do evento, seu sentido será dado em função do TIPO_FREQUENCIA.
E, finalmente, a grande otimização do cenário, em um único atributo - DIAS_DA_SEMANA , do tipo byte, armazenaremos os dias da semana e todas as suas combinações, caso, claro, tenhamos uma freqüência do tipo semanal. Obviamente ainda poderemos ter “desperdício” de um atributo, mas somente para o tipo da freqüência diferente de semanal.
Mas como armazenar tantas informações em um único atributo, e do tipo byte?
Recordar é viver – os tipos de dados fundamentais são formados por conjuntos de bits – assim, um inteiro possui 4 bytes x 8 bits = 32 bits, um double possui 8 bytes x 8 bits = 64 bits, etc. No nosso caso, onde temos que manipular 7 informações (os dias da semana), a melhor opção é um campo do tipo byte que tem 8 bits, tudo bem, ainda desperdiçamos 1, mas nem tudo é perfeito.
Decodificando um campo byte temos:
0000 0001
01
0000 0010
02
0000 0100
04
0000 1000
08
0001 0000
16
0010 0000
32
0100 0000
64
Tabela 3- um byte em bit
Atribuindo um dia da semana para cada valor:
0000 0001
01
domingo
0000 0010
02
segunda-feira
0000 0100
04
terça-feira
0000 1000
08
quarta-feira
0001 0000
16
quinta-feira
0010 0000
32
sexta-feira
0100 0000
64
sábado
Tabela 4 - dias e valores correspondentes
Matematizando os dias da semana:
0000 0001
01 ? 2 0
domingo
0000 0010
02 ? 2 1
segunda-feira
0000 0100
04 ? 2 2
terça-feira
0000 1000
08 ? 2 3
quarta-feira
0001 0000
16 ? 2 4
quinta-feira
0010 0000
32 ? 2 5
sexta-feira
0100 0000
64 ? 2 6
sábado
Tabela 5 - dias e valores correspondentes
Ora, concluímos que o valor associado à um dia da semana corresponde ao número 2 elevado ao seu “peso”, 2 (dia da semana). E para combinação de vários dias como nos exemplos acima? Simples, é só “ligar” os bits correspondentes à cada dia, vejamos: + Segunda, Quarta e Sexta == 0010 1010 == 2 1 + 2 3 + 2 5 == 02 + 08 + 32 == 42 + Terça, Quinta e Sábado == 0101 0100 == 22 + 24 + 26 == 04 + 16 + 64 == 84.
Logo, ao invés de manipular diversos atributos, propriedades e parâmetros na codificação, calculamos um único valor numérico que representa a combinação de todos os dias da semana e assim manipulamos somente um atributo, simplificando e otimizando nosso trabalho.
Finalmente, a expressão para obtenção desse valor será : Valor += 2 (dia da semana) , onde o dia da semana será obtido de sua interface.
E o processo inverso?
Como recuperar o valor armazenado no repositório de dados e disponibilizá-lo ao usuário? Ora, precisamos desse valor representado em bits novamente, ou melhor, em um conjunto de bits (7), em seu devido estado fundamental – ligado x desligado, mais precisamente devido interação com a interface true x false. Mais uma vez recorremos à maravilhosa matemática. Nosso algoritmo foi baseado em funções exponenciais, onde uma das formas de análise dessas funções é o processo conhecido como fatoração, lembram?
64
2
32
2
16
2
08
2
04
2
02
2
01
Tabela 6 - fatoração de 64 na base 2, 64 = 26
Pois bem, precisamos de um conjunto, ou array de bits ligados e desligados, correspondente ao valor armazenado, combinando as operações de fatoração e resto das divisões sucessivas teremos exatamente as informações que precisamos:
42 = ?
O resto da divisão 42 / 2 = 0 (fatorando = 21)
O resto da divisão 21 / 2 = 1 (fatorando = 10)
O resto da divisão 10 / 2 = 0 (fatorando = 05)
O resto da divisão 05 / 2 = 1 (fatorando = 02)
O resto da divisão 02 / 2 = 0 (fatorando = 01)
O resto da divisão 01 1 (fim)
Tabela 7 - Combinando, fatoração e resto das divisões
Esses “zeros” e “uns” gerados, tomados de baixo para cima , corresponde exatamente ao nosso conjunto inicial de bits (10 1010), complementando-os com zeros à esquerda, bingo: 0010 1010, ou melhor, um array do tipo [false – false – true – false true – false – true –false].
Conclusão
É isso ai pessoal, espero ter atingido meu objetivo, despertando nos caros colegas a sensação de que nosso trabalho deve ir muito além de pesquisar no google códigos para resolução de problemas.
Precisamos sim, analisar as situações, racionalizar os problemas (sem esquecer a intuição) e propor soluções da melhor forma possível. Como vimos, especialmente depois de pronto, a codificação utilizada foi mínima, e é ai que está o grande mérito da proposta, conseguimos muito com bem pouco, em mais uma demonstração da lei natural do mínimo esforço (não à toa, a matemática foi nossa principal ferramenta).
Se vocês concluíram que pequenas idéias (geralmente fruto da imaginação) podem fazer grande diferença em nossas carreiras, já estarei satisfeito, afinal como dizia o grande Albert Einstein, “A imaginação é mais importante que o conhecimento”.

Caio Azevedo é arquiteto de softwares, especialista em soluções corporativas nos ambientes intranet/internet. Graduado em Ciência da Computação, Mestrando da Escola Politécnica da USP. Certificações Microsoft [MCP, MCAD e MCSD .NET]. Gestor da célula Microsoft da Magna Sistemas Consultoria ( www.magnasistemas.com.br).
Clique aqui para ler este artigo na Artigonal.Com