Emissor NFC-e na nuvem? Confira na Embarcadero Conference!

No dia 22 de outubro de 2019, teremos mais uma edição da Embarcadero Conference. É o maior evento de Delphi do mundo, e acontece aqui no nosso país, em São Paulo. São centenas de participantes.

Nessa edição, assim como no ano passado, teremos sete palestras simultâneas em cada horário, todas acontecendo no mesmo auditório. Você escolhe qual palestra assistir selecionando o canal de áudio correspondente no seu fone de ouvido. A agenda completa está disponível no site do evento.

Com tantas palestras acontecendo ao mesmo tempo, dá até uma ansiedade em conseguir escolher qual palestra assistir. Mas se tem uma palestra que você não pode perder, é esta que vamos sugerir.

Nosso palestrante, Wagner Landgraf, estará apresentando a palestra “Anatomia de um emissor NFC-e na nuvem (REST API)“. Ah sim, estamos recomendando nossa própria palestra. Mas isso é uma mera coincidência, será muito interessante, acredite!

Por que “na nuvem”?

Ok, vamos dar uma palhinha aqui e adiantar algumas coisas. Uma delas é o “porquê”. Quando emitimos um documento fiscal (como NFC-e) com um sistema “na nuvem”, temos uma série de vantagens em relação à emissão do mesmo documento fiscal num sistema desktop ou mobile.

Só pra esclarecer aos mais iniciantes, um sistema “na nuvem” seria uma aplicação rodando na internet em um serviço como Amazon EC2/Lightsail, Microsoft Azure, etc. Isso ficaria acessível a de chamadas HTTP realizadas de qualquer lugar (outras aplicações desktop, outros sites, aplicações mobile, etc.). Isso traz inúmeras vantagens:

  • Um único e centralizado lugar pra configuração do ambiente de emissão (instalação de certificados, configuração de bibliotecas de criptografia, etc.)
  • Reduz o risco de problemas e custo de suporte em ficar configurando centenas de computadores nos clientes
  • Atualização e manutenção do sistema muito mais fácil – também não é necessário atualizar todos os clientes
  • Possibilidade de emitir NFC-e (e outros documentos fiscals) de qualquer plataforma (de uma aplicação desktop Windows, de uma aplicação mobile, até mesmo de um Raspberry PI, por que não?). Basta que haja conexão internet nessa plataforma.
  • Facilidade de desenvolver clientes em outras plataforma. Que tal desenvolver um PDV no mobile de forma muito fácil? Não há necessidade de portar e compilar bibliotecas complexas como emissores fiscais (ACBr por exemplo), geradores de relatório (FastReport, FortesReport), entre outros.

Dá pra falar mais um pouco?

Queremos você lá assistindo e interagindo! Mas pra atiçar um pouco a curiosidade, deixamos abaixo uma captura da tela de parte da documentação da API. Já dá pra ter uma ideia. Na conference iremos esmiuçar tudo isso!

Não é só isso…

Essa palestra será realmente interessante. Haverá mais uma surpresa que, temos certeza, causará um grande impacto em todos aqueles que trabalham com Delphi nessa área fiscal. Isso tudo é só o começo… Nos vemos na Embarcadero Conference 2019!

Bancos de Dados no Ecossistema Delphi: Webinar

No dia 10 de outubro a Softacom estará apresentando um webinar sobre “Bancos de dados no ecossistema do RAD Studio & Delphi. Processo de migração (legado para atualizado, para outro RDBMS), arquiteturas de camadas de dados (ORM), arquiteturas de acesso a dados (REST API)”.

Palestrantes

Wagner Landgraf da landgraf.dev será um dos palestrantes, falando sobre como o acesso a banco de dados evoluiu no Delphi desde suas versões iniciais, sobre Mapeamento Objeto Relacional (TMS Aurelius), Servidores API REST (TMS XData) e acesso remoto a bancos de dados (TMS RemoteDB).

Serge Pilko

Embarcadero MVP & CEO da Softacom

Wagner Landgraf

CEO da landgraf.dev / TMS Software Partner / TMS Business Product Manager

Bruno Fierens

Embarcadero MVP & CEO da TMS Software

O que você irá aprender

Para CEO / Gerentes / CTO / Diretores de TI / Gerente de Produtos:

  • Soluções Delphi atualizadas e frameworks para comunicação com bancos de dados;
  • Armadilhas na atualização do sistema e/ou migração para outro RDBMS;
  • Abordagens e práticas modernas com Delphi e RDBMS;
  • Arguments: vantagens de se utilizar Delphi e RAD Studio para sua aplicação multicamadas;

Para Desenvolvedores e Especialistas Técnicos:

  • Melhores práticas para desenvolver camadas de acesso a dados em projetos RAD Studio;
  • Como usar ORM para projetos Delphi;
  • Como desenvolver servidores REST API como um facade DB;
  • Dicas e truques para desenvolvedores diretamente dos arquitetos de frameworks e ferramentas para Bancos de Dados;

Principais Tópicos do Webinar

  • Padrões de acesso a dados 10-15 anos atrás e hoje
  • Armadilhas na migração de aplicações RDBMS legadas para versões atualizadas;
  • Prós e contras na migração para ORM em lugar de práticas tradicionais;
  • ORM para Delphi: TMS Aurelius – prós e contras da solução;
  • Prós e contras da migração para REST API em vez do uso “clássico” de acesso ao BD;
  • REST API server for Delphi ─ TMS XData. Prós e contras.

Somente para participantes do Webinar!

Não perca a chance de obter seu desconto promocional para novas licenças de produtos TMS Software e para a EKON conference!

Registration

Link para inscrição: https://www.softacom.com/en_softacom_october_webinar. *Todas as palestras em inglês.

5 Motivos para Usar Variáveis Inline no Delphi

O que é esse novo recurso de declaração de variáveis inline (inline variables) do Delphi, surgido na versão Rio 10.3?

Em resumo, é a possibilidade de se declarar uma variável em qualquer linha do seu código. Ou seja, você pode declarar uma variável da forma a seguir, dentro do bloco begin..end:

procedure Test;
begin
  var I: Integer;
  I := 22;
  ShowMessage (I.ToString);
end;

Muita gente já entendeu como esse recurso funciona, mas não entendeu por que ele é interessante. Neste artigo, vou mostrar essa nova funcionalidade com enfoque nas vantagens que ela traz.

1. Organiza seu código

A variável só passa a ser acessível a partir do ponto que ela é declarada. Pra muitas pessoas isso organiza melhor o código num método grande, pois é possível saber melhor onde aquela variável está sendo usada. Considere o seguinte código:

procedure Test;
var 
  A, B, C, D, E: Integer;
  Found, Done, Excluded: Boolean;
  Text: string;
begin
   // muitas
   // linhas
   // de 
   // código
end;

Pode ser confuso saber onde são usadas todas essas variáveis, quando elas estão sendo inicializadas, se ela já foi altera anteriormente, etc.. No código a seguir, sabemos que a variável Text por exemplo não existe no começo do código, e que ela só é utilizada ao final. Ninguém “mexeu” nela antes dessa parte do código:

procedure Test;
begin
   var A, C: Integer;
   // Não podemos usar o Text aqui!
   // linhas
   // de 
   // código
   
   var Text: string;
   // Text só pode ser usada aqui
end;

2. Minimiza bugs

Quem nunca cometeu esse deslize:

procedure Test;
var I: Integer;
begin
  for I := 0 to Count - 1 do
    Process;
  FazAlgoComI(I);
end;

Ou seja, usar a variável do for depois de terminado o loop. Isso não é seguro, e apesar do compilador emitir um warning pra isso, muitas pessoas o ignoram. Usando declaração inline do for, a variável só é válida dentro do for, e usá-la fora do bloco resultará em um erro de compilação:

procedure Test;
begin
  for var I: Integer := 0 to Count - 1 do
    Process;
  FazAlgoComI(I); // Erro de compilação!!
end;

A vantagem acima vem do fato de que o escopo das variáveis é limitado ao bloco em que elas são declaradas. Declarando as variáveis apenas dentro do escopo em que elas são usadas também minimiza a chance de erros. Por exemplo, suponha que você tem um código assim:

procedure Test;
var I: Integer;
begin
  I := CalculaAlgo;
  Persiste(I);
  // muuuuitas linha depois...
  Loga(I);
end;

Então você precisa refatorar esse código de modo que a primeira parte só aconteça em uma determinada condição. Você acha que só ali a variável I está sendo usada, e faz algo assim:

procedure Test;
var I: Integer;
begin
  if Condicao then
  begin
    I := CalculaAlgo;
    Persiste(I);
  end;
  // muuuuitas linha depois...
  Loga(I);
end;

Pronto, você esqueceu da última linha e talvez o valor de I não seja o que você espera. Alterando o escopo da sua variável para o bloco irá gerar erros de compilação caso a variável seja usada fora do bloco, o que vai lhe mostrar o problema imediatamente para você tomar uma decisão:

procedure Test;
begin
  if Condicao then
  begin
    var I: Integer;
    I := CalculaAlgo;
    Persiste(I);
  end;
  // muuuuitas linha depois...
  Loga(I); // Erro de compilação!
end;

3. Economiza digitação

Quem não quer mais produtividade? Se você puder digitar um pouco menos pra declarar uma variável, por que não? Agora é possível declarar e inicializar uma variável ao mesmo tempo:

procedure Test;
begin
  var I: Integer := 22; 
  ShowMessage (I.ToString);
end;

Mas não só isso. Há também a inferência de tipo, o que significa que na maioria dos casos você não precisa incluir o tipo da variável ao declará-la. Basta o código de inicialização para o Delphi saber qual é o tipo da variável.

Parece pouco? Imagine um caso onde o tipo da variável é uma coisa assombrosa usando generics:

procedure NewTest;
var
  MyDictionary: TObjectDictionary<string, TObjectList<TMyAmazingClass>>;
  Pair: TPair<string, TObjectList<TMyAmazingClass>>;
  List: TObjectList<TMyAmazingClass>;
begin
  MyDictionary := TObjectDictionary<string, TObjectList<TMyAmazingClass>>.Create;
  MyDictionary.Add('one', CreateList);
  Pair := MyDictionary.ExtractPair('one');
  List := Pair.Value;
  ShowMessage(List.Count.ToString);
end;

Com a declaração inline e a inferência de tipo, você pode reescrever o código desta forma:

procedure NewTest;
begin
  var MyDictionary := TObjectDictionary<string, TObjectList<TMyAmazingClass>>.Create;
  MyDictionary.Add('one', CreateList);
  var Pair := MyDictionary.ExtractPair('one');
  var List := Pair.Value;
  ShowMessage(List.Count.ToString);
end;

Melhor, não?

4. Aumenta a performance

O fato de as variáveis pertencerem a um escopo mais limitado (dentro de um bloco begin..end) pode até aumentar a performance do código!

Você pode ver mais detalhes sobre isso neste excelente artigo: Inline Variables can increase performance. Mas em resumo: a variável será inicializada apenas se e quando a execução entrar no código, e será finalizada imediatamente quando a execução sair do código. Ou seja, neste código:

procedure TestInlineVars(const ACondition: Boolean);
begin
  // BEFORE
  if (ACondition) then
  begin
    var S := 'Inline String';
    var I: IInterface := TInterfacedObject.Create;
    var F: TFoo;
    F.S := 'Managed Record';
  end;
  // AFTER
end;

As variáveis S, I e F são tipos gerenciados (string, interface e record). O compilador adiciona automaticamente código para inicializar e finalizar essas variáveis.

Se você chamar a procedure TestInlineVars milhões de vezes, isso terá um impacto grande. Porém com o código acima, essas variáveis só serão inicializadas caso ACondition seja verdadeiro e o bloco seja efetivamente executado. Menos código desnecessário sendo executado.

5. Facilita o uso de diretivas de compilação

Até em pequenas coisas esse recurso pode ajudar. Isso me chamou a atenção ao ler este post: Unexpected Benefit of Inline Variables: Conditional Blocks, que mencionou esse benefício.

Se você usa diretivas de compilação onde declara diferentes variáveis para cada situação, você tem que colocar diretivas na declaração também:

procedure DoesSomething;
var
  {$IFDEF CASE1}
  var1: Integer;
  {$ENDIF}
  {$IFDEF CASE2}
  var2: Integer;
  {$ENDIF
begin
  {$IFDEF CASE1}
  // use var1
  {$ENDIF}
  {$IFDEF CASE2}
  // use var2
  {$ENDIF}
end;

Chato, hein? Acho que assim fica mais fácil e legível:

procedure DoesSomething;
begin
  {$IFDEF CASE1}
  var1: Integer;
  // use var1
  {$ENDIF}
  {$IFDEF CASE2}
  var2: Integer;
  // use var2
  {$ENDIF}
end;

Acredito que as variáveis inline tenham ainda outros sutis benefícios, em situações específicas, que não tenha listado aqui. Caso suspeite de mais algum, deixe seu comentário. Se não concordou com os benefícios e acha que as variáveis inline não são uma boa novidade para o Delphi, comente também. Só não se esqueça de uma coisa: se não gostou, é só não usar!

O que gostei no Delphi Rio 10.3.2 update

A Embarcadero acabou de lançar uma nova versão do Delphi Rio (e consequentemente do Rad Studio e C++ Builder): a versão 10.3.2.

É uma atualização “menor” – ou seja, uma alteração no terceiro dígito do número de versão, de 10.3.1 para 10.3.2. Também significa que o codinome do produto ainda é “Rio”, e que os arquivos binários (leia-se DCU’s) são compatíveis com a versão anterior 10.3.1. Com isso, você não precisará recompilar os packages instalados no Delphi.

Por que então um artigo sobre isso? Em geral, atualizações menores contêm apenas pequenas correções e melhorias, porém não é o caso desta. Listo aqui duas novidades que pessoalmente considero significativas. Não custa lembrar que a Embarcadero recentemente publicou o Roadmap do Rad Studio – Maio de 2019 que lista o que eventualmente será incluído nas próximas versões “maiores” do Delphi. Agora, vamos às melhorias:

Suporte ao macOS 64-bit

O Delphi 10.3.2 inclui, finalmente, suporte a aplicações macOS 64-bit. Se você desenvolve aplicações para macOS com o Delphi, sabe o quanto isso é importante.

A Apple está há anos planejando e informando seus usuários de que as aplicações macOS 32-bit deixarão de funcionar. E essa hora chegou. No macOS Mojave, ao abrir aplicações 32-bit (as criadas com Delphi, por exemplo), os usuários tem recebido a seguinte mensagem:

App não está otimizado para o Mac e precisa ser atualizado

Eu diria que com uma mensagem dessa seu aplicativo não inspira muita confiança para o usuário, concorda? Ainda, na próxima versão do macOS, o macOS Catalina (10.15), as aplicações 32-bit simplesmente não funcionarão mais!

Portanto, para você que desenvolve (ou pretende desenvolver) aplicativos macOS com o Delphi, é um alívio saber que isso não é mais um problema: é só gerar os aplicativos em 64-bit e estará tudo certo!

Estabilidade e performance da IDE

Outra melhoria digna de nota é a melhora significa na estabilidade e performance na IDE. A versão inicial do Delphi Rio trouxe uma IDE renovada, com tema dark e um visual mais moderno. Mas também haviam “efeitos” visuais estranhos, lentidões, a tela era redesenhada várias vezes ao redimensionar, maximizar, entre outros problemas.

Isso foi melhorado e muito nessa nova versão. Se você já esta usando o Delphi Rio, acredito que vai sentir a diferença com uma IDE mais fluida e mais rápida em vários aspectos.

O Delphi Rio 10.3.2 já está disponível! Existem várias outras melhorias além dessas citadas. Se já estiver usando este última versão, deixe um comentário contando o que achou!

O que são memory leaks e quais suas consequências?

Um memory leak (ou vazamento de memória) acontece quando sua aplicação aloca um espaço na memória e nunca mais o libera.

Como os memory leaks acontecem em Delphi

Em uma aplicação Delphi, espaços de memória são alocados e liberados o tempo todo. Muitas vezes isso é feito automaticamente pelo compilador ou pela RTL – por exemplo, ao alocar variáveis de tipos primitivos, parâmetros que são passados a funções, etc. – e não precisamos nos preocupar com isso.

Porém, existem muitos casos em que nós alocamos memória manualmente. Um dos mais comuns acontece ao instanciar um objeto:

Obj := TMyObject.Create;

A linha de código acima irá alocar um espaço de memória e a variável Obj irá apontar para esse endereço alocado. Para liberar o espaço, pode-se usar o método Free:

Obj.Free;

Se o desenvolvedor esquecer de chamar o método Free, o espaço de memória associado ao objeto nunca é liberado. Temos um memory leak.

Consequências dos memory leaks

Você pode se perguntar: "Qual o problema? Já vi isso acontecer na minha aplicação e nunca tive nenhum problema prático!".

Realmente, em geral, não se sente muito os efeitos, quando são poucos memory leaks. Mas as consequências tem intensidades diferentes dependendo do tipo de aplicação.

Aplicações no cliente (desktop ou mobile)

Em geral, em aplicações desktop ou mobile, o efeito não é muito grave. Nos sistemas operacionais atuais, em geral a memória alocada pela aplicação é liberada quando a aplicação é encerrada, de modo a não causar instabilidade no sistema.

Mesmo assim, se sua aplicação gera muitos memory leaks, podem acontecer alguns problemas, causados pelo uso excessivo da memória:

  • Lentidão da aplicação e/ou do sistema: Acesso a disco pode ser necessário pra contornar a falta de memória.

  • Fechamento abrupto da aplicação: O sistema operacional pode forçar a finalização do sistema devido ao uso excessivo de memória. Isso é mais comum em aplicações mobile.

  • Bugs no sistema: Partes do sistema que alocam memória podem começar a falhar e causar bugs.

Aplicações no servidor

Quando se fala em aplicativos servidores, o problema fica pior. Isso porque idealmente você nunca irá fechar o servidor – você quer que ele rode para "sempre", sem se incomodar.

As consequências são praticamente as mesmas das aplicações desktop, mas como teoricamente o servidor nunca fecha, qualquer pequeno memory leak terá consequências futuramente. A memória será lentamente consumida ao longo de dias, semanas, meses, e seu servidor começará a apresentar lentidão, bugs e eventualmente irá parar de funcionar.

Como evitar os memory leaks

Existem técnicas e ferramentas para lhe ajudar a detectar e remover os memory leaks da sua aplicação. Isso será abordado em posts futuros.

E você? Já sentiu teve problemas com memory leaks na sua aplicação? Ou considera um item de baixa prioridade e tem coisas mais importantes pra se preocupar no seu código? Deixe seu comentário!