
Do básico ao intermediário: Estruturas (III)
Introdução
No artigo anterior Do básico ao intermediário: Indicador (IV), foi mostrado como poderíamos fazer, de modo muito simples e fácil de entender, algo que para muitos iniciantes seria extremamente complicado de ser feito. Porém agora, todos conhecem uma maneira simples e fácil, podendo assim colocar suas ideias em prática. Que seria criar um indicador, cujo objetivo seria uma indicação por meio de cores, de algum tipo de sistema de negociação. Claro que ali, mostrei como implementar o modelo de inside bar. Mas aquele conhecimento pode ser aplicado a todo e qualquer modelo cujo padrão de cores dos candles, indica ou não a possibilidade de negociação.
Muito bem, aquilo foi de fato bastante divertido. No entanto, acredito que podemos lidar com um outro tipo de coisa, que ao meu ver também é bastante divertida e interessante. E o assunto, começou a ser demonstrado, no final do artigo anterior. Mas antes de entrar na questão que iremos ver a partir deste artigo de agora. Precisamos voltar um pouco no tempo, e fazer uma breve retrospectiva.
Nos artigos sobre estruturas, especialmente no Do básico ao intermediário: Struct (II), foi explicado como poderíamos trabalhar com estruturas a fim de criar blocos de registro. Durante aqueles dois artigos, focados exclusivamente em falar sobre estruturas, mencionei que estruturas seria um tipo especial de dado. No qual poderíamos colocar diversas informações, porém de as organizando de uma maneira lógica e simplificada. No entanto, devido ao fato de não ter sido mostrado outras coisas antes. Seria complicado, ou mesmo desnecessário, entrar em mais detalhes sobre estruturas. Mas no artigo anterior, foi criada uma brecha adequada o suficiente para que possamos entrar mais profundamente em algumas questões. Basicamente, o objetivo agora é mostrar, que estruturas podem ser utilizadas a fim de se fazer muito mais coisas, do que simplesmente organizar dados de registro.
Então com base nesta breve introdução, podemos enfim entrar em um assunto, que irá fazer você, meu caro leitor, começar a entender por que as classes surgiram. Mas para isto, vamos iniciar o primeiro tópico sobre este assunto.
Código estruturado
Muito provavelmente uma das coisas que mais me desanima, é quando vejo um código todo bagunçado. Na época do antigo BASIC, que DEUS o tenha, de certa forma fazia sentido um código sem uma estrutura previamente definida. Isto por conta da própria natureza da linguagem. Em linguagem do tipo BATCH, como linguagens de script de lote, um exemplo seria o SQL, de certa maneira, podemos não ter uma estrutura muito bem definida. Já que na maior parte das vezes, as tarefas a serem executadas, são relativamente simples, assim como os código. Que normalmente são bem curtos.
Porém, a coisa começa a complicar, quando entramos em linguagens, com objetivos mais profundos. Como seria o caso do MQL5. Neste caso específico, muitas das vezes, temos um objetivo, que dificilmente será alcançado com poucas linhas de código. Mesmo quando fazemos uso de um arquivo de cabeçalho para ocultar boa parte da complexidade envolvida. Porém, existem algumas questões, que acabam tornando a programação um tanto quanto cansativa e tediosa. Uma destas questões a frequente tendência de programadores iniciantes em repetir trechos de código, que poderiam ser melhor estruturados.
E quando falo em código estruturado, não estou me referindo ao uso de funções ou procedimentos, a fim de manter uma certa organização no código. Neste caso, estou sim, dizendo, para jogar o código para dentro de estruturas. Isto de modo a poder tornar o código mais simples de manter e trabalhar. Muitos orientadores ou instrutores de programação, dizem que o fato de utilizarmos funções e procedimentos em um código, já o torna estruturado. Porém, o fato de fazermos isto, não significa necessariamente que o código esteja de fato estruturado. Ele apenas está melhor organizado. Só isto.
Para termos de fato um código realmente estruturado, precisamos utilizar meios e conceitos, que para muitos parece loucura. Ou no mínimo, complicado demais. Um deste meios, seria a utilização de classes. Porém, toda via e, entretanto, não é hora ainda de falarmos sobre classes. Isto por que, as classes não nasceram por conta de que, alguns programadores, um belo dia, acordaram e disseram: "Vamos criar algo para complicar a vida de quem esteja começando. Assim seremos os maiorais.". Não meu caro leitor, classes, somente surgiram devido a uma limitação de algo que ainda não foi mostrado como utilizar de fato. Que é a criação de um código verdadeiramente estruturado.
Para entender que limitação seria esta, precisamos começar a nos aprofundar em questões um pouco mais avançadas. Então se prepare, pois a coisa a partir de agora, realmente irá começar a ficar muito divertida e interessante.
Muito bem, talvez você esteja olhando meio que desconfiado e sem entender o que estou querendo mostrar. Mas vamos começar aos poucos. Pois de fato, é extremamente necessário que você consiga entender o que será feito. Caso contrário irá ficar todo confuso com o que iremos começar a modelar, a fim de atingir o que seria a programação orientada em objetos.
No artigo anterior, vimos o seguinte código mostrado abaixo.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. input bool user01 = true; //Show time scale 05. input bool user02 = true; //Show price scale 06. //+----------------+ 07. struct st_Mem 08. { 09. long View_DateScale, 10. View_PriceScale; 11. }gl_StyleGraphic; 12. //+------------------------------------------------------------------+ 13. int OnInit() 14. { 15. gl_StyleGraphic.View_DateScale = ChartGetInteger(0, CHART_SHOW_DATE_SCALE); 16. gl_StyleGraphic.View_PriceScale = ChartGetInteger(0, CHART_SHOW_PRICE_SCALE); 17. 18. ChartSetInteger(0, CHART_SHOW_DATE_SCALE, user01); 19. ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, user02); 20. 21. return INIT_SUCCEEDED; 22. }; 23. //+------------------------------------------------------------------+ 24. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) 25. { 26. return rates_total; 27. }; 28. //+------------------------------------------------------------------+ 29. void OnDeinit(const int reason) 30. { 31. ChartSetInteger(0, CHART_SHOW_DATE_SCALE, gl_StyleGraphic.View_DateScale); 32. ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, gl_StyleGraphic.View_PriceScale); 33. ChartRedraw(); 34. }; 35. //+------------------------------------------------------------------+
Código 01
Este código é bem simples, porém se você de fato é curioso, deve ter procurando saber mais sobre as propriedades de gráfico, isto a fim de tentar conseguir criar e manipular a aparência do gráfico, diretamente via código. Se você, de fato veio a fazer isto, devo lhe dar os meus parabéns. Já que esta é uma das premissas para quem de fato, irá se tornar um bom profissional no futuro.
No entanto, apesar da aparente simplicidade deste código 01, e muitos o considerarem um código estruturado. Ao meu entender, isto que é visto no código 01, não é de fato um código estruturado. Sendo mais um código bem organizado, do que um código estruturado. Mas, apesar de ser simples, ele não é exatamente o tipo de código que, ao meu entender, seria ideal para começarmos a explicar o que seria um código estruturado. Para isto, vamos recorrer a algo ainda mais simples. Que neste caso seria scripts. Isto por que, scripts tem, e respondem a apenas, e somente um único evento, que seria o evento Start. No final deste evento, o código seria encerrado. Mais simples que isto: IMPOSSIVEL.
Então vamos começar, com o código visto logo abaixo.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. struct st_Mem 07. { 08. long View_DateScale, 09. View_PriceScale; 10. }StyleGraphic; 11. 12. StyleGraphic.View_DateScale = ChartGetInteger(0, CHART_SHOW_DATE_SCALE); 13. StyleGraphic.View_PriceScale = ChartGetInteger(0, CHART_SHOW_PRICE_SCALE); 14. 15. ChartSetInteger(0, CHART_SHOW_DATE_SCALE, false); 16. ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, false); 17. ChartRedraw(); 18. 19. Sleep(2000); 20. 21. ChartSetInteger(0, CHART_SHOW_DATE_SCALE, StyleGraphic.View_DateScale); 22. ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, StyleGraphic.View_PriceScale); 23. ChartRedraw(); 24. } 25. //+------------------------------------------------------------------+
Código 02
Este código 02, que é bem mais simples, do que o código visto em código 01. Tem como mesmo objetivo, ocultar e depois repor tanto a escala de preço, como a escala de tempo. Quando você executar este script do código 02, em um gráfico, irá ver algo parecido com o mostrado na animação logo abaixo.
Animação 01
Veja que é tudo muito fácil de entender. Sendo que o responsável por fazer as escalas ficarem ocultas por uns instantes, é justamente a linha 19. Ali, estamos dizendo que queremos uma pausa de aproximadamente dois segundos, antes do código voltar a ser executado. No entanto, quero que você preste atenção a duas coisas aqui, meu caro leitor. Que são exatamente as linhas 17 e 23. No artigo anterior, mencionei o motivo pelo qual este comando deveria ser utilizado em um código. Porém aqui, como estamos lidando com um script, e o tempo de espera é curto. Este comando, presente em ambas as linhas mencionadas é de fato muito importante. Sem ele, muito provavelmente não iriamos ver as escalas de preço e tempo sendo ocultadas, e depois mostradas novamente.
Certo. Até aí tudo muito bem pensado e bem compreendido. Mas este código 02, ao meu ver não é um código estruturado. Apesar de estamos declarando uma estrutura na linha seis. Então vamos começar a fazer o que muitos consideram ser um código estruturado. Para isto, mudaremos o código 02, para o código que é visto logo abaixo.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. struct st_Mem 05. { 06. long View_DateScale, 07. View_PriceScale; 08. }; 09. //+------------------------------------------------------------------+ 10. void OnStart(void) 11. { 12. st_Mem StyleGraphic; 13. 14. StyleGraphic = SAVE(); 15. 16. ChartSetInteger(0, CHART_SHOW_DATE_SCALE, false); 17. ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, false); 18. ChartRedraw(); 19. 20. Sleep(2000); 21. 22. RESTORE(StyleGraphic); 23. } 24. //+------------------------------------------------------------------+ 25. st_Mem SAVE(void) 26. { 27. st_Mem local; 28. 29. local.View_DateScale = ChartGetInteger(0, CHART_SHOW_DATE_SCALE); 30. local.View_PriceScale = ChartGetInteger(0, CHART_SHOW_PRICE_SCALE); 31. 32. return local; 33. } 34. //+------------------------------------------------------------------+ 35. void RESTORE(const st_Mem &arg) 36. { 37. ChartSetInteger(0, CHART_SHOW_DATE_SCALE, arg.View_DateScale); 38. ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, arg.View_PriceScale); 39. 40. ChartRedraw(); 41. } 42. //+------------------------------------------------------------------+
Código 03
Este código 03 irá produzir o mesmo tipo de resultado, que podemos ver na animação 01. Porém tem um pequeno detalhe. Diferente do código 02, aqui temos uma melhor organização das coisas. Visto que podemos utilizar a função da linha 25 em diversos momentos diferentes. Assim como também podemos utilizar o procedimento da linha 35, a qualquer momento. A principal vantagem deste tipo de modelagem e implementação que podemos ver no código 03, é justamente o fato de que, podemos salvar e restaurar, todos os valores de propriedades de gráfico, sem nos preocuparmos quais serão os valores que realmente serão modificados. Isto evita aquela coisa de termos de criar uma imensa quantidade de linhas, sempre contendo o mesmo tipo de código.
Porém existe um pequeno problema nesta mesma abordagem vista no código 03. E o problema é o seguinte: Note que estamos lidando com uma estrutura para conter os dados. Até aí tudo ok. Mas qual o sentido em implementarmos a função da linha 25 e o procedimento da linha 35, se o objetivo é trabalhar diretamente com dados presentes na estrutura?
Este tipo de coisa, que a princípio, parece não incomodar programadores iniciantes. Ou até mesmo, programadores mais experientes, ainda mais quando estamos lidando com códigos simples. Acaba se tornando um verdadeiro tormento, quando começamos a lidar com códigos mais elaborados. Isto por que, começamos a implementar coisas, que não fazem muito sentido fora do contexto dos dados que estão sendo trabalhados.
Este código 03, de fato é muito bom, para que isto seja explicado, e você, meu caro leitor, venha a compreender o conceito por de traz do que iremos fazer daqui a pouco. Observe o seguinte: Temos uma estrutura que pode ser utilizada em diversos pontos, distintos no código. Esta mesma estrutura tem como objetivo, salvar e restabelecer a condição em que o gráfico se encontra em um dado momento. Por conta disto, podemos implementar o código como mostrado acima.
No entanto, conforme vamos criando mais e mais coisas, a função SAVE e o procedimento RESTORE, começam a sair do contexto. Ou, podemos vir a necessitar criar uma outra função e um outro procedimento com exatamente o mesmo nome. Porém com um objetivo diferente, que não venha a ser o de salvar e restaurar as propriedades do gráfico. Neste momento, podemos utilizar a sobrecarga, mas isto acabará por complicar o código de maneira completamente desnecessária. E é neste ponto que entra a questão de o código ser ou não estruturado.
Em um código estruturado, esta mesma função SAVE e o procedimento RESTORE, deixariam de ser declarados como podemos visualizar no código 03. Onde não estão devidamente ligadas ao contexto da estrutura definida na linha quatro. E passariam a ser declarados, ou melhor dizendo, implementados, dentro do contexto da estrutura definida na linha quatro. Como este tipo de coisa, não tem como ser mostrada aos poucos, iremos direto ao que seria a mesma solução vista nos demais códigos. Só que agora em uma modelagem completamente estruturada. Tal coisa é vista no código logo abaixo.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. struct st_PropertyGraphics 05. { 06. long View_DateScale, 07. View_PriceScale; 08. //+----------------+ 09. void SAVE(void) 10. { 11. View_DateScale = ChartGetInteger(0, CHART_SHOW_DATE_SCALE); 12. View_PriceScale = ChartGetInteger(0, CHART_SHOW_PRICE_SCALE); 13. } 14. //+----------------+ 15. void RESTORE(void) 16. { 17. ChartSetInteger(0, CHART_SHOW_DATE_SCALE, View_DateScale); 18. ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, View_PriceScale); 19. 20. ChartRedraw(); 21. } 22. //+----------------+ 23. }; 24. //+------------------------------------------------------------------+ 25. void OnStart(void) 26. { 27. st_PropertyGraphics StyleGraphic; 28. 29. StyleGraphic.SAVE(); 30. 31. ChartSetInteger(0, CHART_SHOW_DATE_SCALE, false); 32. ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, false); 33. ChartRedraw(); 34. 35. Sleep(2000); 36. 37. StyleGraphic.RESTORE(); 38. } 39. //+------------------------------------------------------------------+
Código 04
Caramba. Que coisa mais maluca e sem noção. Cara, agora me deu um nó no cérebro. Pois até onde, eu já havia entendido. Uma estrutura seria como se fosse uma variável. Só que do tipo especial, podendo ser organizada de modo a podemos criar pequenos bancos de registro. Mas isto que estou vendo no código 04, para mim não faz o menor sentido.
Bem, neste momento, a régua acabou de subir. Quem não vinha praticando e estudando o que estava sendo mostrado. Agora não terá outra forma de progredir. Já que deste momento em diante, as possibilidades se multiplicam de maneira muito rápida exponencial. Porém não existe motivo para ter medo deste código 04. Estou tentando fazer as coisas, da forma que seja o mais didática possível. Justamente para evitar, precisar ficar explicando coisas, quando poderíamos focar em algo mais interessante.
Então vamos entender o que está acontecendo aqui, neste código 04. Primeiramente, este código 04, irá funcionar da mesma forma que os demais códigos visto anteriormente. No entanto, aqui temos uma vantagem, visto que agora aqueles mesmos procedimentos e funções, cujo proposito seria o de armazenar as propriedades gráficas. Estão e sempre estarão dentro do contexto da própria estrutura que irá conter tais dados. E é este tipo de coisa, que conhecemos como programação estruturada.
Por hora vamos ignorar a estrutura definida na linha quatro. E vamos focar no tratador de evento OnStart. Na linha 27 declaramos a estrutura da mesma forma que era feito anteriormente. Ou seja, a criação de nossa variável, ou registro especial, estará se dando da mesma maneira. Mas, olhe a linha 29 e a linha 37. O que passa em sua cabeça, neste exato momento, ao ver estas linhas? Muito provavelmente você esteja pensando: Bem, na linha 29 estou pedindo para salvar algo, já na linha 37, que este mesmo algo seja restaurado. Agora, se seu pensamento foi este, estamos na direção correta.
Então olhe novamente, as mesmas linhas. O que seria este algo que estamos pedindo para salvar e restaurar? Certo, este algo seria uma variável que declarei na linha 27. Hum, interessante. Então, deixe-me ver se consegui entender. Na linha 27, estou declarando uma variável. Quando a linha 29 é executada, estou pedindo para que esta mesma variável, venha a ser salva. Ok, como esta variável, tem como tipo, um registro das propriedades gráficas.
Então estou pedindo para que na linha 29, as propriedades gráficas sejam salvas. Assim nas linhas 31 e 32, posso modificar as propriedades sem me preocupar com possíveis mudanças. Legal, acho que estou começando a entender. Então, quando executamos a linha 37, estamos pedindo para que aquelas mesmas propriedades salvas, sejam restauradas. Fazendo assim, com que qualquer mudança efetuada entre as linhas 29 e 37, sejam descartadas. É isto? Será que entendi direito o que está sendo feito aqui no tratador de evento OnStart? Sim, meu caro leitor. Seu entendimento foi de fato bem adequado.
Legal. Mas agora estou com uma dúvida. Olhando o código 03 e o comparando com o código 04. Notei que não temos mais a mesma forma de declarar as coisas aqui. Isto com relação ao que tange às rotinas SAVE e RESTORE. Por que desta diferença está sendo feita entre ambos os códigos? Já que a princípio, ambos têm o mesmo tipo de objetivo e comportamento? Isto ainda não consegui captar e compreender.
Que bom que você observou isto, meu caro leitor, pois agora, devido ao fato de você ter compreendido o código dentro de OnStart, chegou a hora de explicar o código dentro da estrutura declarada na linha quatro. Então, desta vez, quero que você ignore momentaneamente, qualquer outra coisa presente no código 04, e foquemos única e exclusivamente no bloco da estrutura.
Observe que mudei o nome da estrutura para fins de tornar a coisa mais simples. Porém, você pode usar qualquer nome. O importante é que a estrutura esteja em âmbito global. Podendo inclusive estar presente em um arquivo de cabeçalho. Mas por enquanto, não vamos nos preocupar com isto. Apenas observe e preste atenção ao que será explicado.
Note que, mantemos as mesmas variáveis, vistas nos códigos anteriores. Estas variáveis, continuam acessíveis e perfeitamente funcionais, da mesma forma que seria feito, no código 03. Você pode inclusive trabalhar com elas. Mas isto será visto em outro momento. O importante, é o que acontece dentro das rotinas. No caso temos a rotina SAVE na linha nove e a rotina RESTORE na linha quinze. Veja que elas se parecem em muito com as vistas no código 03.
Mas, e é aqui onde a coisa começa a ficar interessante. As variáveis View_DateScale e View_PriceScale, já não precisam mais ser declaradas como visto no código 03. Por que? O motivo é que, para o compilador, e para um programador, estas variáveis fazem parte de um contexto. No caso, o contexto é justamente a estrutura st_PropertyGraphics.
Ou seja, por conta de que estamos lidando com um contexto, e que faz todo o sentido dentro da estrutura. NÃO PRECISAMOS MAIS DECLARAR AS VARIÁVEIS, como estava sendo feito no código 03. Onde, nas linhas 29, 30, 37 e 38, precisávamos dizer a qual tipo de dados estaríamos ligando as variáveis. Já que ali, no código 03, tanto a rotina SAVE, quanto a rotina RESTORE, não faziam parte do contexto da estrutura. Coisa que no código 04, já não faz mais sentido. Já que ambas rotinas pertencem a estrutura.
Isto é o que podemos realmente chamar de programação estruturada. Já que agora, podemos lidar com coisas, de forma complemente contextualizadas. Não mais, imaginando ou tendo que recorrer a uma leitura completa e total do código a ponto de compreender o que está acontecendo ali.
Sinta-se à vontade em fazer mudanças e experiência neste código 04, meu caro leitor, a fim de realmente conseguir entender o que está acontecendo. Mas, antes de terminar este artigo, quero mostrar uma outra coisa. Só que desta vez utilizando um outro código. Porém, como isto envolverá outras questões, vamos abordar isto em um novo tópico.
Manipulações simples de estruturas
No tópico anterior, mostrei como estaríamos contextualizando o código, ao criamos um código estruturado. Mas, apesar de toda aquela beleza, existem alguns cuidados a serem tomados. Claro que devido justamente a estes cuidados, é que surgiu a necessidade da criação das classes. Mas isto será visto em um outro momento. Agora vamos entender alguns destes cuidados.
Primeiro, dentro de uma estrutura, todos os dados seguem um critério muito simples. Eles podem ser públicos ou podem ser privados. Geralmente quando declaramos uma estrutura simples, sempre teremos dados públicos. No entanto, quando estamos trabalhando com uma programação estruturada, NÃO QUEREMOS dados públicos. De fato, neste tipo de caso, o que desejamos é garantir que os dados irão e deverão permanecer íntegros durante todo o período de vida dos mesmos.
Para garantir esta integridade, podemos mudar o tipo de acesso que os dados terão. Agora preste atenção, meu caro leitor. O que será visto aqui, NÃO DEVE ser usado em estruturas simples, como as vistas anteriormente. Somente utilize isto, quando de fato, vier a implementar código estruturado e que você deseje um controle mais fino sobre como o código estará trabalhando. Fazer uso, o que será mostrado, sem o devido conhecimento, irá acabar complicando algo, que a princípio é bem simples.
Para explicar isto de maneira adequada, vamos ver um código que seja simples, porém adequado ao que quero explicar neste momento. O mesmo pode ser visto logo abaixo.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. struct st_PropertyGraphics 05. { 06. long View_DateScale, 07. View_PriceScale, 08. Chart_Mode; 09. //+----------------+ 10. void SAVE(void) 11. { 12. View_DateScale = ChartGetInteger(0, CHART_SHOW_DATE_SCALE); 13. View_PriceScale = ChartGetInteger(0, CHART_SHOW_PRICE_SCALE); 14. Chart_Mode = ChartGetInteger(0, CHART_MODE); 15. } 16. //+----------------+ 17. void RESTORE(void) 18. { 19. ChartSetInteger(0, CHART_SHOW_DATE_SCALE, View_DateScale); 20. ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, View_PriceScale); 21. ChartSetInteger(0, CHART_MODE, Chart_Mode); 22. 23. ChartRedraw(); 24. } 25. //+----------------+ 26. }; 27. //+------------------------------------------------------------------+ 28. void OnStart(void) 29. { 30. st_PropertyGraphics StyleGraphic; 31. 32. StyleGraphic.SAVE(); 33. 34. StyleGraphic.Chart_Mode = CHART_LINE; 35. 36. ChartSetInteger(0, CHART_SHOW_DATE_SCALE, false); 37. ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, false); 38. ChartSetInteger(0, CHART_MODE, CHART_BARS); 39. ChartRedraw(); 40. 41. Sleep(2000); 42. 43. StyleGraphic.RESTORE(); 44. } 45. //+------------------------------------------------------------------+
Código 05
Observe que este código 05, se parece bastante com o código 04. Mas para exemplificar o que quero mostrar, adicionei uma nova propriedade de gráfico a estrutura. Esta propriedade, é a que está sendo declarada na linha oito, deste código 05. Observe que junto dela também foram adicionados, novas linhas nas rotinas SAVE e RESTORE. Nada demais e que mereça grandes explicações. Assim como também, ocorreram pequenas mudanças no procedimento OnStart. Que também são simples de entender e não preciso entrar em detalhes sobre tais mudanças. Porém quando você executar este script em um gráfico, irá ver algo parecido como o que é visto na animação logo abaixo.
Animação 02
Epá. Parou geral. Vamos rebobinar a fita. Pois acabamos de ter um resultado não esperado. E quero entender porque do gráfico não ter sido restabelecido ao seu estado original. Já que mantemos o mesmo tipo de princípio e ideia adotado no código 04. No entanto, acho que o erro pode estar sendo esta nova propriedade que acabamos de adicionar. Bem, meu caro leitor, é mais ou menos isto. Porém não é bem este o problema. O problema aqui é conhecido como vazamento de dados, ou falha de encapsulamento. Ou seja, algo que antes não podia ser feito está sendo feito. E isto é que está causando o resultado que você observa na animação 02.
Preste atenção: Na linha 32 estamos salvando as propriedades gráficas, e na linha 43 a estamos restaurando. Da mesma maneira que era feito no código 04. No entanto, aqui temos um problema, que é a linha 34. Mas não vejo problema ali. Será que se removemos esta linha tudo volta ao normal? Sim. Se a linha 34 for removida tudo volta ao normal. Mas não é este o ponto.
O ponto aqui é: Como os dados estão sendo salvos na variável StyleGraphics. E esta variável está diretamente relacionada a um pequeno banco de registros, que pode ser visto entre as linhas seis e oito. Qualquer coisa que viermos a fazer nestes registros irá afetar o conteúdo presente na variável StyleGraphics.
Assim, quando pedimos para restaurar os dados. Isto na linha 43, todos os dados presentes no registro serão utilizados. No entanto, devido a mudança que fizemos, na linha 34, o registro original foi perdido. E por conta disto, agora temos um valor diferente do que foi salvo, sendo aplicado ao gráfico. Restabelecendo o mesmo, com uma informação estanha.
Este tipo de problema é muito sério, e ao mesmo tempo muito comum de ocorrer. Para resolver isto, precisamos mudar a clausula de declaração dos valores dentro da estrutura. Lembre-se de que por padrão, todos valores são públicos. Porém, se mudarmos o código 05, para o que é mostrado logo abaixo, as coisas passaram a ser diferentes.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. struct st_PropertyGraphics 05. { 06. private: 07. //+----------------+ 08. long View_DateScale, 09. View_PriceScale, 10. Chart_Mode; 11. //+----------------+ 12. public: 13. //+----------------+ 14. void SAVE(void) 15. { 16. View_DateScale = ChartGetInteger(0, CHART_SHOW_DATE_SCALE); 17. View_PriceScale = ChartGetInteger(0, CHART_SHOW_PRICE_SCALE); 18. Chart_Mode = ChartGetInteger(0, CHART_MODE); 19. } 20. //+----------------+ 21. void RESTORE(void) 22. { 23. ChartSetInteger(0, CHART_SHOW_DATE_SCALE, View_DateScale); 24. ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, View_PriceScale); 25. ChartSetInteger(0, CHART_MODE, Chart_Mode); 26. 27. ChartRedraw(); 28. } 29. //+----------------+ 30. }; 31. //+------------------------------------------------------------------+ 32. void OnStart(void) 33. { 34. st_PropertyGraphics StyleGraphic; 35. 36. StyleGraphic.SAVE(); 37. 38. StyleGraphic.Chart_Mode = CHART_LINE; 39. 40. ChartSetInteger(0, CHART_SHOW_DATE_SCALE, false); 41. ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, false); 42. ChartSetInteger(0, CHART_MODE, CHART_BARS); 43. ChartRedraw(); 44. 45. Sleep(2000); 46. 47. StyleGraphic.RESTORE(); 48. } 49. //+------------------------------------------------------------------+
Código 06
Neste caso, quando você tentar compilar o código, lhe será mostrada uma mensagem muito parecida com a que pode ser observada logo abaixo.
Imagem 01
Note temos um erro acontecendo. Já que na linha 38 estamos tentando acessar um valor, que agora não é mais público. Isto devido ao fato, de termos incluído uma clausula private na linha seis. No entanto, se esta linha 38 for removida do código 06, poderemos em fim compilar o código. Já que as rotinas SAVE e RESTORE são públicas, justamente devido ao fato de termos incluído uma clausula public na linha doze. Sei que neste exato momento, isto que acabou de ser feito, é um tanto quanto confuso e complicado. Mas acredite, isto daqui é bem mais simples do que você possa vir a imaginar. Ainda mais por conta que neste exato momento, começamos de fato a utilizar uma forma de programação cem porcento estrutural. Pelo simples fato de termos incluído as cláusulas public e private em nosso código.
Considerações finais
Bem, chegamos ao fim de mais um artigo. Porém este artigo daqui, é um artigo especial. Isto por que, neste momento, entramos no que é conhecido como programação estrutural. Onde criamos pequenas estruturas de dados, e a contextualizamos com uso de procedimentos e funções, voltadas única e exclusivamente a tratar, manter e analisar, os dados presentes dentro de uma estrutura de código.
Sei que neste primeiro momento, o que foi visto aqui, pode se fato ser muito complicado e confuso. Ainda mais pelo fato de que para muitos, isto que foi visto neste artigo, foi o primeiro contato real com tal forma de implementação de código. No anexo, você terá acesso aos principais códigos vistos aqui. Isto para que possa treinar, praticar e estudar com mais calma, cada detalhe mostrado neste artigo.
É muito importante, que você, meu caro leitor, venha a criar um conceito adequado sobre o conteúdo visto neste artigo. Isto por que, se devidamente compreendido, os próximos passos, serão bem mais suaves de serem dados. Mas principalmente o entendimento sobre classes, que será feito explicado depois, será muito mais fácil e simples. De qualquer maneira, aqui foi feita apenas uma breve introdução a respeito do tema.
No próximo artigo, iremos entrar em mais detalhes sobre o que foi visto, aqui. Porém não deixe de estudar esta base inicial. Pois irá facilitar bastante a sua vida, nos conteúdos a ser visto nos próximos artigos.





- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso