Alguém aqui usa Lazarus?

128 respostas
M

Caros, atualmente trabalho dando manutenção em um sistema legado em Delphi. Procurando por uma ferramenta Open Source para programar em Object Pascal, encontrei a IDE Lazarus. Então, tenho algumas perguntas a fazer:

  1. Como está o projeto atualmente?
  2. Ela pode substituir o Delphi 7 (as versões posteriores ao Delphi 7 são meio bugadas)
  3. Pode-se desenvolver uma aplicação comercial somente usando o Lazarus, ele dá conta do recado?
  4. Ouvi dizer que o debug dele é lento. Isso procede?
  5. Existe refactor no Lazarus?
  6. Em comparação ao Delphi, é muito difícil desenvolver componentes para o Lazarus?

[]'s

128 Respostas

J

Eu uso. Mas não profissionalmente. Gosto da sintaxe do pascal.

  1. Como está o projeto atualmente? Sempre em desenvolvimento.
  2. Ela pode substituir o Delphi 7 (as versões posteriores ao Delphi 7 são meio bugadas). Meio bugadas!? Completamente. O free pascal é um compilador melhor que o delphi32. O segundo não suporta instruções mmx
  3. Pode-se desenvolver uma aplicação comercial somente usando o Lazarus, ele dá conta do recado? Sim.
  4. Ouvi dizer que o debug dele é lento. Isso procede? Não
  5. Existe refactor no Lazarus? Existe mas não como você conhece no beans ou no eclipse
  6. Em comparação ao Delphi, é muito difícil desenvolver componentes para o Lazarus? Não, a lcl é 100% compatível com a vcl, e isso quer dizer que você compila projetos do delphi no lazarus.
M

Meu projeto faz uso de um componente que faz acesso à porta serial que foi escrito para o Delphi. Eu posso instalar esse componente no Lazarus ou eu terei que rescrever o código do componente?

X

matheuslmota:
Caros, atualmente trabalho dando manutenção em um sistema legado em Delphi. Procurando por uma ferramenta Open Source para programar em Object Pascal, encontrei a IDE Lazarus. Então, tenho algumas perguntas a fazer:

  1. Como está o projeto atualmente?
  2. Ela pode substituir o Delphi 7 (as versões posteriores ao Delphi 7 são meio bugadas)
  3. Pode-se desenvolver uma aplicação comercial somente usando o Lazarus, ele dá conta do recado?
  4. Ouvi dizer que o debug dele é lento. Isso procede?
  5. Existe refactor no Lazarus?
  6. Em comparação ao Delphi, é muito difícil desenvolver componentes para o Lazarus?

[]'s


Como desenvolvedor delphi tentei usar um tempo o lazarus e desisti.
Essa estória de que as versões mais novas são bugadas é lenda. A única versão horrível de trabalhar era a 2005 porém a partir do 2006 é tranquilo.
Mas como você só vai fazer uma manutenção não vejo necessidade de compra de uma licença, da para ir de Lazarus mesmo. Agora no dia a dia, não tem como trabalhar.
(Isso é uma opnião pessoal).

M

x@ndy:
matheuslmota:
Caros, atualmente trabalho dando manutenção em um sistema legado em Delphi. Procurando por uma ferramenta Open Source para programar em Object Pascal, encontrei a IDE Lazarus. Então, tenho algumas perguntas a fazer:

  1. Como está o projeto atualmente?
  2. Ela pode substituir o Delphi 7 (as versões posteriores ao Delphi 7 são meio bugadas)
  3. Pode-se desenvolver uma aplicação comercial somente usando o Lazarus, ele dá conta do recado?
  4. Ouvi dizer que o debug dele é lento. Isso procede?
  5. Existe refactor no Lazarus?
  6. Em comparação ao Delphi, é muito difícil desenvolver componentes para o Lazarus?

[]'s


Como desenvolvedor delphi tentei usar um tempo o lazarus e desisti.
Essa estória de que as versões mais novas são bugadas é lenda. A única versão horrível de trabalhar era a 2005 porém a partir do 2006 é tranquilo.
Mas como você só vai fazer uma manutenção não vejo necessidade de compra de uma licença, da para ir de Lazarus mesmo. Agora no dia a dia, não tem como trabalhar.
(Isso é uma opnião pessoal).

Mas o que foi que você viu de negativo no Lazarus?

X

matheuslmota:
x@ndy:
matheuslmota:
Caros, atualmente trabalho dando manutenção em um sistema legado em Delphi. Procurando por uma ferramenta Open Source para programar em Object Pascal, encontrei a IDE Lazarus. Então, tenho algumas perguntas a fazer:

  1. Como está o projeto atualmente?
  2. Ela pode substituir o Delphi 7 (as versões posteriores ao Delphi 7 são meio bugadas)
  3. Pode-se desenvolver uma aplicação comercial somente usando o Lazarus, ele dá conta do recado?
  4. Ouvi dizer que o debug dele é lento. Isso procede?
  5. Existe refactor no Lazarus?
  6. Em comparação ao Delphi, é muito difícil desenvolver componentes para o Lazarus?

[]'s


Como desenvolvedor delphi tentei usar um tempo o lazarus e desisti.
Essa estória de que as versões mais novas são bugadas é lenda. A única versão horrível de trabalhar era a 2005 porém a partir do 2006 é tranquilo.
Mas como você só vai fazer uma manutenção não vejo necessidade de compra de uma licença, da para ir de Lazarus mesmo. Agora no dia a dia, não tem como trabalhar.
(Isso é uma opnião pessoal).

Mas o que foi que você viu de negativo no Lazarus?

Na época em que testei era extremamente lento, gerava um executável gigante(embora tenha como corrigir), a IDE e o refactoring eram horríveis e cheia de bugs e instalar um componente delphi era um parto.
Essa foi a experiencia que eu tive e já faz alguns anos hoje em dia não sei se melhorou ou não!

K

Testei o Lazarus uns 4 anos atrás e, naquela época, achei ele MUITO fraquinho comparado com o Delphi 7. Além disto, era também bem bugado. Travava o tempo inteiro.

O papo de que as versões do Delphi posteriores á 7 ser bugado é um mito. Um maldito mito que basicamente destruiu a Borland. Há uma versão bugada e horrível do Delphi, e esta se chama 8 (Octane). O maior erro da história da empresa.

Recentemente brinquei com o Delphi 2010 e achei MUITO legal. Fiquei uns 5 anos longe do Delphi e quando o reencontrei, foi uma surpresa maravilhosa. Sei lá: acho que se é para dar suporte à plataforma, compensa muito comprar o Delphi. Inclusive, a versão XE te permite acesso às versões anteriores (incluindo a 7) gratuitamente.

Compensa também comprar por outra razão: dar o suporte financeiro para que continuem o desenvolvimento da ferramenta que, apesar de ter perdido muito mercado, ainda é uma ferramenta foda.

M

kicolobo:
Testei o Lazarus uns 4 anos atrás e, naquela época, achei ele MUITO fraquinho comparado com o Delphi 7. Além disto, era também bem bugado. Travava o tempo inteiro.

O papo de que as versões do Delphi posteriores á 7 ser bugado é um mito. Um maldito mito que basicamente destruiu a Borland. Há uma versão bugada e horrível do Delphi, e esta se chama 8 (Octane). O maior erro da história da empresa.

Recentemente brinquei com o Delphi 2010 e achei MUITO legal. Fiquei uns 5 anos longe do Delphi e quando o reencontrei, foi uma surpresa maravilhosa. Sei lá: acho que se é para dar suporte à plataforma, compensa muito comprar o Delphi. Inclusive, a versão XE te permite acesso às versões anteriores (incluindo a 7) gratuitamente.

Compensa também comprar por outra razão: dar o suporte financeiro para que continuem o desenvolvimento da ferramenta que, apesar de ter perdido muito mercado, ainda é uma ferramenta foda.

eu gosto muito mesmo do Delphi. De todas as ferramentas que já usei (eclipse, netbean, visual studio, codeblocks e outras que não lembro agora), o delphi foi certamente a melhor. Produtividade total, debug excelente, bom nível de otimização dos executáveis, alta facilidade para integrar a aplicação com banco de dados, o editor de interface gráfica dá uma surra nos disponíveis para o Java, sem falar que gera um código muito mais limpo. Talvez o Delphi só perca (em termos de produtivade) para o Visual Studio 2010. Mas como eu disse, tava atrás de uma ferramenta open source e multiplataforma e achei o Lazarus. Me pareceu uma opção interessante, possuindo inclusíve, suporte ao qt. Mas como eu não conheço a ferramenta, vim pedir a opinião dos colegas mais experientes. Será que esse suporte ao qt funciona bem mesmo?

X

matheuslmota:
kicolobo:
Testei o Lazarus uns 4 anos atrás e, naquela época, achei ele MUITO fraquinho comparado com o Delphi 7. Além disto, era também bem bugado. Travava o tempo inteiro.

O papo de que as versões do Delphi posteriores á 7 ser bugado é um mito. Um maldito mito que basicamente destruiu a Borland. Há uma versão bugada e horrível do Delphi, e esta se chama 8 (Octane). O maior erro da história da empresa.

Recentemente brinquei com o Delphi 2010 e achei MUITO legal. Fiquei uns 5 anos longe do Delphi e quando o reencontrei, foi uma surpresa maravilhosa. Sei lá: acho que se é para dar suporte à plataforma, compensa muito comprar o Delphi. Inclusive, a versão XE te permite acesso às versões anteriores (incluindo a 7) gratuitamente.

Compensa também comprar por outra razão: dar o suporte financeiro para que continuem o desenvolvimento da ferramenta que, apesar de ter perdido muito mercado, ainda é uma ferramenta foda.

eu gosto muito mesmo do Delphi. De todas as ferramentas que já usei (eclipse, netbean, visual studio, codeblocks e outras que não lembro agora), o delphi foi certamente a melhor. Produtividade total, debug excelente, bom nível de otimização dos executáveis, alta facilidade para integrar a aplicação com banco de dados, o editor de interface gráfica dá uma surra nos disponíveis para o Java, sem falar que gera um código muito mais limpo. Talvez o Delphi só perca (em termos de produtivade) para o Visual Studio 2010. Mas como eu disse, tava atrás de uma ferramenta open source e multiplataforma e achei o Lazarus. Me pareceu uma opção interessante, possuindo inclusíve, suporte ao qt. Mas como eu não conheço a ferramenta, vim pedir a opinião dos colegas mais experientes. Será que esse suporte ao qt funciona bem mesmo?

Realmente a IDE do delphi é ainda superior ao Eclipse, Netbeans e Cia.
Tenho um único porém ao seu comentário "alta facilidade para integrar a aplicação com banco de dados, o editor de interface gráfica dá uma surra nos disponíveis para o Java,"
O delphi é extremamente produtivo para desenvolver no padrão de Interface Inteligente. O modelo Dataware do delphi é maravilhoso para isso, porém se você vai querer desenvolver OO no delphi ele se torna um inferno. Nisso o java é nota 10.
Para quem tenta fazer uma aplicação OO em delphi o primeiro problema é questão das referencias entre os objetos. No pascal, como não existe garbage colector, você cria um objeto é obrigado a destrui-lo. Isso se torna um problema quando esse objeto é compartilhado. Aqui até tem uma solução para isso, mas não é nada elegante.

F

LAZARUS ? CREDOO.

M

Credo por quê? Tem algum argumento técnico?

M

Também não gostei do Lazarus, parece o Delphi de 15 anos atrás.

E o suporte a MMX, o Delphi possui, mas é o compilador que cuida disso, enquanto o Lazarus a gente programa explicitamente. Pra mim, uma vantagem do Lazarus.

Os componentes novos e os recursos novos da IDE do Delphi não estão presentes no Lazarus. Delphi evoluiu muito, principalmente da versão 2007 em diante.

M

x@ndy:
Realmente a IDE do delphi é ainda superior ao Eclipse, Netbeans e Cia.
Tenho um único porém ao seu comentário "alta facilidade para integrar a aplicação com banco de dados, o editor de interface gráfica dá uma surra nos disponíveis para o Java,"
O delphi é extremamente produtivo para desenvolver no padrão de Interface Inteligente. O modelo Dataware do delphi é maravilhoso para isso, porém se você vai querer desenvolver OO no delphi ele se torna um inferno. Nisso o java é nota 10.
Para quem tenta fazer uma aplicação OO em delphi o primeiro problema é questão das referencias entre os objetos. No pascal, como não existe garbage colector, você cria um objeto é obrigado a destrui-lo. Isso se torna um problema quando esse objeto é compartilhado. Aqui até tem uma solução para isso, mas não é nada elegante.

O fato de o Delphi (ou Object Pascal, chame como quiser) não ser uma linguagem gerenciada não encaro como um problema, é uma característica da linguagem, assim como o C++ e o C possuem, que também têm essa características. Além do mais, também não é certo do ponto de vista das boas práticas usar objetos compartilhados.

EDIT:
Complementando o que eu disse, esse negocio de objetos compartilhados parece aquele padrão Singleton, que eu acho horroroso. Uma instância de um objeto para ser referenciada em vários lugar, posso está errado, mas nem parece OO, parece quase uma tentativa de programar de maneira procedual dentro do OO. Como eu disse, é minha opinião e posso está errado.
Agora voltando ao tópico, mais alguém usa o Lazarus atualmente? Até agora a única pessoa que de fato usa a versão mais atual do Lazarus é o julicbq. Os outros, usaram somente versões antigas (4 anos para um projeto que sofre alterações diárias é uma eternidade).

M

Outra coisa, todo mundo taca o pau no OO do object pascal. Mas ele possui recursos bem interessantes, polimorfismo, interface, muita coisa que o Java tem. A única coisa que eu tenho raiva no object pascal é a referência circular não existir, quando à vezes ela é necessária para introduzir um comportamento bidirecional entre as classes. Mas no mais, eu não acho o OO do object pascal ruim ou inferior ao de outras linguagens, como Java e C#.

K

marcosalex:
Também não gostei do Lazarus, parece o Delphi de 15 anos atrás.

E o suporte a MMX, o Delphi possui, mas é o compilador que cuida disso, enquanto o Lazarus a gente programa explicitamente. Pra mim, uma vantagem do Lazarus.

Os componentes novos e os recursos novos da IDE do Delphi não estão presentes no Lazarus. Delphi evoluiu muito, principalmente da versão 2007 em diante.

O Delphi de 15 anos atrás era o Delphi 2, que já era ordens de magnitude superior ao Lazarus :slight_smile:

Mas agora, numa boa? Eu acredito que com um apoio maior da comunidade, o Lazarus pode se tornar um “Delphi 3” no futuro, o que em si já seria ótimo. Eu comecei no Delphi 3 e, me lembro bem, era TOP.

Um problema que eu vejo no Lazarus é que toda documentação só lista alguns bancos de dados. Ele tem suporte a ADO ou ODBC direto também? Se tiver, já começa a valer a pena pensar em trabalhar com ele. Se não… bem, desista, porque você vai estar na mão de quem for implementar drivers específicos pro Lazarus pra você.

F

Credo por quê? Tem algum argumento técnico?

Sim tive diversos problemas com lazarus, ja faz um tempao nem quero argumentar e lembrar sobre isso, foram os piores momentos da minha vida rsrs

M

Pelo que andei pesquisando, o Lazarus já possui suporte nativo à vários bancos, como Oracle, Portgres, MySQL, SQL Server, SQLite etc. Basta adicionar o uses ODBCConn ao seu código.

X

matheuslmota:

O fato de o Delphi (ou Object Pascal, chame como quiser) não ser uma linguagem gerenciada não encaro como um problema, é uma característica da linguagem, assim como o C++ e o C possuem, que também têm essa características. Além do mais, também não é certo do ponto de vista das boas práticas usar objetos compartilhados.

EDIT:
Complementando o que eu disse, esse negocio de objetos compartilhados parece aquele padrão Singleton, que eu acho horroroso. Uma instância de um objeto para ser referenciada em vários lugar, posso está errado, mas nem parece OO, parece quase uma tentativa de programar de maneira procedual dentro do OO. Como eu disse, é minha opinião e posso está errado.
Agora voltando ao tópico, mais alguém usa o Lazarus atualmente? Até agora a única pessoa que de fato usa a versão mais atual do Lazarus é o julicbq. Os outros, usaram somente versões antigas (4 anos para um projeto que sofre alterações diárias é uma eternidade).

Não tem nada haver com o padrão singleton. O que eu falei é passar um objeto como referencia para outro tipo "ObjetoA.Create(ObjetoB)"
Se você destruir o ObjetoB o ObjetoA a referencia que o ObjetoA faz para ele estará perdida e quando be chamar algum procedimento do ObjetoB vai levandar uma exceção de “Access violation”.

PS: Singleton é muito bom e só saber usar, como para factorys e objtetos de configuração.

M

x@ndy:
matheuslmota:

O fato de o Delphi (ou Object Pascal, chame como quiser) não ser uma linguagem gerenciada não encaro como um problema, é uma característica da linguagem, assim como o C++ e o C possuem, que também têm essa características. Além do mais, também não é certo do ponto de vista das boas práticas usar objetos compartilhados.

EDIT:
Complementando o que eu disse, esse negocio de objetos compartilhados parece aquele padrão Singleton, que eu acho horroroso. Uma instância de um objeto para ser referenciada em vários lugar, posso está errado, mas nem parece OO, parece quase uma tentativa de programar de maneira procedual dentro do OO. Como eu disse, é minha opinião e posso está errado.
Agora voltando ao tópico, mais alguém usa o Lazarus atualmente? Até agora a única pessoa que de fato usa a versão mais atual do Lazarus é o julicbq. Os outros, usaram somente versões antigas (4 anos para um projeto que sofre alterações diárias é uma eternidade).

Não tem nada haver com o padrão singleton. O que eu falei é passar um objeto como referencia para outro tipo "ObjetoA.Create(ObjetoB)"
Se você destruir o ObjetoB o ObjetoA a referencia que o ObjetoA faz para ele estará perdida e quando be chamar algum procedimento do ObjetoB vai levandar uma exceção de “Access violation”.

PS: Singleton é muito bom e só saber usar, como para factorys e objtetos de configuração.

Mas esse problema não é coisa do Delphi, é problema das linguagens não gerenciadas e cabe ao programador avaliar se uma referência aponta para um lugar válido ou criar mecanismos que impessam a aplicação desalocar um objeto compartilhado. Não vejo onde o Delphi pode ser a causa do problema.

J

x@ndy:
matheuslmota:
x@ndy:
matheuslmota:
Caros, atualmente trabalho dando manutenção em um sistema legado em Delphi. Procurando por uma ferramenta Open Source para programar em Object Pascal, encontrei a IDE Lazarus. Então, tenho algumas perguntas a fazer:

  1. Como está o projeto atualmente?
  2. Ela pode substituir o Delphi 7 (as versões posteriores ao Delphi 7 são meio bugadas)
  3. Pode-se desenvolver uma aplicação comercial somente usando o Lazarus, ele dá conta do recado?
  4. Ouvi dizer que o debug dele é lento. Isso procede?
  5. Existe refactor no Lazarus?
  6. Em comparação ao Delphi, é muito difícil desenvolver componentes para o Lazarus?

[]'s


Como desenvolvedor delphi tentei usar um tempo o lazarus e desisti.
Essa estória de que as versões mais novas são bugadas é lenda. A única versão horrível de trabalhar era a 2005 porém a partir do 2006 é tranquilo.
Mas como você só vai fazer uma manutenção não vejo necessidade de compra de uma licença, da para ir de Lazarus mesmo. Agora no dia a dia, não tem como trabalhar.
(Isso é uma opnião pessoal).

Mas o que foi que você viu de negativo no Lazarus?

Na época em que testei era extremamente lento, gerava um executável gigante(embora tenha como corrigir), a IDE e o refactoring eram horríveis e cheia de bugs e instalar um componente delphi era um parto.
Essa foi a experiencia que eu tive e já faz alguns anos hoje em dia não sei se melhorou ou não!

O executável ainda é gigante se você não estripar as informações de debug do mesmo. Existe uma opção no compilador, ou mesmo você pode usar a ferramenta strip.exe para fazer isso.

Já trabalhei muitos anos com delphi, e na minha opinião as melhores ides foram as de código nativo(até o 7). Quando o .net entrou em cena ficou tão ruim de usar a ferramente que eu fui obrigado a portar meu trabalho para java(sem nenhum arrependimento nem dor de cabeça).

J

kicolobo:
Testei o Lazarus uns 4 anos atrás e, naquela época, achei ele MUITO fraquinho comparado com o Delphi 7. Além disto, era também bem bugado. Travava o tempo inteiro.

O papo de que as versões do Delphi posteriores á 7 ser bugado é um mito. Um maldito mito que basicamente destruiu a Borland. Há uma versão bugada e horrível do Delphi, e esta se chama 8 (Octane). O maior erro da história da empresa.

Recentemente brinquei com o Delphi 2010 e achei MUITO legal. Fiquei uns 5 anos longe do Delphi e quando o reencontrei, foi uma surpresa maravilhosa. Sei lá: acho que se é para dar suporte à plataforma, compensa muito comprar o Delphi. Inclusive, a versão XE te permite acesso às versões anteriores (incluindo a 7) gratuitamente.

Compensa também comprar por outra razão: dar o suporte financeiro para que continuem o desenvolvimento da ferramenta que, apesar de ter perdido muito mercado, ainda é uma ferramenta foda.

Mito não é não. Apesar de eu ter usado apenas a 2005 e 2006 posteriores ao 7, são bugadas, da mesma forma que o c++ builder nas mesmas versões. O erro da borland foi o dot net no início de carreira, que afetou o desempenho da ide de maneira fatal.

M

Julio,
Uma coisa que me chamou atenção no Lazarus foi uma integração com o qt. Dá pra desenvolver bem pascal com qt usando o Lazarus?

J

marcosalex:
Também não gostei do Lazarus, parece o Delphi de 15 anos atrás.

E o suporte a MMX, o Delphi possui, mas é o compilador que cuida disso, enquanto o Lazarus a gente programa explicitamente. Pra mim, uma vantagem do Lazarus.

Os componentes novos e os recursos novos da IDE do Delphi não estão presentes no Lazarus. Delphi evoluiu muito, principalmente da versão 2007 em diante.

Isso é verdade. O suporte a instruções mmx apareceram no delphi 2007. Mas em termos de compilador o free pascal na minha opinião tem muitas vantagens ao delphi, principalmente no quesito multiplataforma.

M

matheuslmota:
Julio,
Uma coisa que me chamou atenção no Lazarus foi uma integração com o qt. Dá pra desenvolver bem pascal com qt usando o Lazarus?

Você consegue falar pro compilador gerar os widgets usando Qt ou usando gtk. Basta configurar o parâmetro que o código gerado muda completamente, de forma totalmente transparente pra você.

Claaaaro que como os widgets são diferentes, pode ser que um botão fique um pouco maior ou menor e estrague seu layout, mas daí basta um ajuste manual, da mesma forma que acontece com o swt no Java.

Sobre a linguagem OO do Delphi, também gosto muito e muita coisa que o pessoal conta como vantagem no Java e .NET, o Delphi já tinha. A única coisa que não gosto da sintaxe dele, é que pra implementar uma interface, você é obrigado a usar uma herança.

J

matheuslmota:
Julio,
Uma coisa que me chamou atenção no Lazarus foi uma integração com o qt. Dá pra desenvolver bem pascal com qt usando o Lazarus?

Tem um projeto para isso, mas nesse ponto não sei te dizer se é estável. Com lazarus posso te dizer que não terá problemas para desenvolver software, embora eu tenha que concordar com o pessoal em que as ferramentas do delphi são mais maduras e realmente melhores. Mas se for criar software multiplataforma o lazarus é uma boa opção.

M

juliocbq:
O executável ainda é gigante se você não estripar as informações de debug do mesmo. Existe uma opção no compilador, ou mesmo você pode usar a ferramenta strip.exe para fazer isso.

Já trabalhei muitos anos com delphi, e na minha opinião as melhores ides foram as de código nativo(até o 7). Quando o .net entrou em cena ficou tão ruim de usar a ferramente que eu fui obrigado a portar meu trabalho para java(sem nenhum arrependimento nem dor de cabeça).

Concordo. Eu gosto muito do Delphi por causa da facilidade em se chamar funções nativas e também por causa da possibilidade de usar Assembly inline. Mas com a entrada do .net no Delphi deixou a IDE bastante bugada, tanto que todos os densenvolvedores Delphi que eu conheço usam somente a versão 7 do Delphi.

Uma outra dúvida: dá pra chamar funções nativas no Lazarus?

J

x@ndy:
matheuslmota:
kicolobo:
Testei o Lazarus uns 4 anos atrás e, naquela época, achei ele MUITO fraquinho comparado com o Delphi 7. Além disto, era também bem bugado. Travava o tempo inteiro.

O papo de que as versões do Delphi posteriores á 7 ser bugado é um mito. Um maldito mito que basicamente destruiu a Borland. Há uma versão bugada e horrível do Delphi, e esta se chama 8 (Octane). O maior erro da história da empresa.

Recentemente brinquei com o Delphi 2010 e achei MUITO legal. Fiquei uns 5 anos longe do Delphi e quando o reencontrei, foi uma surpresa maravilhosa. Sei lá: acho que se é para dar suporte à plataforma, compensa muito comprar o Delphi. Inclusive, a versão XE te permite acesso às versões anteriores (incluindo a 7) gratuitamente.

Compensa também comprar por outra razão: dar o suporte financeiro para que continuem o desenvolvimento da ferramenta que, apesar de ter perdido muito mercado, ainda é uma ferramenta foda.

eu gosto muito mesmo do Delphi. De todas as ferramentas que já usei (eclipse, netbean, visual studio, codeblocks e outras que não lembro agora), o delphi foi certamente a melhor. Produtividade total, debug excelente, bom nível de otimização dos executáveis, alta facilidade para integrar a aplicação com banco de dados, o editor de interface gráfica dá uma surra nos disponíveis para o Java, sem falar que gera um código muito mais limpo. Talvez o Delphi só perca (em termos de produtivade) para o Visual Studio 2010. Mas como eu disse, tava atrás de uma ferramenta open source e multiplataforma e achei o Lazarus. Me pareceu uma opção interessante, possuindo inclusíve, suporte ao qt. Mas como eu não conheço a ferramenta, vim pedir a opinião dos colegas mais experientes. Será que esse suporte ao qt funciona bem mesmo?

Realmente a IDE do delphi é ainda superior ao Eclipse, Netbeans e Cia.
Tenho um único porém ao seu comentário "alta facilidade para integrar a aplicação com banco de dados, o editor de interface gráfica dá uma surra nos disponíveis para o Java,"
O delphi é extremamente produtivo para desenvolver no padrão de Interface Inteligente. O modelo Dataware do delphi é maravilhoso para isso, porém se você vai querer desenvolver OO no delphi ele se torna um inferno. Nisso o java é nota 10.
Para quem tenta fazer uma aplicação OO em delphi o primeiro problema é questão das referencias entre os objetos. No pascal, como não existe garbage colector, você cria um objeto é obrigado a destrui-lo. Isso se torna um problema quando esse objeto é compartilhado. Aqui até tem uma solução para isso, mas não é nada elegante.

Como qualquer linguagem sem coletor de lixo e que suporta apontadores, você pode implementar um smart pointer. Funciona como um coletor de lixo automático.

http://www.swissdelphicenter.ch/torry/printcode.php?id=2192

X

juliocbq:
x@ndy:
matheuslmota:
kicolobo:
Testei o Lazarus uns 4 anos atrás e, naquela época, achei ele MUITO fraquinho comparado com o Delphi 7. Além disto, era também bem bugado. Travava o tempo inteiro.

O papo de que as versões do Delphi posteriores á 7 ser bugado é um mito. Um maldito mito que basicamente destruiu a Borland. Há uma versão bugada e horrível do Delphi, e esta se chama 8 (Octane). O maior erro da história da empresa.

Recentemente brinquei com o Delphi 2010 e achei MUITO legal. Fiquei uns 5 anos longe do Delphi e quando o reencontrei, foi uma surpresa maravilhosa. Sei lá: acho que se é para dar suporte à plataforma, compensa muito comprar o Delphi. Inclusive, a versão XE te permite acesso às versões anteriores (incluindo a 7) gratuitamente.

Compensa também comprar por outra razão: dar o suporte financeiro para que continuem o desenvolvimento da ferramenta que, apesar de ter perdido muito mercado, ainda é uma ferramenta foda.

eu gosto muito mesmo do Delphi. De todas as ferramentas que já usei (eclipse, netbean, visual studio, codeblocks e outras que não lembro agora), o delphi foi certamente a melhor. Produtividade total, debug excelente, bom nível de otimização dos executáveis, alta facilidade para integrar a aplicação com banco de dados, o editor de interface gráfica dá uma surra nos disponíveis para o Java, sem falar que gera um código muito mais limpo. Talvez o Delphi só perca (em termos de produtivade) para o Visual Studio 2010. Mas como eu disse, tava atrás de uma ferramenta open source e multiplataforma e achei o Lazarus. Me pareceu uma opção interessante, possuindo inclusíve, suporte ao qt. Mas como eu não conheço a ferramenta, vim pedir a opinião dos colegas mais experientes. Será que esse suporte ao qt funciona bem mesmo?

Realmente a IDE do delphi é ainda superior ao Eclipse, Netbeans e Cia.
Tenho um único porém ao seu comentário "alta facilidade para integrar a aplicação com banco de dados, o editor de interface gráfica dá uma surra nos disponíveis para o Java,"
O delphi é extremamente produtivo para desenvolver no padrão de Interface Inteligente. O modelo Dataware do delphi é maravilhoso para isso, porém se você vai querer desenvolver OO no delphi ele se torna um inferno. Nisso o java é nota 10.
Para quem tenta fazer uma aplicação OO em delphi o primeiro problema é questão das referencias entre os objetos. No pascal, como não existe garbage colector, você cria um objeto é obrigado a destrui-lo. Isso se torna um problema quando esse objeto é compartilhado. Aqui até tem uma solução para isso, mas não é nada elegante.

Como qualquer linguagem sem coletor de lixo e que suporta apontadores, você pode implementar um smart pointer. Funciona como um coletor de lixo automático.

http://www.swissdelphicenter.ch/torry/printcode.php?id=2192

Não conhecia o “smart pointer”, ótima referência, mas achei horrível a forma de utilização, mas é valido quando não se pode usar a contagem de referencia como havia colocado no link acima!

Adoro o delphi justamente por ele mascarar muito bem o uso de ponteiros. Ter que fazer uso deles com um smart pointer só mostra como java é melhor para programar usando OO.

Isso não é um ode ao java até pq adoro o delphi e pascal, mas a falta de da contagem de referencia em TObject, a meu ver, limita muito sua utilização em sistemas OO.

Já havia colocado antes, mas não custa repetir, para quem saber sobre contagem de referencia com o delphi segue o link abaixo
http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html]Aqui até tem uma solução para isso, mas não é nada elegante[/url]

M

x@ndy:
juliocbq:
x@ndy:
matheuslmota:
kicolobo:
Testei o Lazarus uns 4 anos atrás e, naquela época, achei ele MUITO fraquinho comparado com o Delphi 7. Além disto, era também bem bugado. Travava o tempo inteiro.

O papo de que as versões do Delphi posteriores á 7 ser bugado é um mito. Um maldito mito que basicamente destruiu a Borland. Há uma versão bugada e horrível do Delphi, e esta se chama 8 (Octane). O maior erro da história da empresa.

Recentemente brinquei com o Delphi 2010 e achei MUITO legal. Fiquei uns 5 anos longe do Delphi e quando o reencontrei, foi uma surpresa maravilhosa. Sei lá: acho que se é para dar suporte à plataforma, compensa muito comprar o Delphi. Inclusive, a versão XE te permite acesso às versões anteriores (incluindo a 7) gratuitamente.

Compensa também comprar por outra razão: dar o suporte financeiro para que continuem o desenvolvimento da ferramenta que, apesar de ter perdido muito mercado, ainda é uma ferramenta foda.

eu gosto muito mesmo do Delphi. De todas as ferramentas que já usei (eclipse, netbean, visual studio, codeblocks e outras que não lembro agora), o delphi foi certamente a melhor. Produtividade total, debug excelente, bom nível de otimização dos executáveis, alta facilidade para integrar a aplicação com banco de dados, o editor de interface gráfica dá uma surra nos disponíveis para o Java, sem falar que gera um código muito mais limpo. Talvez o Delphi só perca (em termos de produtivade) para o Visual Studio 2010. Mas como eu disse, tava atrás de uma ferramenta open source e multiplataforma e achei o Lazarus. Me pareceu uma opção interessante, possuindo inclusíve, suporte ao qt. Mas como eu não conheço a ferramenta, vim pedir a opinião dos colegas mais experientes. Será que esse suporte ao qt funciona bem mesmo?

Realmente a IDE do delphi é ainda superior ao Eclipse, Netbeans e Cia.
Tenho um único porém ao seu comentário "alta facilidade para integrar a aplicação com banco de dados, o editor de interface gráfica dá uma surra nos disponíveis para o Java,"
O delphi é extremamente produtivo para desenvolver no padrão de Interface Inteligente. O modelo Dataware do delphi é maravilhoso para isso, porém se você vai querer desenvolver OO no delphi ele se torna um inferno. Nisso o java é nota 10.
Para quem tenta fazer uma aplicação OO em delphi o primeiro problema é questão das referencias entre os objetos. No pascal, como não existe garbage colector, você cria um objeto é obrigado a destrui-lo. Isso se torna um problema quando esse objeto é compartilhado. Aqui até tem uma solução para isso, mas não é nada elegante.

Como qualquer linguagem sem coletor de lixo e que suporta apontadores, você pode implementar um smart pointer. Funciona como um coletor de lixo automático.

http://www.swissdelphicenter.ch/torry/printcode.php?id=2192

Não conhecia o “smart pointer”, ótima referência, mas achei horrível a forma de utilização, mas é valido quando não se pode usar a contagem de referencia como havia colocado no link acima!

Adoro o delphi justamente por ele mascarar muito bem o uso de ponteiros. Ter que fazer uso deles com um smart pointer só mostra como java é melhor para programar usando OO.

Isso não é um ode ao java até pq adoro o delphi e pascal, mas a falta de da contagem de referencia em TObject, a meu ver, limita muito sua utilização em sistemas OO.

Alguma linguagem não gerenciada OO possui contador de referência?

X

juliocbq:
kicolobo:
Testei o Lazarus uns 4 anos atrás e, naquela época, achei ele MUITO fraquinho comparado com o Delphi 7. Além disto, era também bem bugado. Travava o tempo inteiro.

O papo de que as versões do Delphi posteriores á 7 ser bugado é um mito. Um maldito mito que basicamente destruiu a Borland. Há uma versão bugada e horrível do Delphi, e esta se chama 8 (Octane). O maior erro da história da empresa.

Recentemente brinquei com o Delphi 2010 e achei MUITO legal. Fiquei uns 5 anos longe do Delphi e quando o reencontrei, foi uma surpresa maravilhosa. Sei lá: acho que se é para dar suporte à plataforma, compensa muito comprar o Delphi. Inclusive, a versão XE te permite acesso às versões anteriores (incluindo a 7) gratuitamente.

Compensa também comprar por outra razão: dar o suporte financeiro para que continuem o desenvolvimento da ferramenta que, apesar de ter perdido muito mercado, ainda é uma ferramenta foda.

Mito não é não. Apesar de eu ter usado apenas a 2005 e 2006 posteriores ao 7, são bugadas, da mesma forma que o c++ builder nas mesmas versões. O erro da borland foi o dot net no início de carreira, que afetou o desempenho da ide de maneira fatal.

Cara, uso o 2006 até hoje (Win32) e não tenho problemas. A IDE tem alguns bugs, mas é raro dar algum problema (lembrando que o eclipse tb tem alguns bugs), o 2005 sim era horrível, e realmente o .net foi tiro no pé, tanto que foi abandonada a partir do delphi 2007

O fato da maioria das pessoas usarem delphi 7 pelo que sei é devido ao uso de componentes legados sem codigo fonte. Isso é a maior dor de cabeça.

Digo isso pq trabalho com delphi até hoje. Hoje mesmo estou usando trabalhando com ele.

J

x@ndy:
juliocbq:
x@ndy:
matheuslmota:
kicolobo:
Testei o Lazarus uns 4 anos atrás e, naquela época, achei ele MUITO fraquinho comparado com o Delphi 7. Além disto, era também bem bugado. Travava o tempo inteiro.

O papo de que as versões do Delphi posteriores á 7 ser bugado é um mito. Um maldito mito que basicamente destruiu a Borland. Há uma versão bugada e horrível do Delphi, e esta se chama 8 (Octane). O maior erro da história da empresa.

Recentemente brinquei com o Delphi 2010 e achei MUITO legal. Fiquei uns 5 anos longe do Delphi e quando o reencontrei, foi uma surpresa maravilhosa. Sei lá: acho que se é para dar suporte à plataforma, compensa muito comprar o Delphi. Inclusive, a versão XE te permite acesso às versões anteriores (incluindo a 7) gratuitamente.

Compensa também comprar por outra razão: dar o suporte financeiro para que continuem o desenvolvimento da ferramenta que, apesar de ter perdido muito mercado, ainda é uma ferramenta foda.

eu gosto muito mesmo do Delphi. De todas as ferramentas que já usei (eclipse, netbean, visual studio, codeblocks e outras que não lembro agora), o delphi foi certamente a melhor. Produtividade total, debug excelente, bom nível de otimização dos executáveis, alta facilidade para integrar a aplicação com banco de dados, o editor de interface gráfica dá uma surra nos disponíveis para o Java, sem falar que gera um código muito mais limpo. Talvez o Delphi só perca (em termos de produtivade) para o Visual Studio 2010. Mas como eu disse, tava atrás de uma ferramenta open source e multiplataforma e achei o Lazarus. Me pareceu uma opção interessante, possuindo inclusíve, suporte ao qt. Mas como eu não conheço a ferramenta, vim pedir a opinião dos colegas mais experientes. Será que esse suporte ao qt funciona bem mesmo?

Realmente a IDE do delphi é ainda superior ao Eclipse, Netbeans e Cia.
Tenho um único porém ao seu comentário "alta facilidade para integrar a aplicação com banco de dados, o editor de interface gráfica dá uma surra nos disponíveis para o Java,"
O delphi é extremamente produtivo para desenvolver no padrão de Interface Inteligente. O modelo Dataware do delphi é maravilhoso para isso, porém se você vai querer desenvolver OO no delphi ele se torna um inferno. Nisso o java é nota 10.
Para quem tenta fazer uma aplicação OO em delphi o primeiro problema é questão das referencias entre os objetos. No pascal, como não existe garbage colector, você cria um objeto é obrigado a destrui-lo. Isso se torna um problema quando esse objeto é compartilhado. Aqui até tem uma solução para isso, mas não é nada elegante.

Como qualquer linguagem sem coletor de lixo e que suporta apontadores, você pode implementar um smart pointer. Funciona como um coletor de lixo automático.

http://www.swissdelphicenter.ch/torry/printcode.php?id=2192

Não conhecia o “smart pointer”, ótima referência, mas achei horrível a forma de utilização, mas é valido quando não se pode usar a contagem de referencia como havia colocado no link acima!

Adoro o delphi justamente por ele mascarar muito bem o uso de ponteiros. Ter que fazer uso deles com um smart pointer só mostra como java é melhor para programar usando OO.

Isso não é um ode ao java até pq adoro o delphi e pascal, mas a falta de da contagem de referencia em TObject, a meu ver, limita muito sua utilização em sistemas OO.

Já havia colocado antes, mas não custa repetir, para quem saber sobre contagem de referencia com o delphi segue o link abaixo
http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html]Aqui até tem uma solução para isso, mas não é nada elegante[/url]

Depende do ponto de vista. Em alguns casos o uso de apontadores é importante, justamente para se pode gerenciar a memória de uma maneira mais clara. Um exemplo são justamente os smart pointers e o seu irmão mais complexo, o garbage colector.

Um ótimo exemplo também é o impliciti sharing do framework qt: Os componentes compartilham memória e isso minimiza o custo da cópia(deep copy), aumentando o desempenho da aplicação. Já que ao invés do conteúdo da área de memória, apenas o endereço é copiado.

http://doc.qt.nokia.com/4.7-snapshot/implicit-sharing.html

Todos eles não modelos de otimização e gerenciamento de memória


http://dlugosz.com/Repertoire/refman/Classics/Smart%20Pointers%20Overview.html

X

matheuslmota:

Alguma linguagem não gerenciada OO possui contador de referência?

Bah, otima pergunta! Alguem conhece?
Bem que a Embarcadero podia implementar isso nativamente no delphi, ia ser uma mão na roda.

J

x@ndy:
juliocbq:

Mito não é não. Apesar de eu ter usado apenas a 2005 e 2006 posteriores ao 7, são bugadas, da mesma forma que o c++ builder nas mesmas versões. O erro da borland foi o dot net no início de carreira, que afetou o desempenho da ide de maneira fatal.

Cara, uso o 2006 até hoje (Win32) e não tenho problemas. A IDE tem alguns bugs, mas é raro dar algum problema (lembrando que o eclipse tb tem alguns bugs), o 2005 sim era horrível, e realmente o .net foi tiro no pé, tanto que foi abandonada a partir do delphi 2007

O fato da maioria das pessoas usarem delphi 7 pelo que sei é devido ao uso de componentes legados sem codigo fonte. Isso é a maior dor de cabeça.

Digo isso pq trabalho com delphi até hoje. Hoje mesmo estou usando trabalhando com ele.

Não tenho como opinar sobre as novas versões do delphi. Há tempos que não trabalho com ele, então minha opinião até pode ser dita como desatualizada.
Na época, as versões dotnet deram muita dor de cabeça, inclusive para compilar programas com o c++ builder.

O lazarus é uma boa ferramenta e pode ser utilizada sem problemas, e ainda aposto no freepascal como gerador de código mais enxuto que o bdc32.exe. Lembrando, comparando com as versões que eu já trabalhei(3,5,6,7, 2005 e 2006).

X

juliocbq:

Depende do ponto de vista. Em alguns casos o uso de apontadores é importante, justamente para se pode gerenciar a memória de uma maneira mais clara. Um exemplo são justamente os smart pointers e o seu irmão mais complexo, o garbage colector.

Um ótimo exemplo também é o impliciti sharing do framework qt: Os componentes compartilham memória e isso minimiza o custo da cópia(deep copy), aumentando o desempenho da aplicação. Já que ao invés do conteúdo da área de memória, apenas o endereço é copiado.

http://doc.qt.nokia.com/4.7-snapshot/implicit-sharing.html

Todos eles não modelos de otimização e gerenciamento de memória


http://dlugosz.com/Repertoire/refman/Classics/Smart%20Pointers%20Overview.html

Com certeza o uso de ponteiros tem seu lugar. Mas eu pessoalmente não gosto de usar. Faço uso somente quando necessário.

O engraçodo sobre isso é q esses tempos fui implementar uma arvore binária balanceada em java para um trabalho da facul e vi que ela éra muito mais fácil de ser implementada usando C e ponteiros :D!

J

x@ndy:
matheuslmota:

Alguma linguagem não gerenciada OO possui contador de referência?

Bah, otima pergunta! Alguem conhece?
Bem que a Embarcadero podia implementar isso nativamente no delphi, ia ser uma mão na roda.

olha o link que postei acima. O framework qt usa isso. Contadores de referência são implementados em frameworks, não são atributos de linguagens.

M

x@ndy:
Com certeza o uso de ponteiros tem seu lugar. Mas eu pessoalmente não gosto de usar. Faço uso somente quando necessário.
O engraçodo sobre isso é q esses tempos fui implementar uma arvore binária balanceada em java para um trabalho da facul e vi que ela éra muito mais fácil de ser implementada usando C e ponteiros :D!

Eu também já me encontrei em situações, no Java, em que eu implementaria uma algoritmo muito mais facilmente se a linguagem tivesse ponteiro (obviamente eu sei que uma linguagem gerenciada não pode ter ponteiros).
Bem que o Delphi e o C++ poderiam implementar nativamente Smart Pointers, iria ser uma senhora ajuda.

X

juliocbq:
x@ndy:
juliocbq:

Mito não é não. Apesar de eu ter usado apenas a 2005 e 2006 posteriores ao 7, são bugadas, da mesma forma que o c++ builder nas mesmas versões. O erro da borland foi o dot net no início de carreira, que afetou o desempenho da ide de maneira fatal.

Cara, uso o 2006 até hoje (Win32) e não tenho problemas. A IDE tem alguns bugs, mas é raro dar algum problema (lembrando que o eclipse tb tem alguns bugs), o 2005 sim era horrível, e realmente o .net foi tiro no pé, tanto que foi abandonada a partir do delphi 2007

O fato da maioria das pessoas usarem delphi 7 pelo que sei é devido ao uso de componentes legados sem codigo fonte. Isso é a maior dor de cabeça.

Digo isso pq trabalho com delphi até hoje. Hoje mesmo estou usando trabalhando com ele.

Não tenho como opinar sobre as novas versões do delphi. Há tempos que não trabalho com ele, então minha opinião até pode ser dita como desatualizada.
Na época, as versões dotnet deram muita dor de cabeça, inclusive para compilar programas com o c++ builder.

O lazarus é uma boa ferramenta e pode ser utilizada sem problemas, e ainda aposto no freepascal como gerador de código mais enxuto que o bdc32.exe. Lembrando, comparando com as versões que eu já trabalhei(3,5,6,7, 2005 e 2006).

Isso me faz lembrar que no em algum lugar do blog do joão morais ele fala de algumas IDEs para freepascal. Quem tiver interesse de procurar
http://blog.joaomorais.com.br/

G

trabalho com Delphi a ums 15 anos.

atualmente estou trabalhando com Lazarus por ser open e multi-plataforma.

tive um rapido contato com ele a ums 5 anos atraz e julguei estar ainda mt "zigoto".

mas hoje, acho q dizer q o lazarus é inferior a um Delphi3 é não saber o q fala.

pra falar a verdade o lazarus coloca o Delhi2007 pra traz em mts quisitos.

a grande vantagem q acho nele é q ele melhora a acada dia literalmente.

e temos q derrubar alguns MITOS.

executaveis grandes: mentira. (provar?) desmarque a opção "gerar informação de depuração";
o exe de 13 mb cai pra 1.5 mb;
ah no delphi ele seria 400 kb. (mas com API até no talo);

lento pra compilar; (mentira) desmarque a opção "sempre contruir tudo";

essa é do pascal;
não permite referencia circular. mentira; (a verdade é q tem gente q não conhece o pascal)

type
  ClasseB = class;

  ClasseA = class
  strict private
    B1 : ClasseB;
    B2 : ClasseB;
  end;

  ClasseB = class
  strict private
    A1, A2, A3 : ClasseA;
  end;

isso é referencia circular não?

G

x@ndy:
matheuslmota:

O fato de o Delphi (ou Object Pascal, chame como quiser) não ser uma linguagem gerenciada não encaro como um problema, é uma característica da linguagem, assim como o C++ e o C possuem, que também têm essa características. Além do mais, também não é certo do ponto de vista das boas práticas usar objetos compartilhados.

EDIT:
Complementando o que eu disse, esse negocio de objetos compartilhados parece aquele padrão Singleton, que eu acho horroroso. Uma instância de um objeto para ser referenciada em vários lugar, posso está errado, mas nem parece OO, parece quase uma tentativa de programar de maneira procedual dentro do OO. Como eu disse, é minha opinião e posso está errado.
Agora voltando ao tópico, mais alguém usa o Lazarus atualmente? Até agora a única pessoa que de fato usa a versão mais atual do Lazarus é o julicbq. Os outros, usaram somente versões antigas (4 anos para um projeto que sofre alterações diárias é uma eternidade).

Não tem nada haver com o padrão singleton. O que eu falei é passar um objeto como referencia para outro tipo "ObjetoA.Create(ObjetoB)"
Se você destruir o ObjetoB o ObjetoA a referencia que o ObjetoA faz para ele estará perdida e quando be chamar algum procedimento do ObjetoB vai levandar uma exceção de “Access violation”.

PS: Singleton é muito bom e só saber usar, como para factorys e objtetos de configuração.

quem sabe usar pascal não tem problema com isso.

primeiro. no maioria das vezes seria feito um Assign.
Exite tb o

TComponent .... procedure Notification(AComponent: TComponent; Operation: TOperation); virtual;

q avisaria q fulano está sendo destruido.

td vc cria vc tem q destruir.
Pesquise sobre o parametro AOwner passado nos construtores.

X

GilsonNunes:
x@ndy:
matheuslmota:

O fato de o Delphi (ou Object Pascal, chame como quiser) não ser uma linguagem gerenciada não encaro como um problema, é uma característica da linguagem, assim como o C++ e o C possuem, que também têm essa características. Além do mais, também não é certo do ponto de vista das boas práticas usar objetos compartilhados.

EDIT:
Complementando o que eu disse, esse negocio de objetos compartilhados parece aquele padrão Singleton, que eu acho horroroso. Uma instância de um objeto para ser referenciada em vários lugar, posso está errado, mas nem parece OO, parece quase uma tentativa de programar de maneira procedual dentro do OO. Como eu disse, é minha opinião e posso está errado.
Agora voltando ao tópico, mais alguém usa o Lazarus atualmente? Até agora a única pessoa que de fato usa a versão mais atual do Lazarus é o julicbq. Os outros, usaram somente versões antigas (4 anos para um projeto que sofre alterações diárias é uma eternidade).

Não tem nada haver com o padrão singleton. O que eu falei é passar um objeto como referencia para outro tipo "ObjetoA.Create(ObjetoB)"
Se você destruir o ObjetoB o ObjetoA a referencia que o ObjetoA faz para ele estará perdida e quando be chamar algum procedimento do ObjetoB vai levandar uma exceção de “Access violation”.

PS: Singleton é muito bom e só saber usar, como para factorys e objtetos de configuração.

quem sabe usar pascal não tem problema com isso.

primeiro. no maioria das vezes seria feito um Assign.
Exite tb o

TComponent .... procedure Notification(AComponent: TComponent; Operation: TOperation); virtual;

q avisaria q fulano está sendo destruido.

Nesse caso, você está errado. Não tenho os 15 anos de experiência, mas tenho 10 o que me permite dizer isso.

  1. Assign deve ser implementado em todas as classes! Seria como fazer uma copia do mesmo e estamos falando de referência e não cópia do mesmo. Já tentou fazer um Assign de um TButton por exemplo? É gerado uma exeção pois o TButton não implementa a função Assign, mesmo herdando de TPersistent.

  2. Gerar um evento para notificar que um objeto está sendo destruído também não resolve o problema, pois o evento agiria sobre o objeto em si e não sobre o objeto que contém a referencia. Isso só poderia ser utilizado implementando o padrão observer, de modo que a classe que contém a referência fosse notificada sobre quando esse objeto fosse destruído, mas ai fica mais simples utilizar a contagem de referencia.

  3. Usar Owner também não resolve, pois estou passando a responsabilidade de destruição para o objeto proprietário desse objeto e se seguirmos assim o proprietário final será a a própria aplicação. Isso forçaria a liberação da memória somente quando a aplicação fosse encerrada.

Não sei qual a sua experiência em objetos com delphi, mas a minha me diz que não usar contagem de referencia torna a utilização de objetos bem dificil, principalmente em aplicações complexas.

G

eu disse na maioria das vezes. lembra?

vc está enganado e não conhece a estrutura da VCL/LCL.

veja esse trecho da VCL:

procedure TControl.Notification(AComponent: TComponent; Operation: TOperation); begin inherited Notification(AComponent, Operation); if Operation = opRemove then begin if AComponent = PopupMenu then PopupMenu := nil else if AComponent = Action then Action := nil else if AComponent = FHostDockSite then FHostDockSite := nil; end; end;

vc vai perceber q quem recebe a notificação é o objeto q tem a referencia e não o objeto referenciado.

concordo q 99% dos programadores pascal não sabem disso.

ou seja. se seu objeto ta fazendo referencia a um q foi destruido é pq ele foi mal implementado.

X
GilsonNunes:
trabalho com Delphi a ums 15 anos.

atualmente estou trabalhando com Lazarus por ser open e multi-plataforma.

tive um rapido contato com ele a ums 5 anos atraz e julguei estar ainda mt "zigoto".

mas hoje, acho q dizer q o lazarus é inferior a um Delphi3 é não saber o q fala.

pra falar a verdade o lazarus coloca o Delhi2007 pra traz em mts quisitos.

a grande vantagem q acho nele é q ele melhora a acada dia literalmente.

e temos q derrubar alguns MITOS.

executaveis grandes: mentira. (provar?) desmarque a opção "gerar informação de depuração";
o exe de 13 mb cai pra 1.5 mb;
ah no delphi ele seria 400 kb. (mas com API até no talo);

lento pra compilar; (mentira) desmarque a opção "sempre contruir tudo";

essa é do pascal;
não permite referencia circular. mentira; (a verdade é q tem gente q não conhece o pascal)

type
  ClasseB = class;

  ClasseA = class
  strict private
    B1 : ClasseB;
    B2 : ClasseB;
  end;

  ClasseB = class
  strict private
    A1, A2, A3 : ClasseA;
  end;

isso é referencia circular não?

Faz muito tempo que não uso o Lazarus, então não posso dizer se ele é melhor que o Delphi 2007, porém como disse antes, a minha experiência inicial não foi nada agradável.

Com relação a referencia circular, você está certo, mas creio que o que ele quis dizer é a referência circular quando as classe estão em Units diferentes, o que não é permitido!

Eu pessoalmente já utilizei o método que você citou para driblar isso mas pessoalmente eu não gosto pois mistura na mesma unit diversas classes diferentes e muitas vezes com responsabilidades diferentes. Nesse sentido a forma utilizada pelo java é melhor, pois permite que as classes sejam separadas.

X
GilsonNunes:
1) Assign deve ser implementado em todas as classes! Seria como fazer uma copia do mesmo e estamos falando de referência e não cópia do mesmo. Já tentou fazer um Assign de um TButton por exemplo? É gerado uma exeção pois o TButton não implementa a função Assign, mesmo herdando de TPersistent.

eu disse na maioria das vezes. lembra?

Gerar um evento para notificar que um objeto está sendo destruído também não resolve o problema, pois o evento agiria sobre o objeto em si e não sobre o objeto que contém a referencia.

vc está enganado e não conhece a estrutura da VCL/LCL.

veja esse trecho da VCL:
procedure TControl.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if Operation = opRemove then
  begin
    if AComponent = PopupMenu then
      PopupMenu := nil
    else if AComponent = Action then
      Action := nil
    else if AComponent = FHostDockSite then
      FHostDockSite := nil;
  end;
end;

vc vai perceber q quem recebe a notificação é o objeto q tem a referencia e não o objeto referenciado.

concordo q 99% dos programadores pascal não sabem disso.

ou seja. se seu objeto ta fazendo referencia a um q foi destruido é pq ele foi mal implementado.

Realmente eu não conheço a estrutura da LCL Gilosn, mas da VCL, pelo jeito, eu conheço mais que você.

O Evento Notification da classe de TComponent é chamado quando eu Chamo o Método TComponent.InsertComponent ou TComponent.RemoveComponent e não quando um componente é detruido.
Pessoalmente eu não sei qual a sua experiência com objetos, mas pelo sua colocação creio que não seja muito grande.

procedure TComponent.InsertComponent(AComponent: TComponent);
begin
  AComponent.ValidateContainer(Self);
  if AComponent.FOwner <> nil then
    AComponent.FOwner.RemoveComponent(AComponent);
  ValidateRename(AComponent, '', AComponent.FName);
  Insert(AComponent);
  AComponent.SetReference(True);
  if csDesigning in ComponentState then
    AComponent.SetDesigning(True);
  Notification(AComponent, opInsert);
end;

..............

procedure TComponent.RemoveComponent(AComponent: TComponent);
begin
  ValidateRename(AComponent, AComponent.FName, '');
  Notification(AComponent, opRemove);
  AComponent.SetReference(False);
  Remove(AComponent);
end;
G

da pra ver q vc entende mesmo!!!

é isso q mata o pascal.

veja bem!!

vamos levar a discursão na boa igual ta indo até agora!!! blz?

vc ta confundindo Notification com RemoveComponent

veja esse trecho:
destructor TComponent.Destroy;
begin
  Destroying;
  if FFreeNotifies <> nil then
  begin
    while Assigned(FFreeNotifies) and (FFreeNotifies.Count > 0) do
      TComponent(FFreeNotifies[FFreeNotifies.Count - 1]).Notification(Self, opRemove);
    FreeAndNil(FFreeNotifies);
  end;
  DestroyComponents;
  if FOwner <> nil then FOwner.RemoveComponent(Self);
  inherited Destroy;
end;

mais necessariamente essa linha:

TComponent(FFreeNotifies[FFreeNotifies.Count - 1]).Notification(Self, opRemove);

nessa linha ai o componente q ta sendo destruido. ta avisando pra todo mundo, q tem uma referencia monitorada (twiter, rsrs) a ele, q ele será destruido.

vc pegou um trecho q usou o Notification e fez a sua tese em cima dele. Mas esse era apenas um exemplo se vc tivesse olhado com mais cuidado teria percebido logo.

techo do help da Embarcadero

Notification is called automatically when the component specified by AComponent is about to be inserted or removed, as specified by Operation. By default, components pass along the notification to their owned components, if any. A component can, if needed, act on the notification that a component is being inserted or removed. For example, if a component has object fields or properties that contain references to other components, it can check the notifications of component removals and invalidate those references as needed.

então:
não sei sua experiencia com objeto, mas pelo visto a minha é melhor q a sua.

teste isso no delphi/lazaus

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ExtCtrls;

type
  TTeste = class (TTimer)
  strict private
    FBotao : TButton;
    procedure SetBotao(const Value: TButton);
  protected
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure ExecTimer(Sender : TObject);
  public
    property Botao : TButton read FBotao write SetBotao;
  end;

  TForm1 = class(TForm)
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
  private
    FTeste : TTeste;
    procedure BtnClick(Sender: TObject);
    procedure BtnMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TTeste }

procedure TTeste.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited;
  if (Operation = opRemove) and (AComponent = FBotao) then
  begin
    FBotao := nil;

    if not (csDestroying in ComponentState) then
      ShowMessage('Botão foi removido e eu vi');
  end;
end;

procedure TTeste.SetBotao(const Value: TButton);
begin
  if FBotao <> Value then
  begin
    if Assigned(FBotao) then
      FBotao.RemoveFreeNotification(Self);

    Enabled := False;
    FBotao := Value;

    if Assigned(FBotao) then
    begin
      FBotao.FreeNotification(Self);
      OnTimer := ExecTimer;
      Enabled := True;
    end;
  end;
end;

procedure TTeste.ExecTimer;
var
  I : Integer;
  F : TCustomForm;
begin
  if Botao = nil then
    Exit;

  F := GetParentForm(Botao);
  if F = nil then
    Exit;

  if Botao.Tag and 1 = 0 then
  begin
    if Botao.Left + 10 + Botao.Width > F.ClientWidth then
    begin
      Botao.Tag := Botao.Tag or 1;
      Botao.Left := Botao.Left - 10;
    end else
      Botao.Left := Botao.Left + 10;
  end else
  begin
    if Botao.Left - 10 < 0 then
    begin
      Botao.Tag := Botao.Tag and not 1;
      Botao.Left := Botao.Left + 10;
    end else
      Botao.Left := Botao.Left - 10;
  end;

  if Botao.Tag and 2 = 0 then
  begin
    if Botao.Top + 10 + Botao.Height > F.ClientHeight then
    begin
      Botao.Tag := Botao.Tag or 2;
      Botao.Top := Botao.Top - 10;
    end else
      Botao.Top := Botao.Top + 10;
  end else
  begin
    if Botao.Top - 10 < 0 then
    begin
      Botao.Tag := Botao.Tag and not 2;
      Botao.Top := Botao.Top + 10;
    end else
      Botao.Top := Botao.Top - 10;
  end;
end;

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  FTeste := TTeste.Create(Self); //vai ser destruido qdo esse form for destruido e naõ qdo finalizar a app
  FTeste.Interval := 300;
end;

procedure TForm1.BtnClick(Sender: TObject);
begin
  Sender.Free;
end;

procedure TForm1.BtnMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbRight then
    if Sender is TButton then
      FTeste.Botao := TButton(Sender);
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbRight then
  begin
    Tag := Tag + 1;
    with TButton.Create(Self) do
    begin
      Parent := Self;
      Left := X;
      Top := Y;
      Caption := IntToStr(Self.Tag);
      OnClick := BtnClick;
      OnMouseDown := BtnMouseDown;
    end;
  end;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
  Canvas.TextOut(100, 30, 'Direito cria botao');
  Canvas.TextOut(100, 60, 'Direito sobre o botao Liga ele');
  Canvas.TextOut(100, 90, 'Esquerdo sobre o botao destroi ele');
end;

end.
X

Cara, agora entendi o que você colocou e realmente você está certo e eu não conhecia a função RemoveFreeNotification, mas vejo que você ainda mas você ainda não entendeu o que eu coloquei, e por isso falei que você não esta acostumado a trabalhar com objetos.

1)Para que isso funcione, todas as suas classes teriam que herdar de TComponent! O que eu faço com classes que não herdam de TComponent?

2)Ok, todas as minhas classes herdam de TComponent. Você ainda tem fazer:
//Isso
procedure TTeste.Notification(AComponent: TComponent; Operation: TOperation);  
begin  
  inherited; 
  if (Operation = opRemove) and (AComponent = FBotao) then  
  begin  
    FBotao := nil;  
  
    if not (csDestroying in ComponentState) then  
      ShowMessage('Botão foi removido e eu vi');  
  end;  
end;  
....
//E isso
procedure TTeste.SetBotao(const Value: TButton);  
begin  
  if FBotao <> Value then  
  begin  
    if Assigned(FBotao) then  
      FBotao.RemoveFreeNotification(Self);  
  
    Enabled := False;  
    FBotao := Value;  
  
    if Assigned(FBotao) then  
    begin  
      FBotao.FreeNotification(Self);  
      OnTimer := ExecTimer;  
      Enabled := True;  
    end;  
  end;  
end;
Essas operações são obrigatórias para todas as classes a que eu faço referencia. Então é mais fácil implementar a contagem de referencia (como eu já havia falado em outro post) em uma classe e estende-la e simplesmente fazer minhaClasse.AddReferecia. Claro quer isso impõem outros problemas como não usar mais Free e sim outro método, mas ainda é mais simples do que essa solução, alêm do fato de eu não criar um acoplamento desnecessário.

O maior problema ainda continua sendo que eu não posso aplicar essas soluções a qualquer classe independente da facilidade da implementação. Isso faz com que, alem de eu me preocupar em destruir o objeto, tenho que me preocupar com as referencias a ele.

J
x@ndy:
Cara, agora entendi o que você colocou e realmente você está certo e eu não conhecia a função RemoveFreeNotification, mas vejo que você ainda mas você ainda não entendeu o que eu coloquei, e por isso falei que você não esta acostumado a trabalhar com objetos.

1)Para que isso funcione, todas as suas classes teriam que herdar de TComponent! O que eu faço com classes que não herdam de TComponent?

2)Ok, todas as minhas classes herdam de TComponent. Você ainda tem fazer:
//Isso
procedure TTeste.Notification(AComponent: TComponent; Operation: TOperation);  
begin  
  inherited; 
  if (Operation = opRemove) and (AComponent = FBotao) then  
  begin  
    FBotao := nil;  
  
    if not (csDestroying in ComponentState) then  
      ShowMessage('Botão foi removido e eu vi');  
  end;  
end;  
....
//E isso
procedure TTeste.SetBotao(const Value: TButton);  
begin  
  if FBotao <> Value then  
  begin  
    if Assigned(FBotao) then  
      FBotao.RemoveFreeNotification(Self);  
  
    Enabled := False;  
    FBotao := Value;  
  
    if Assigned(FBotao) then  
    begin  
      FBotao.FreeNotification(Self);  
      OnTimer := ExecTimer;  
      Enabled := True;  
    end;  
  end;  
end;
Essas operações são obrigatórias para todas as classes a que eu faço referencia. Então é mais fácil implementar a contagem de referencia (como eu já havia falado em outro post) em uma classe e estende-la e simplesmente fazer minhaClasse.AddReferecia. Claro quer isso impõem outros problemas como não usar mais Free e sim outro método, mas ainda é mais simples do que essa solução, alêm do fato de eu não criar um acoplamento desnecessário.

O maior problema ainda continua sendo que eu não posso aplicar essas soluções a qualquer classe independente da facilidade da implementação. Isso faz com que, alem de eu me preocupar em destruir o objeto, tenho que me preocupar com as referencias a ele.

Todas as classes devem herdar TComponent porque esse modelo necessita de um pai. Com o qt é a mesma coisa, você precisa herdar QObject para que se possa mapear todas as referências. Se for comparar com o java, o mesmo funciona dessa maneira já que todas as classes herdam Object implicitamente. O que é importante ressaltar é que java e o famoso coletor de lixo não são nada mais que contadores de referência, e quem entende de desenvolvimento de software sabe como implementar esses modelos.

A linguagem pascal é uma das mais organizadas que eu já usei. O compilador é rigoroso e te obriga a escrever código organizado. Essa é uma grande vantagem em relação as demais.

G

eu acho q o problema do pascal, do c++, do clipper, do assembly, etc. é q quem faz os comparativos só conhece java e quer q funcione do mesmo jeito.

por exemplo:
vira e mexe e alguem diz: "td q vc cria vc tem q destruir"
o cara faz assim:

F := TFomCheiodeControles.Create(nil);

F.ShowModal;

F.Free;

será q foi criado só um Form ou um punhado de coisas?
ele teve q destruir td?
lembra do Owner? então, ele q resolveu o problema.
precisou do GC? ficou lixo na mem? agora vai no java e deixa um referencia perdida, estatica principalmente (os apps java são cheios disso) .
ai o cara fica descabelando querendo saber pq o GC não ta liberando a mem.

acho GC ruim? lógico q não!!!
mas o desenvolvedor pode deixar td por conta dele? não!!!

o pessoal desce a lenha no c++ e no pascal. mas qdo precisa de velocidade de verdade, logo alguem grita: Usa JNI!!!
lógico q significa, “faz em outra linguagem” mas fazem de conta q não é bem isso!

M

Eu programo em Delphi há algum tempo. Esse owner é uma forma de delegar a responsabilidade do gerenciamento de memória de um componente para um formulário, ou tem mais casos em que esse Owner pode ser usado?
Obs: Estou gostando muito do desenrolar desse tópico.

G

não necessariamente um formulario

X

GilsonNunes:
eu acho q o problema do pascal, do c++, do clipper, do assembly, etc. é q quem faz os comparativos só conhece java e quer q funcione do mesmo jeito.

por exemplo:
vira e mexe e alguem diz: "td q vc cria vc tem q destruir"
o cara faz assim:

F := TFomCheiodeControles.Create(nil);

F.ShowModal;

F.Free;

será q foi criado só um Form ou um punhado de coisas?
ele teve q destruir td?
lembra do Owner? então, ele q resolveu o problema.
precisou do GC? ficou lixo na mem? agora vai no java e deixa um referencia perdida, estatica principalmente (os apps java são cheios disso) .
ai o cara fica descabelando querendo saber pq o GC não ta liberando a mem.

acho GC ruim? lógico q não!!!
mas o desenvolvedor pode deixar td por conta dele? não!!!

o pessoal desce a lenha no c++ e no pascal. mas qdo precisa de velocidade de verdade, logo alguem grita: Usa JNI!!!
lógico q significa, “faz em outra linguagem” mas fazem de conta q não é bem isso!


Gilson, pelo que eu vi aqui ninguém colocou que o java é a melhor coisa do mundo. O que foi feito foi uma critica a uma ferramenta. Até porque não existe melhor linguagem. Eu entendo que as linguagens são como ferramentas e cada um tem o seu lugar. Acho que devemos usar a ferramenta certa para o problema certo. Eu posso programar com OO em Delphi, mas isso vai me dar muito mais trabalho do que em Java. Agora se eu quero fazer uma aplicação que vai fazer uso intensivo da API do Windows, por exemplo, vou fazer em Delphi, com certeza.
Não pode-se dizer que existe melhor linguagem, por que isso é besteira. Cada uma atende bem a uma necessidade, algumas até se igualam.
O que foi feito é uma crítica em relação ao Lazarus, e todas baseadas na experiência dos usuários. O que foi colocado é um problema que existe na utilização de OO no delphi, que, com um pouco de trabalho, pode ser contornado. Problemas existem em qualquer linguagem não só no Delphi.

X

juliocbq:

Todas as classes devem herdar TComponent porque esse modelo necessita de um pai. Com o qt é a mesma coisa, você precisa herdar QObject para que se possa mapear todas as referências. Se for comparar com o java, o mesmo funciona dessa maneira já que todas as classes herdam Object implicitamente. O que é importante ressaltar é que java e o famoso coletor de lixo não são nada mais que contadores de referência, e quem entende de desenvolvimento de software sabe como implementar esses modelos.

A linguagem pascal é uma das mais organizadas que eu já usei. O compilador é rigoroso e te obriga a escrever código organizado. Essa é uma grande vantagem em relação as demais.

Julio, no delphi todas as classes herdam, se não for especificado outra classe, de TObjetc, similar ao que acontece no Java. Sendo assim, nesse modelo eu não consegueria gerenciar as classes que não herdam de TComponent. Isso funciona bem para gerenciar componentes da VCL, mas seria no mínimo estranho, herdar de TComponent para criar classes que não sejam componentes. A meu ver seria mais simples implementar nessas Classes a contagem de referencia.

X

matheuslmota:
Eu programo em Delphi há algum tempo. Esse owner é uma forma de delegar a responsabilidade do gerenciamento de memória de um componente para um formulário, ou tem mais casos em que esse Owner pode ser usado?
Obs: Estou gostando muito do desenrolar desse tópico.

Tu pode fazer TMeuObjeto.Create(Owner). Assim, quando o componente O Owner for destruido, todos os outros que o tem como pai também serão.
Mas atenção, isso deve ser usado com cuidado. Utilize principalmente com componentes, pois ai existe uma hierarquia. Em um dominio OO isso pode ser mais um problema que uma solução, pois cria uma hierarquia de classes, e você pode não querer isso.

J

x@ndy:
juliocbq:

Todas as classes devem herdar TComponent porque esse modelo necessita de um pai. Com o qt é a mesma coisa, você precisa herdar QObject para que se possa mapear todas as referências. Se for comparar com o java, o mesmo funciona dessa maneira já que todas as classes herdam Object implicitamente. O que é importante ressaltar é que java e o famoso coletor de lixo não são nada mais que contadores de referência, e quem entende de desenvolvimento de software sabe como implementar esses modelos.

A linguagem pascal é uma das mais organizadas que eu já usei. O compilador é rigoroso e te obriga a escrever código organizado. Essa é uma grande vantagem em relação as demais.

Julio, no delphi todas as classes herdam, se não for especificado outra classe, de TObjetc, similar ao que acontece no Java. Sendo assim, nesse modelo eu não consegueria gerenciar as classes que não herdam de TComponent. Isso funciona bem para gerenciar componentes da VCL, mas seria no mínimo estranho, herdar de TComponent para criar classes que não sejam componentes. A meu ver seria mais simples implementar nessas Classes a contagem de referencia.

Nem no delphi nem no pascal herdarão TComponent se você não especificar(ou não usar wizard do delphi para gerar classes). O modelo de gerência de memória por contagem de referencia, além de boa pratica de programação é herdar o objeto pai que implementa o “smart pointer”.

/************ Correção *************/

Usando o delphi o correto é herdar todas as classes de TObject(desculpem postar TComponent, acabei me confundindo no calor da conversa), dessa maneira você está assegurando que seu software implementa contagem de referência, e não vai gerar leaks.

Por exemplo, quando você programa em c++(utilizando a propria standard library), o primeiro objeto a se implementar é justamento um coletor de lixo. Se você não faz isso desenvolve software errado(conforme o que li em livros).

Não é regra implementar nenhum modelo, mas saber conceitos de gerenciamento de memória é essencial para escrever o básico com linguagens que expõem apontadores.

Esse livro aqui foi o melhor que já li nesse quesito. É livro pro resto da vida:

X

Na verdade não! TObject não implementa contagem de referencia, é necessário criar uma classe que herda dela e ai sim implementar a contagem de referência!

É exatamente isso que é necessário fazer no delphi. No blog do João Morais tem um exemplo de implementação em Delphi: http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html

juliocbq:

Não é regra implementar nenhum modelo, mas saber conceitos de gerenciamento de memória é essencial para escrever o básico com linguagens que expõem apontadores.

Esse livro aqui foi o melhor que já li nesse quesito. É livro pro resto da vida:


Obrigado pela dica, assim que sobrar tempo vou ver se compro, to atolado de livros para ler e comprar.

J
x@ndy:
matheuslmota:
Eu programo em Delphi há algum tempo. Esse owner é uma forma de delegar a responsabilidade do gerenciamento de memória de um componente para um formulário, ou tem mais casos em que esse Owner pode ser usado? Obs: Estou gostando muito do desenrolar desse tópico.

Tu pode fazer TMeuObjeto.Create(Owner). Assim, quando o componente O Owner for destruido, todos os outros que o tem como pai também serão.
Mas atenção, isso deve ser usado com cuidado. Utilize principalmente com componentes, pois ai existe uma hierarquia. Em um dominio OO isso pode ser mais um problema que uma solução, pois cria uma hierarquia de classes, e você pode não querer isso.

De maneira alguma, a idéia é justamente criar a hierarquia.

no caso do Qt se app morrer todos os objetos são coletados.

#include <QApplication>
          #include <QTextEdit>
  
          int main(int argv, char **args)
          {
             QApplication app(argv, args);
  
              QTextEdit textEdit;
             textEdit.show();
 
             return app.exec();
         }

Mas QObject é pesada e você não vai herdar "todas" as classes dela. Vai criar uma hierarquia adequada, os objetos mais leves são gerenciados com auto_ptr.

J

Na verdade não! TObject não implementa contagem de referencia, é necessário criar uma classe que herda dela e ai sim implementar a contagem de referência!

[/quote]

Você tem razão, quem implementa é esse: TInterfacedObject(de acordo com a documentação).

dessa maneira vai criar uma hierarquia consistente.

X
juliocbq:
x@ndy:
matheuslmota:
Eu programo em Delphi há algum tempo. Esse owner é uma forma de delegar a responsabilidade do gerenciamento de memória de um componente para um formulário, ou tem mais casos em que esse Owner pode ser usado? Obs: Estou gostando muito do desenrolar desse tópico.

Tu pode fazer TMeuObjeto.Create(Owner). Assim, quando o componente O Owner for destruido, todos os outros que o tem como pai também serão.
Mas atenção, isso deve ser usado com cuidado. Utilize principalmente com componentes, pois ai existe uma hierarquia. Em um dominio OO isso pode ser mais um problema que uma solução, pois cria uma hierarquia de classes, e você pode não querer isso.

De maneira alguma, a idéia é justamente criar a hierarquia.

no caso do Qt se app morrer todos os objetos são coletados.

#include <QApplication>
          #include <QTextEdit>
  
          int main(int argv, char **args)
          {
             QApplication app(argv, args);
  
              QTextEdit textEdit;
             textEdit.show();
 
             return app.exec();
         }

Mas QObject é pesada e você não vai herdar "todas" as classes dela. Vai criar uma hierarquia adequada, os objetos mais leves são gerenciados com auto_ptr.

Não entendi sua colocação? Todos os domínios devem ter uma hierarquia de classes é isso? Se for eu discordo de você, pois determinados domínios não representam hierarquisa de classes, pelo contrário, existe uma colaboração entre elas, mas nunca uma hierarquia. Pense em um sistema comercial, por exemplo, as muitas classes desse domínio não estão em uma hierarquia, ou até estão, mas pertencem a hierarquias distintas. Se eu usar um Owner isso vai me criar um grave problema, pois eu tenho classes distintas com período de vida distintos. Um outro caso são serviços! Nesse caso não posso contar com o fim da aplicação para liberar a memória! Na verdade já tive esse problema em um sistema assim. Muitas classes eram criadas e a sua memória não era devolvida e assim em alguns dias a memória do servidor era esgotada. Por isso que digo que isso deve ser usado com cuidado.

X

juliocbq:

Você tem razão, quem implementa é esse: TInterfacedObject(de acordo com a documentação).

dessa maneira vai criar uma hierarquia consistente.

Na verdade também não. Você não pode chamar o método Free de uma classe descendente de TInterfacedObject. Se fizer isso vai ser levantada uma exceção!

G

eu tenho servidores desenvolvidos em pascal e nunca tive problema com memoria não liberada.

qdo falei do Owner não disse q ele era “um”, mt menos disse q era “uma” hierarquia. disse q ele pode ser usado qdo conveniente.
dei o exemplo do formCheioDeControles q vc não tem q destruir cada controle. o Form seria o Owner deles, mas não de td o projeto.

do jeito q alguns falam parece impossível desenvolver sem GC. Realmente é impossível desenvolver se vc trabalhar no pascal como se tivesse trabalhando com java.

negocio é a pratica.

vamos pensar uma situação real q se tornaria mt dificil sem o GC.

os Objetos q precisam de outros pra se fazer algo, basta colocar na lista “para serem avisados”.
não herda de TComponent? o q seria? q tal usar uma cópia então? seria custoso?
q tal um q implementa uma especie de Share?

sobre a tal Hierarquia q seria criado pelo Owner, ou eu não entendi ou é isso?

o q um TDataSet tem a ver com TForm? e no entanto ele pode ser apropriado por ele.

vejo sempre alguem dizer: se vc destruir um Datamodule enquanto um form tiver usando ele?
pq vc iria destruir esse maldito? pra criar “quizumba”?

eu destruo DataModules. mas com certeza não vai ter nem um form usando ele.
como eu sei? pq não tem nenhuma variavel global recebendo a instancia dele pra um programador avacalhar a coisa.

OO no pascal funciona bem. se vc começar bem.

duas regras importantes:

Regra  1: Retornar uma nova instancia  se for construtor ou o metodo tiver um nome do tipo Criar, Novo, Etc.;

Regra  2: não esqueça a regra  1;

um exemplo da violação dessas regras: (quem diria, a VCL?)

forms.pas linha 5570;

function TCustomForm.GetFormImage: TBitmap; .. begin Result := TBitmap.Create; ...

ai um infeliz acha q ta no java e faz assim:

MeuForm.GetFormImage.SaveToFile(xxxx);

ou

Printer.Canvas.Draw(0, 0, MeuForm.GetFormImage);

a instania retornada por TBitmap.Create; ficou sobrando mais q jiló na janta.

como deveria ser então?

assim:

procedure TCustomForm.GetFormImage(Result : TBitmap); .. begin Result.Width := ClientWidth; Result.Height := ClientHeight; Result.Canvas.Brush := Brush; Result.Canvas.FillRect(ClientRect); Result.Canvas.Lock; try if GetWindowLong(Handle, GWL_STYLE) and WS_BORDER <> 0 then Ofs := -1 // Don't draw form border else Ofs := 0; // There is no border PaintTo(Result.Canvas.Handle, Ofs, Ofs); finally Result.Canvas.Unlock; end; ...

pq ai o cara percebia logo q não tava no eclipse.

X

Gilson, como tu trabalha em teus projetos? Usa interface Inteligente, no modo tradicional do Delphi, usando DBware, Ou cria uma classe para cada entidade nos teus sistemas?
Digo isso, por que vejo que você não tem muita experiência com sistemas totalmente OO. Suas colocações são válidas, mas são colocações de quem nunca enfrentou os problemas trazidos por um sistema totalmente OO com uma dezena, ou até centena de classes. Pelo que vejo você deve fazer o que eu fiz durante muito tempo, você usa objetos em seus projetos mas não desenvolve orientado a objetos.

Como disse antes, existe uma forma de contornar o problema das referencias no delphi, principalmente usando contagem de referencia, mas isso torna o desenvolvimento mais complexo e sujeito a erros, se fazermos através de notificações, isso se torna ainda mais complexo e mais sujeitos a erros ainda. Quando usamos poucas classes em nossos sistemas é fácil controlar isso porém a media que o número de classes cresce isso muda de figura. Esquecer de uma implementar isso em algum lugar gera erros dificeis de localizar.

Outro problema é a abordagem do delphi no uso de interfaces. Qualquer sistema OO faz uso intensivo de interfaces. Agora quem já criou interfaces no Delphi sabe as dificuldades de o faze-lo.

Como disse antes, delphi é muito bom, mas não é a ferramenta ideal para desenvolver um sistema OO, porém é a melhor ferramenta para usar DBware.

G

na minha humilde opinião, a qtde de classes não vai afetar em nada isso. talvez a qtde de referencias poderia criar algum prob para os menos experientes.

eu uso OO, confesso q não desenvolvo preocupado se estou usando OO ou não.
desenvolvo procurando a melhor técnica do ponto de vista performance/manutenção
se OO for a melhor com certeza irei usá-la.

uso interfaces só qdo necessário. não gosto de usar só pra ver a palavra interface em negrito no meu código.

cite algumas situações em q eu poderia estar achando q estava desenvolvendo OO e q na realidade não o é.
qual a real dificuldade em usar interface no delphi?

e como ja supra citado, um exemplo real de q a ausência de GC comprometeria o desenvolvimento;

dá impressão de q suas classes são tdas dependentes umas das outras.
vc não usa encapsulamento, abstração, etc?
sábia q a razão de ser do OO é justamente evitar esse espaguete?

Sobre DBWare realmente o delphi é bom nisso. mas ser bom em algo não significa ser ruim em outros.
nem td é DBWare.

posso te mandar um exemplo de um programa desenvolvido em OO e q não tem nem um DBWare até pq ele não tem nada a ver com DB.

J

x@ndy:

Não entendi sua colocação? Todos os domínios devem ter uma hierarquia de classes é isso? Se for eu discordo de você, pois determinados domínios não representam hierarquisa de classes, pelo contrário, existe uma colaboração entre elas, mas nunca uma hierarquia. Pense em um sistema comercial, por exemplo, as muitas classes desse domínio não estão em uma hierarquia, ou até estão, mas pertencem a hierarquias distintas. Se eu usar um Owner isso vai me criar um grave problema, pois eu tenho classes distintas com período de vida distintos. Um outro caso são serviços! Nesse caso não posso contar com o fim da aplicação para liberar a memória! Na verdade já tive esse problema em um sistema assim. Muitas classes eram criadas e a sua memória não era devolvida e assim em alguns dias a memória do servidor era esgotada. Por isso que digo que isso deve ser usado com cuidado.

X@andy, o grafo hierárquico que você vai criar em algum ponto vai possuir várias bifurcações e várias classes do mesmo nível terão como ancestral apenas TObject, QObject, ou Object como no caso do java, que já faz isso implicitamente. Esse é o desenho ideal.

E você também está confundindo compartilhamento de memória com herança, o que não tem nada a ver com reference counting. Se um pai(pai é quem compartilha e conta referencias) compartilha seu endereço de memória com os filhos(alocados em memória), se eu matar o pai os filhos morrem sem eu ter a necessidade de eu ter que fazer isso explicitamente (chamar delete ou free).

No caso da hierarquia e herança de classes, você já faz isso com java sem perceber, todas as suas classes herdam Object.

http://doc.qt.nokia.com/4.7-snapshot/implicit-sharing.html

J

x@ndy:
juliocbq:

Você tem razão, quem implementa é esse: TInterfacedObject(de acordo com a documentação).

dessa maneira vai criar uma hierarquia consistente.

Na verdade também não. Você não pode chamar o método Free de uma classe descendente de TInterfacedObject. Se fizer isso vai ser levantada uma exceção!

Claro que não, ela já implementa um smart pointer. Você não precisa usar free explicitamente.

J

GilsonNunes:
eu tenho servidores desenvolvidos em pascal e nunca tive problema com memoria não liberada.

qdo falei do Owner não disse q ele era “um”, mt menos disse q era “uma” hierarquia. disse q ele pode ser usado qdo conveniente.
dei o exemplo do formCheioDeControles q vc não tem q destruir cada controle. o Form seria o Owner deles, mas não de td o projeto.

do jeito q alguns falam parece impossível desenvolver sem GC. Realmente é impossível desenvolver se vc trabalhar no pascal como se tivesse trabalhando com java.

negocio é a pratica.

vamos pensar uma situação real q se tornaria mt dificil sem o GC.

os Objetos q precisam de outros pra se fazer algo, basta colocar na lista “para serem avisados”.
não herda de TComponent? o q seria? q tal usar uma cópia então? seria custoso?
q tal um q implementa uma especie de Share?

sobre a tal Hierarquia q seria criado pelo Owner, ou eu não entendi ou é isso?

o q um TDataSet tem a ver com TForm? e no entanto ele pode ser apropriado por ele.

vejo sempre alguem dizer: se vc destruir um Datamodule enquanto um form tiver usando ele?
pq vc iria destruir esse maldito? pra criar “quizumba”?

eu destruo DataModules. mas com certeza não vai ter nem um form usando ele.
como eu sei? pq não tem nenhuma variavel global recebendo a instancia dele pra um programador avacalhar a coisa.

OO no pascal funciona bem. se vc começar bem.

duas regras importantes:

Regra  1: Retornar uma nova instancia  se for construtor ou o metodo tiver um nome do tipo Criar, Novo, Etc.;

Regra  2: não esqueça a regra  1;

um exemplo da violação dessas regras: (quem diria, a VCL?)

forms.pas linha 5570;

function TCustomForm.GetFormImage: TBitmap; .. begin Result := TBitmap.Create; ...

ai um infeliz acha q ta no java e faz assim:

MeuForm.GetFormImage.SaveToFile(xxxx);

ou

Printer.Canvas.Draw(0, 0, MeuForm.GetFormImage);

a instania retornada por TBitmap.Create; ficou sobrando mais q jiló na janta.

como deveria ser então?

assim:

procedure TCustomForm.GetFormImage(Result : TBitmap); .. begin Result.Width := ClientWidth; Result.Height := ClientHeight; Result.Canvas.Brush := Brush; Result.Canvas.FillRect(ClientRect); Result.Canvas.Lock; try if GetWindowLong(Handle, GWL_STYLE) and WS_BORDER <> 0 then Ofs := -1 // Don't draw form border else Ofs := 0; // There is no border PaintTo(Result.Canvas.Handle, Ofs, Ofs); finally Result.Canvas.Unlock; end; ...

pq ai o cara percebia logo q não tava no eclipse.

Justamente. É que a conversa desviou para herança e acabamos fazendo confusão com isso e contagem de referências.

J
x@ndy:
Gilson, como tu trabalha em teus projetos? Usa interface Inteligente, no modo tradicional do Delphi, usando DBware, Ou cria uma classe para cada entidade nos teus sistemas? Digo isso, por que vejo que você não tem muita experiência com sistemas totalmente OO. Suas colocações são válidas, mas são colocações de quem nunca enfrentou os problemas trazidos por um sistema totalmente OO com uma dezena, ou até centena de classes. Pelo que vejo você deve fazer o que eu fiz durante muito tempo, você usa objetos em seus projetos mas não desenvolve orientado a objetos.

Como disse antes, existe uma forma de contornar o problema das referencias no delphi, principalmente usando contagem de referencia, mas isso torna o desenvolvimento mais complexo e sujeito a erros, se fazermos através de notificações, isso se torna ainda mais complexo e mais sujeitos a erros ainda. Quando usamos poucas classes em nossos sistemas é fácil controlar isso porém a media que o número de classes cresce isso muda de figura. Esquecer de uma implementar isso em algum lugar gera erros dificeis de localizar.

Outro problema é a abordagem do delphi no uso de interfaces. Qualquer sistema OO faz uso intensivo de interfaces. Agora quem já criou interfaces no Delphi sabe as dificuldades de o faze-lo.

Como disse antes, delphi é muito bom, mas não é a ferramenta ideal para desenvolver um sistema OO, porém é a melhor ferramenta para usar DBware.

Não existe dificuldade nenhuma de usar interfaces com o delphi. É a mesma coisa que usar java ou c++. No caso da c++ a interface é apenas uma classe pura abstrata com métodos x=0
em pascal é isso. A idéia é sempre a mesma, o que muda é sintaxe.

type

   IColor = Interface(IInterface)

     function getRed : Boolean;
 
     property IsRed : Boolean read getRed;
   end;
X

juliocbq:
x@ndy:

Não entendi sua colocação? Todos os domínios devem ter uma hierarquia de classes é isso? Se for eu discordo de você, pois determinados domínios não representam hierarquisa de classes, pelo contrário, existe uma colaboração entre elas, mas nunca uma hierarquia. Pense em um sistema comercial, por exemplo, as muitas classes desse domínio não estão em uma hierarquia, ou até estão, mas pertencem a hierarquias distintas. Se eu usar um Owner isso vai me criar um grave problema, pois eu tenho classes distintas com período de vida distintos. Um outro caso são serviços! Nesse caso não posso contar com o fim da aplicação para liberar a memória! Na verdade já tive esse problema em um sistema assim. Muitas classes eram criadas e a sua memória não era devolvida e assim em alguns dias a memória do servidor era esgotada. Por isso que digo que isso deve ser usado com cuidado.

X@andy, o grafo hierárquico que você vai criar em algum ponto vai possuir várias bifurcações e várias classes do mesmo nível terão como ancestral apenas TObject, QObject, ou Object como no caso do java, que já faz isso implicitamente. Esse é o desenho ideal.

E você também está confundindo compartilhamento de memória com herança, o que não tem nada a ver com reference counting. Se um pai(pai é quem compartilha e conta referencias) compartilha seu endereço de memória com os filhos(alocados em memória), se eu matar o pai os filhos morrem sem eu ter a necessidade de eu ter que fazer isso explicitamente (chamar delete ou free).

No caso da hierarquia e herança de classes, você já faz isso com java sem perceber, todas as suas classes herdam Object.

<a href="http://doc.qt.nokia.com/4.7-snapshot/implicit-sharing.html%5B/quote%5D" class="onebox" target="_blank">http://doc.qt.nokia.com/4.7-snapshot/implicit-sharing.html</blockquote></a>

Não é isso! Não estou falando de hierarquia de herança, acho que a palavara hierarquia ficou confusa aqui. O que queria falar é que podemos ter uma espécie de escada de objetos, vamos a um exemplo. Digamos que tenha-mos as classes A,  B,  C, D e eu faça

A.Create(nil)

B.Create(A)

C.Create(B)

D.Create©

Para que a memória dos objetos sejam liberaradas eu tenho que destruir o objeto A, até ai tudo bem, porém, se por engano eu destruo o objeto B, a memória de todos os objetos sera liberada, digo, a memória de todos os obetos que tem o B como owner e eu perco a referência a eles. Por isso que eu disse que isso tem que ser usado com cuidado. E essa hierarquia de que falo. Ao usar o Owner para liberar a memória temos que ter cuidado para não criar algo desse tipo!

X

juliocbq:
x@ndy:
juliocbq:

Você tem razão, quem implementa é esse: TInterfacedObject(de acordo com a documentação).

dessa maneira vai criar uma hierarquia consistente.

Na verdade também não. Você não pode chamar o método Free de uma classe descendente de TInterfacedObject. Se fizer isso vai ser levantada uma exceção!

Claro que não, ela já implementa um smart pointer. Você não precisa usar free explicitamente.

Não entendi como isso funciona, poderia me explicar?

J

x@ndy:
juliocbq:
x@ndy:
juliocbq:

Você tem razão, quem implementa é esse: TInterfacedObject(de acordo com a documentação).

dessa maneira vai criar uma hierarquia consistente.

Na verdade também não. Você não pode chamar o método Free de uma classe descendente de TInterfacedObject. Se fizer isso vai ser levantada uma exceção!

Claro que não, ela já implementa um smart pointer. Você não precisa usar free explicitamente.

Não entendi como isso funciona, poderia me explicar?

Porque essa classe já implementa reference count.
http://www.freepascal.org/docs-html/rtl/system/tinterfacedobject.html

X
juliocbq:
Não existe dificuldade nenhuma de usar interfaces com o delphi. É a mesma coisa que usar java ou c++. No caso da c++ a interface é apenas uma classe pura abstrata com métodos x=0 em pascal é isso. A idéia é sempre a mesma, o que muda é sintaxe.
type

   IColor = Interface(IInterface)

     function getRed : Boolean;
 
     property IsRed : Boolean read getRed;
   end;
Eu disse isso por que usar interfaces no java é muito simples e no delphi a pessoa tem que saber como a interface funciona, vamos a um exemplo usando a sua interface Se eu fizer isso, como faria no java, vai gerar uma exceção
type
   TTesteColor = class(IColor)
      function getRed : Boolean;
      property IsRed : Boolean read getRed;
   end;
Pois a interface exige a implementação dos métodos
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
   function _AddRef: Integer; stdcall;
   function _Release: Integer; stdcall;
Então ou implemento isso em todas as classes ou faço isso.
type
   TTesteColor = class(TInterfacedObject, IColor)
      function getRed : Boolean;
      property IsRed : Boolean read getRed;
   end;
Até ai tudo bem, mas o pior é que o cuidado que temos que ter para não misturar ponteiros para objetos com ponteiros para interfaces de modo a não termos problema, veja aqui: [url]http://br.groups.yahoo.com/group/delphi-br/message/196124[/url]
J

x@ndy:
juliocbq:
x@ndy:

Não entendi sua colocação? Todos os domínios devem ter uma hierarquia de classes é isso? Se for eu discordo de você, pois determinados domínios não representam hierarquisa de classes, pelo contrário, existe uma colaboração entre elas, mas nunca uma hierarquia. Pense em um sistema comercial, por exemplo, as muitas classes desse domínio não estão em uma hierarquia, ou até estão, mas pertencem a hierarquias distintas. Se eu usar um Owner isso vai me criar um grave problema, pois eu tenho classes distintas com período de vida distintos. Um outro caso são serviços! Nesse caso não posso contar com o fim da aplicação para liberar a memória! Na verdade já tive esse problema em um sistema assim. Muitas classes eram criadas e a sua memória não era devolvida e assim em alguns dias a memória do servidor era esgotada. Por isso que digo que isso deve ser usado com cuidado.

X@andy, o grafo hierárquico que você vai criar em algum ponto vai possuir várias bifurcações e várias classes do mesmo nível terão como ancestral apenas TObject, QObject, ou Object como no caso do java, que já faz isso implicitamente. Esse é o desenho ideal.

E você também está confundindo compartilhamento de memória com herança, o que não tem nada a ver com reference counting. Se um pai(pai é quem compartilha e conta referencias) compartilha seu endereço de memória com os filhos(alocados em memória), se eu matar o pai os filhos morrem sem eu ter a necessidade de eu ter que fazer isso explicitamente (chamar delete ou free).

No caso da hierarquia e herança de classes, você já faz isso com java sem perceber, todas as suas classes herdam Object.

<a href="http://doc.qt.nokia.com/4.7-snapshot/implicit-sharing.html%5B/quote%5D" class="onebox" target="_blank">http://doc.qt.nokia.com/4.7-snapshot/implicit-sharing.html</blockquote></a>

Não é isso! Não estou falando de hierarquia de herança, acho que a palavara hierarquia ficou confusa aqui. O que queria falar é que podemos ter uma espécie de escada de objetos, vamos a um exemplo. Digamos que tenha-mos as classes A,  B,  C, D e eu faça

A.Create(nil)

B.Create(A)

C.Create(B)

D.Create©

Para que a memória dos objetos sejam liberaradas eu tenho que destruir o objeto A, até ai tudo bem, porém, se por engano eu destruo o objeto B, a memória de todos os objetos sera liberada e eu perco a referência a eles. Por isso que eu disse que isso tem que ser usado com cuidado. E essa hierarquia de que falo. Ao usar o Ower para liberar a memória temos que ter cuidado para não criar algo desse tipo!

Isso é verdade. Se o pai exclui o endereço que os filhos apontam você pode ter problemas. Além do mais, existem algoritmos que cuidam disso.

O Implicit sharing é um mecanismo um pouco diferente e bem robusto. Ele já consegue cuidar desse problema que você citou. Nunca cometi nenhum deslize usando o qt dessa maneira.

X

Removi esse tópico pois repliquei algo que eu mesmo havia colocado

X

juliocbq:
x@ndy:
juliocbq:
x@ndy:
juliocbq:

Você tem razão, quem implementa é esse: TInterfacedObject(de acordo com a documentação).

dessa maneira vai criar uma hierarquia consistente.

Na verdade também não. Você não pode chamar o método Free de uma classe descendente de TInterfacedObject. Se fizer isso vai ser levantada uma exceção!

Claro que não, ela já implementa um smart pointer. Você não precisa usar free explicitamente.

Não entendi como isso funciona, poderia me explicar?

Porque essa classe já implementa reference count.
http://www.freepascal.org/docs-html/rtl/system/tinterfacedobject.html


Ah sim! Mas isso cria um outro problema: http://br.groups.yahoo.com/group/delphi-br/message/196124

X

Pessoal, o que estou colocando aqui não é que impossível de se fazer um sistema OO no Delphi, por que não é. O que coloco é que ele não é linguagem mais adequada para isso, pois impõem uma serie de cuidados a serem tomados.
Pela discussão até levada até aqui é fácil notar que para se fazer isso em Delphi é necessário um bom conhecimento de como ele funciona, se não você vai ter diversos problemas.
Digo isso por que já enfrentei esses problemas. Esses problemas se tornam mais evidentes ainda quando se tem uma equipe formadas de programadores pleno/junior.

X

O próprio exemplo que você colocou do FreeNotification mostra a utlização de objetos, mas não uma programação orientada a objetos!

Já citei isso aqui duas vezes, mas vai de novo:http://br.groups.yahoo.com/group/delphi-br/message/196124

Eu nunca falei que ausência de Garbage Colector compremete o desenvolvimento. O que estou falando é que ele dificulta o desenvolvimento! Já disse antes e vou falar de novo, você pode programar OO no delphi, não existe uma restrição, porém você terá que contornar a falta do GC e terá que ter cuidado no uso de interfaces. No resto use e seja feliz.

G
x@ndy:
Eu disse isso por que usar interfaces no java é muito simples e no delphi a pessoa tem que saber como a interface funciona, vamos a um exemplo usando a sua interface Se eu fizer isso, como faria no java, vai gerar uma exceção
type
   TTesteColor = class(IColor)
      function getRed : Boolean;
      property IsRed : Boolean read getRed;
   end;
Pois a interface exige a implementação dos métodos
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
   function _AddRef: Integer; stdcall;
   function _Release: Integer; stdcall;
Então ou implemento isso em todas as classes ou faço isso.
type
   TTesteColor = class(TInterfacedObject, IColor)
      function getRed : Boolean;
      property IsRed : Boolean read getRed;
   end;
Pois a interface exige a implementação dos métodos Até ai tudo bem, mas o pior é que o cuidado que temos que ter para não misturar ponteiros para objetos com ponteiros para interfaces de modo a não termos problema, veja aqui: [url]http://br.groups.yahoo.com/group/delphi-br/message/196124[/url]

viu? é só uma questão de saber. vc deu dois exemplos o segundo tentou melhorar mas realmente ficou ruim comparando com java.

ma e o tercerio exemplo?

faltou ele: ele era o correto:

unit Unit1; 

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls;

type

   IRotulavel = interface
      function GetTexto : string;
      function GetDesenvolvedor : string;
   end;

   { Botao }

   { TBotao }

   TBotao = Class(TButton, IRotulavel)
   public
     function GetTexto: string;
     function GetDesenvolvedor: string;
   end;

   { TGShape }

   TGShape = Class(TShape, IRotulavel)
   public
     function GetTexto: string;
     function GetDesenvolvedor: string;
   end;


  { TForm1 }

  TForm1 = class(TForm)
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    procedure BotaoClick(Sender: TObject);
    procedure ShapeClick(Sender: TObject);
  public
    { public declarations }
  end; 

var
  Form1: TForm1; 

implementation

{$R *.lfm}

{ TForm1 }

{ TBotao }

function TBotao.GetTexto: string;
begin
  Result := 'Botão: '+Caption;
end;

function TBotao.GetDesenvolvedor: string;
begin
  Result := 'Gilson';
end;

{ TGShape }

function TGShape.GetTexto: string;
begin
  Result := 'Shape: ' + ColorToString(Brush.Color);
end;

function TGShape.GetDesenvolvedor: string;
begin
  Result := 'João';
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Tag := Tag + 1;
  if Button = mbLeft then
  begin
    with TBotao.Create(Self) do
    begin
      Parent := Self;
      Top:=Y;
      Left:=X;
      OnClick:=@BotaoClick;
      Caption:=IntToStr(Self.Tag);
    end;
  end else
  begin
    with TGShape.Create(Self) do
    begin
      Parent := Self;
      Top:=Y;
      Left:=X;
      OnClick:=@ShapeClick;
      Brush.Color:= RGBToColor(Self.Tag * 10, Self.Tag * 40, Self.Tag * 80);
    end;
  end;
end;

procedure MostraTexto(obj : IRotulavel);
begin
  ShowMessage(obj.GetTexto+#13#10'Feito por: '+obj.GetDesenvolvedor);
end;

procedure TForm1.BotaoClick(Sender: TObject);
begin
   MostraTexto(Sender as TBotao);
end;

procedure TForm1.ShapeClick(Sender: TObject);
begin
   MostraTexto(Sender as TGShape);
end;

end.

esse é um exemplo de uso de inteface, não?
no java teria q facilidade a mais?

X
GilsonNunes:
x@ndy:
Eu disse isso por que usar interfaces no java é muito simples e no delphi a pessoa tem que saber como a interface funciona, vamos a um exemplo usando a sua interface Se eu fizer isso, como faria no java, vai gerar uma exceção
type
   TTesteColor = class(IColor)
      function getRed : Boolean;
      property IsRed : Boolean read getRed;
   end;
Pois a interface exige a implementação dos métodos
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
   function _AddRef: Integer; stdcall;
   function _Release: Integer; stdcall;
Então ou implemento isso em todas as classes ou faço isso.
type
   TTesteColor = class(TInterfacedObject, IColor)
      function getRed : Boolean;
      property IsRed : Boolean read getRed;
   end;
Pois a interface exige a implementação dos métodos Até ai tudo bem, mas o pior é que o cuidado que temos que ter para não misturar ponteiros para objetos com ponteiros para interfaces de modo a não termos problema, veja aqui: [url]http://br.groups.yahoo.com/group/delphi-br/message/196124[/url]

viu? é só uma questão de saber. vc deu dois exemplos o segundo tentou melhorar mas realmente ficou ruim comparando com java.

ma e o tercerio exemplo?

faltou ele: ele era o correto:

unit Unit1; 

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls;

type

   IRotulavel = interface
      function GetTexto : string;
      function GetDesenvolvedor : string;
   end;

   { Botao }

   { TBotao }

   TBotao = Class(TButton, IRotulavel)
   public
     function GetTexto: string;
     function GetDesenvolvedor: string;
   end;

   { TGShape }

   TGShape = Class(TShape, IRotulavel)
   public
     function GetTexto: string;
     function GetDesenvolvedor: string;
   end;


  { TForm1 }

  TForm1 = class(TForm)
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    procedure BotaoClick(Sender: TObject);
    procedure ShapeClick(Sender: TObject);
  public
    { public declarations }
  end; 

var
  Form1: TForm1; 

implementation

{$R *.lfm}

{ TForm1 }

{ TBotao }

function TBotao.GetTexto: string;
begin
  Result := 'Botão: '+Caption;
end;

function TBotao.GetDesenvolvedor: string;
begin
  Result := 'Gilson';
end;

{ TGShape }

function TGShape.GetTexto: string;
begin
  Result := 'Shape: ' + ColorToString(Brush.Color);
end;

function TGShape.GetDesenvolvedor: string;
begin
  Result := 'João';
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Tag := Tag + 1;
  if Button = mbLeft then
  begin
    with TBotao.Create(Self) do
    begin
      Parent := Self;
      Top:=Y;
      Left:=X;
      OnClick:=@BotaoClick;
      Caption:=IntToStr(Self.Tag);
    end;
  end else
  begin
    with TGShape.Create(Self) do
    begin
      Parent := Self;
      Top:=Y;
      Left:=X;
      OnClick:=@ShapeClick;
      Brush.Color:= RGBToColor(Self.Tag * 10, Self.Tag * 40, Self.Tag * 80);
    end;
  end;
end;

procedure MostraTexto(obj : IRotulavel);
begin
  ShowMessage(obj.GetTexto+#13#10'Feito por: '+obj.GetDesenvolvedor);
end;

procedure TForm1.BotaoClick(Sender: TObject);
begin
   MostraTexto(Sender as TBotao);
end;

procedure TForm1.ShapeClick(Sender: TObject);
begin
   MostraTexto(Sender as TGShape);
end;

end.
esse é um exemplo de uso de inteface, não? no java teria q facilidade a mais?
Qual a diferença desse exemplo para o anterior? Parece que você esta querendo confundir, até porque (se não me engano), TComponent, já herda de TInterfacedObject que implementa os métodos. O que você fez, foi algo assim:
type
   TColorBase = class(TInterfacedObject)
   end;
...
type
   TTesteColor = class(TColorBase, IColor)
      function getRed : Boolean;
      property IsRed : Boolean read getRed;
   end;
Qual a diferença do seu exemplo afinal? Tirando o fato de você colocar a implementação também? E pelo que eu vejo, você não leu o que estava no link, então vou copiar e colar aqui:
Re: [delphi-br] Problema com Objetos da classe TInterfacedObject + uma interface

PUBLICIDADE
2008/12/29 Thales (Shubacca) - Tebo Software :
> O problema que estou encontrando é que após o dao persistir o objeto, ele
> chama o destructor do objeto persistido, mas eu não destrui o mesmo.
>
> Debugando descobri que o campo que conta as referencias do objeto fica com
> valor 0 (zero) após a persistencia, mas ainda existe uma variavel local que
> está fazendo referencia ao meu objeto.
>
> alguém sabe como me ajudar nisso?

Parece que você está misturando ponteiros para objetos e ponteiros
para interface. O gerenciamento de memória do Delphi, no que tange
interfaces, é feito com contagem de referência: associação conta mais
um, alteração do ponteiro ou saída de escopo conta menos um. Mas se
você faz com que um ponteiro para objeto aponte para objetos que
também tem interfaces apontando, tão logo as interfaces saiam de
escopo e o objeto será destruído, deixando aquele ponteiro
referenciando uma área de memória inválida. Mais ou menos assim:

var
VObjI: IObj; // interface
VObjO: TObj; // TObj implementa IObj
begin
VObjO := TObj.Create;
VObjI := VObjO;
VObjI := nil;
VObjO.Free; // erro
end;

Caso o problema seja este, então ou você não mistura ponteiros para
objeto com ponteiros para interface, ou contorna da mesma forma que eu
contornei:
[url]http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html[/url]

Se não for, detalhe melhor a sua implementação.

--
Joao Morais

J

x@ndy:
juliocbq:
x@ndy:
juliocbq:
x@ndy:
juliocbq:

Você tem razão, quem implementa é esse: TInterfacedObject(de acordo com a documentação).

dessa maneira vai criar uma hierarquia consistente.

Na verdade também não. Você não pode chamar o método Free de uma classe descendente de TInterfacedObject. Se fizer isso vai ser levantada uma exceção!

Claro que não, ela já implementa um smart pointer. Você não precisa usar free explicitamente.

Não entendi como isso funciona, poderia me explicar?

Porque essa classe já implementa reference count.
http://www.freepascal.org/docs-html/rtl/system/tinterfacedobject.html


Ah sim! Mas isso cria um outro problema: http://br.groups.yahoo.com/group/delphi-br/message/196124

É justamente o que o link que você postou disse. Se você já tem o smart pointer não precisa gerenciar memória manualmente para não causar confusão.

G

eu precisei implemntar os tais metodos q vc citou?

<blockquote>

function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;

function _AddRef: Integer; stdcall;

function _Release: Integer; stdcall;  </blockquote>

herdei de TInterfacedobject?

o cara ai do tal link ta tendo problema pq ele usa o q conta referencia e trata como se não fosse. (é o tipico despreparado)

mas vc não viu nada de diferente no exemplo q postei?
vc então não leu ele.

mas faz o seguinte:

crie um exemplo usando inteface no java e poste aki pra vermos como ficaria em pascal.
blz?

J

x@ndy:

Bom, vejo que você não leu o que estava no link, então vou colocar aqui:

Re: [delphi-br] Problema com Objetos da classe TInterfacedObject + uma interface

PUBLICIDADE
2008/12/29 Thales (Shubacca) - Tebo Software <tebosoftware@…>:

O problema que estou encontrando é que após o dao persistir o objeto, ele
chama o destructor do objeto persistido, mas eu não destrui o mesmo.

Debugando descobri que o campo que conta as referencias do objeto fica com
valor 0 (zero) após a persistencia, mas ainda existe uma variavel local que
está fazendo referencia ao meu objeto.

alguém sabe como me ajudar nisso?

Parece que você está misturando ponteiros para objetos e ponteiros
para interface. O gerenciamento de memória do Delphi, no que tange
interfaces, é feito com contagem de referência: associação conta mais
um, alteração do ponteiro ou saída de escopo conta menos um. Mas se
você faz com que um ponteiro para objeto aponte para objetos que
também tem interfaces apontando, tão logo as interfaces saiam de
escopo e o objeto será destruído, deixando aquele ponteiro
referenciando uma área de memória inválida. Mais ou menos assim:

var

VObjI: IObj; // interface

VObjO: TObj; // TObj implementa IObj

begin

VObjO := TObj.Create;

VObjI := VObjO;

VObjI := nil;

VObjO.Free; // erro

end;

Caso o problema seja este, então ou você não mistura ponteiros para
objeto com ponteiros para interface, ou contorna da mesma forma que eu
contornei:
http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html

Se não for, detalhe melhor a sua implementação.


Joao Morais

O que foi postado no link é que você não precisa chamar free explicitamente porque já usa contagem de referência. Aliás, fazer isso é a mesma coisa que querer usar um delete num objeto java.
Vocês estão colocando posts muito extensos. Tá ficando difícil de ler.

Para criar software bem modelado não é necessário usar uma linguagem como java. Nem de longe java facilita nesse quesito. Existem implementações em c++ e pascal que dão um banho em muitas que são produzidas em linguagens modernas. Um exemplo disso é o proprio qt. Totalmente MVC.

Para construir software bom você tem que saber o que faz com as ferramentas que utiliza.

X
x@ndy:
GilsonNunes:
x@ndy:
Eu disse isso por que usar interfaces no java é muito simples e no delphi a pessoa tem que saber como a interface funciona, vamos a um exemplo usando a sua interface Se eu fizer isso, como faria no java, vai gerar uma exceção
type
   TTesteColor = class(IColor)
      function getRed : Boolean;
      property IsRed : Boolean read getRed;
   end;
Pois a interface exige a implementação dos métodos
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
   function _AddRef: Integer; stdcall;
   function _Release: Integer; stdcall;
Então ou implemento isso em todas as classes ou faço isso.
type
   TTesteColor = class(TInterfacedObject, IColor)
      function getRed : Boolean;
      property IsRed : Boolean read getRed;
   end;
Pois a interface exige a implementação dos métodos Até ai tudo bem, mas o pior é que o cuidado que temos que ter para não misturar ponteiros para objetos com ponteiros para interfaces de modo a não termos problema, veja aqui: [url]http://br.groups.yahoo.com/group/delphi-br/message/196124[/url]

viu? é só uma questão de saber. vc deu dois exemplos o segundo tentou melhorar mas realmente ficou ruim comparando com java.

ma e o tercerio exemplo?

faltou ele: ele era o correto:

unit Unit1; 

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls;

type

   IRotulavel = interface
      function GetTexto : string;
      function GetDesenvolvedor : string;
   end;

   { Botao }

   { TBotao }

   TBotao = Class(TButton, IRotulavel)
   public
     function GetTexto: string;
     function GetDesenvolvedor: string;
   end;

   { TGShape }

   TGShape = Class(TShape, IRotulavel)
   public
     function GetTexto: string;
     function GetDesenvolvedor: string;
   end;


  { TForm1 }

  TForm1 = class(TForm)
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    procedure BotaoClick(Sender: TObject);
    procedure ShapeClick(Sender: TObject);
  public
    { public declarations }
  end; 

var
  Form1: TForm1; 

implementation

{$R *.lfm}

{ TForm1 }

{ TBotao }

function TBotao.GetTexto: string;
begin
  Result := 'Botão: '+Caption;
end;

function TBotao.GetDesenvolvedor: string;
begin
  Result := 'Gilson';
end;

{ TGShape }

function TGShape.GetTexto: string;
begin
  Result := 'Shape: ' + ColorToString(Brush.Color);
end;

function TGShape.GetDesenvolvedor: string;
begin
  Result := 'João';
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Tag := Tag + 1;
  if Button = mbLeft then
  begin
    with TBotao.Create(Self) do
    begin
      Parent := Self;
      Top:=Y;
      Left:=X;
      OnClick:=@BotaoClick;
      Caption:=IntToStr(Self.Tag);
    end;
  end else
  begin
    with TGShape.Create(Self) do
    begin
      Parent := Self;
      Top:=Y;
      Left:=X;
      OnClick:=@ShapeClick;
      Brush.Color:= RGBToColor(Self.Tag * 10, Self.Tag * 40, Self.Tag * 80);
    end;
  end;
end;

procedure MostraTexto(obj : IRotulavel);
begin
  ShowMessage(obj.GetTexto+#13#10'Feito por: '+obj.GetDesenvolvedor);
end;

procedure TForm1.BotaoClick(Sender: TObject);
begin
   MostraTexto(Sender as TBotao);
end;

procedure TForm1.ShapeClick(Sender: TObject);
begin
   MostraTexto(Sender as TGShape);
end;

end.
esse é um exemplo de uso de inteface, não? no java teria q facilidade a mais?
Qual a diferença desse exemplo para o anterior? Parece que você esta querendo confundir, até porque (se não me engano), TComponent, já herda de TInterfacedObject que implementa os métodos. O que você fez, foi algo assim:
type
   TColorBase = class(TInterfacedObject)
   end;
...
type
   TTesteColor = class(TColorBase, IColor)
      function getRed : Boolean;
      property IsRed : Boolean read getRed;
   end;
Qual a diferença do seu exemplo afinal? Tirando o fato de você colocar a implementação também? E pelo que eu vejo, você não leu o que estava no link, então vou copiar e colar aqui:
Re: [delphi-br] Problema com Objetos da classe TInterfacedObject + uma interface

PUBLICIDADE
2008/12/29 Thales (Shubacca) - Tebo Software :
> O problema que estou encontrando é que após o dao persistir o objeto, ele
> chama o destructor do objeto persistido, mas eu não destrui o mesmo.
>
> Debugando descobri que o campo que conta as referencias do objeto fica com
> valor 0 (zero) após a persistencia, mas ainda existe uma variavel local que
> está fazendo referencia ao meu objeto.
>
> alguém sabe como me ajudar nisso?

Parece que você está misturando ponteiros para objetos e ponteiros
para interface. O gerenciamento de memória do Delphi, no que tange
interfaces, é feito com contagem de referência: associação conta mais
um, alteração do ponteiro ou saída de escopo conta menos um. Mas se
você faz com que um ponteiro para objeto aponte para objetos que
também tem interfaces apontando, tão logo as interfaces saiam de
escopo e o objeto será destruído, deixando aquele ponteiro
referenciando uma área de memória inválida. Mais ou menos assim:

var
VObjI: IObj; // interface
VObjO: TObj; // TObj implementa IObj
begin
VObjO := TObj.Create;
VObjI := VObjO;
VObjI := nil;
VObjO.Free; // erro
end;

Caso o problema seja este, então ou você não mistura ponteiros para
objeto com ponteiros para interface, ou contorna da mesma forma que eu
contornei:
[url]http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html[/url]

Se não for, detalhe melhor a sua implementação.

--
Joao Morais

Complementando:

No java é mais simples pois, só faço assim:
public interface Lutador {
	public boolean estaVivo();
	public int forcaDeAtaque();
	public String nome();
	public int numeroDeVidasAtual();
	public void registrarObservador(ObservadorDaLuta observador);
}
...
public class Inimigo implements Lutador {
...
}
G
public interface Lutador {  
    public boolean estaVivo();  
    public int forcaDeAtaque();  
    public String nome();  
    public int numeroDeVidasAtual();  
    public void registrarObservador(ObservadorDaLuta observador);  
}  
...  
public class Inimigo implements Lutador {  
...  
}

no pascal é assim:

type
   Lutador = interface
    public
      function estaVivo : boolean;
      function forcaDeAtaque : Integer;
      function nome : string;
      function numeroDeVidasAtual : Integer;
      procedure registrarObservador(observador : ObservadorDaLuta);
  end;

  Inimigo = class(Lutador)
    ...
  end;

qual a diferença?

posta um exemplo completo.

X

juliocbq:
x@ndy:
juliocbq:
x@ndy:
juliocbq:
x@ndy:
juliocbq:

Você tem razão, quem implementa é esse: TInterfacedObject(de acordo com a documentação).

dessa maneira vai criar uma hierarquia consistente.

Na verdade também não. Você não pode chamar o método Free de uma classe descendente de TInterfacedObject. Se fizer isso vai ser levantada uma exceção!

Claro que não, ela já implementa um smart pointer. Você não precisa usar free explicitamente.

Não entendi como isso funciona, poderia me explicar?

Porque essa classe já implementa reference count.
http://www.freepascal.org/docs-html/rtl/system/tinterfacedobject.html


Ah sim! Mas isso cria um outro problema: http://br.groups.yahoo.com/group/delphi-br/message/196124

É justamente o que o link que você postou disse. Se você já tem o smart pointer não precisa gerenciar memória manualmente para não causar confusão.


O problema é a confusão que isso gera e o cuidado que devo ter para evitar esse tipo de problema.
O que o java faz é justamente tirar isso do ombro do programador.

X
GilsonNunes:
public interface Lutador {  
    public boolean estaVivo();  
    public int forcaDeAtaque();  
    public String nome();  
    public int numeroDeVidasAtual();  
    public void registrarObservador(ObservadorDaLuta observador);  
}  
...  
public class Inimigo implements Lutador {  
...  
}

no pascal é assim:

type
   Lutador = interface
    public
      function estaVivo : boolean;
      function forcaDeAtaque : Integer;
      function nome : string;
      function numeroDeVidasAtual : Integer;
      procedure registrarObservador(observador : ObservadorDaLuta);
  end;

  Inimigo = class(Lutador)
    ...
  end;

qual a diferença?

posta um exemplo completo.


Bom seu exemplo está errado, exatamente aqui: Inimigo = class(Lutador). O exemplo completo esta abaixo:

public interface Lutador {
	public boolean estaVivo();
	public int forcaDeAtaque();
	public String nome();
	public int numeroDeVidasAtual();
	public void registrarObservador(ObservadorDaLuta observador);
}
package dominio;



import dominio.tesouros.*;
import dominio.utensilios.*;

public class Jogador implements Lutador {
	private int numeroDeVidas;
	private Arma arma = new Arma(TipoDeArma.FACA);
	private Tesouro tesouro = null;
	private Armadura armadura = new Armadura(TipoDeArmadura.NENHUMA);
	private String nome;
	private ObservadorDaLuta observador;
	private EstrategiaDeCombate estrategiaDeCombate;
	public final int efetividadeDoGolpe = 80;

	private void reiniciarNumeroDeVidas(){
		numeroDeVidas = 10;
	}

	private void levantarExcecaoParametroNulo(Object parametro, String nomeDoParametro){
		if (parametro == null){
			String mensagem = String.format("O parâmetro '%s' não pode ser nulo!", nomeDoParametro);
			throw new IllegalArgumentException(mensagem);
		}
	}

	public Jogador(String nome) {
		levantarExcecaoParametroNulo(nome, "nome");

		if (nome.trim().equals(""))
			throw new IllegalArgumentException("O campo nome não pode ser nulo");
		this.nome = nome;
		reiniciarNumeroDeVidas();
	}

	public void beberPocaoDeVida(){
		if (tesouro instanceof PocaoDeVida){
			reiniciarNumeroDeVidas();
			tesouro = null;
		}
	}

	public void golpeRecebido(Inimigo inimigo, Golpe golpe){
		levantarExcecaoParametroNulo(inimigo, "inimigo");
		levantarExcecaoParametroNulo(golpe, "golpe");
		int danoCausado = golpe.danoQueCausa() - armadura.tipo().nivelDeProtecao();

		if (danoCausado < 0)
			danoCausado = 0;
		numeroDeVidas -= danoCausado; 

		if (observador != null)
			observador.notificarContraAtaqueRecebido(inimigo, golpe, danoCausado);
	}

	public void golpear(Inimigo inimigo) throws ExcecaoEstrategiaNaoDefinida{
		levantarExcecaoParametroNulo(inimigo, "inimigo");

		if (!estaVivo())
			throw new IllegalStateException("Operação illegal quando se está morto");

		if (estrategiaDeCombate == null)
			throw new ExcecaoEstrategiaNaoDefinida();

		Golpe golpe = estrategiaDeCombate.gerarGolpe(this);
		inimigo.golpeadoPor(this, golpe);
	}

	public void definirEstrategiaDeCombate(EstrategiaDeCombate estrategia){
		levantarExcecaoParametroNulo(estrategia, "estrategia");
		estrategiaDeCombate = estrategia;		
	}

	public Arma arma(){
		return arma;
	}

	public Arma segurarArma(Arma arma){
		levantarExcecaoParametroNulo(arma, "arma");
		Arma armaParaSoltar;

		if (arma.tipo().danosQueElaCausa() > this.arma.tipo().danosQueElaCausa()){
			armaParaSoltar = this.arma;
			this.arma = arma;
		}
		else
			armaParaSoltar = arma;

		return armaParaSoltar;
	}

	public Armadura vestirArmadura(Armadura armadura){
		levantarExcecaoParametroNulo(armadura, "armadura");

		Armadura armaduraRetirada;

		if (armadura.tipo().nivelDeProtecao() > this.armadura.tipo().nivelDeProtecao()){
			armaduraRetirada = this.armadura;
			this.armadura = armadura;
		}

		else
			armaduraRetirada = armadura;

		return armaduraRetirada;
	}

	@Override

	public boolean estaVivo() {
		return (numeroDeVidas > 0);
	}

	@Override
	public int forcaDeAtaque() {
		return 2 + arma.tipo().danosQueElaCausa();
	}

	@Override
	public String nome() {
		return nome;
	}

	@Override
	public int numeroDeVidasAtual() {
		return numeroDeVidas;
	}

	@Override
	public void registrarObservador(ObservadorDaLuta observador) {
		if (observador == null)
			throw new IllegalArgumentException("O parâmetro 'observador' não pode ser nulo!");
		this.observador = observador;		
	}

	public Tesouro tesouro(){
		return tesouro;
	}

	public Tesouro segurarTesouro(Tesouro tesouro) {
		levantarExcecaoParametroNulo(tesouro, "pocaoDeVida");
		Tesouro tesouroAtual = this.tesouro;
		this.tesouro = tesouro;
		return tesouroAtual;
	}
}
public abstract class Inimigo implements Lutador {
	
	private ObservadorDaLuta observador;
	private final int efetividadeDoGolpe = 50;

	protected static final Random random = new Random();
	
	protected abstract void definirNumeroDeVida(int numeroDeVidas);
		
	protected void revidarGolpe(Jogador jogador){
		jogador.golpeRecebido(this, new Golpe(forcaDeAtaque(), "nenhum", efetividadeDoGolpe));
	}
	
	public void golpeadoPor(Jogador jogador, Golpe golpe){
		if (jogador == null)
			throw new IllegalArgumentException("O parâmetro 'jogador' não pode ser nulo!");
		if (golpe == null)
			throw new IllegalArgumentException("O parâmetro 'golpe' não pode ser nulo!");
		
		int numeroDeVidas = numeroDeVidasAtual() - golpe.danoQueCausa();
		
		definirNumeroDeVida(numeroDeVidas);
		
		if (observador != null)
			observador.notificarAtaqueRecebido(jogador, golpe, golpe.danoQueCausa());
		
		if (estaVivo()) 
			revidarGolpe(jogador);
	}
	
	public void registrarObservador(ObservadorDaLuta observador){
		if (observador == null)
			throw new IllegalArgumentException("O parâmetro 'observador' não pode ser nulo!");
		this.observador = observador;		
	}
	
	@Override
	public boolean estaVivo() {
		return numeroDeVidasAtual() > 0;
	}
}
J

x@ndy:

O problema é a confusão que isso gera e o cuidado que devo ter para evitar esse tipo de problema.
O que o java faz é justamente tirar isso do ombro do programador.

Não existe confusão nenhuma. O grande problema é o estudo. Quando você sabe o que fazer a tarefa é simples.
O fato é que usar java com essas tarefas implícitas acaba nos tornando muito preguiçosos. Eu mesmo já percebi isso, já que uso java profissionalmente. Quando trabalhava com pascal nem sentia o peso dessas tarefas.

X

GilsonNunes:

o cara ai do tal link ta tendo problema pq ele usa o q conta referencia e trata como se não fosse. (é o tipico despreparado)

Boa a sua colocação, então qual o nivel do programador que eu tenho que ter para trabalhar com OO no delphi, para evitar esse tipo de problema?
Lembro que em uma equipe existem programadores de diversos niveis, como evitar esse tipo de problema?

X

juliocbq:
x@ndy:

O problema é a confusão que isso gera e o cuidado que devo ter para evitar esse tipo de problema.
O que o java faz é justamente tirar isso do ombro do programador.

Não existe confusão nenhuma. O grande problema é o estudo. Quando você sabe o que fazer a tarefa é simples.
O fato é que usar java com essas tarefas implícitas acaba nos tornando muito preguiçosos. Eu mesmo já percebi isso, já que uso java profissionalmente. Quando trabalhava com pascal nem sentia o peso dessas tarefas.

Cara, não chamaria de preguiça, sinceramente eu prefiro não me preocupar com isso. Se for preguiça, daqui a pouco todos os programadores que não programam em C são preguiçosos.
Acho que isso é mais uma vantagem da linguagem que qualquer outra coisa.

A confusão a que me refiro é quando você trabalha em equipe. Se você trabalha solo, blz, mas numa equipe nem sempre todos os programadores estão no mesmo nível. Você até pode saber o que está fazendo, mas e os outros da sua equipe. Isso que me refiro quando digo que gera confusão. Se eu implementei não posso ficar confuso né. Agora e os outros membros da equipe estão no mesmo nivel de conhecimento do meu?

O java tirando isso dos ombros do programador facilita enormemente o trabalho. Como disse antes da para trabalhar com OO no Delphi, mas isso mais cuidado que no Java. É claro que com o tempo e experiência isso vai no automático, mas mesmo assim requer mais experiência do que eu teria para fazer em java.

J

x@ndy:
GilsonNunes:

o cara ai do tal link ta tendo problema pq ele usa o q conta referencia e trata como se não fosse. (é o tipico despreparado)

Boa a sua colocação, então qual o nivel do programador que eu tenho que ter para trabalhar com OO no delphi, para evitar esse tipo de problema?
Lembro que em uma equipe existem programadores de diversos niveis, como evitar esse tipo de problema?

Precisa do nível que saiba o básico do desenvolvimento de software. Porque o profissional que não conhece o que é um apontador e que objetos e estruturas primitivas são alocadas em memória não é profissional.
Você colocou aí um ítem muito importante. As escolas ensinam pascal e c nas universidades para que tenham contato com um ambiente computacional real, não um virtual.

Por isso eu sou contra o ensino java inicialmente numa cadeira de computação.

J

x@ndy:
juliocbq:
x@ndy:

O problema é a confusão que isso gera e o cuidado que devo ter para evitar esse tipo de problema.
O que o java faz é justamente tirar isso do ombro do programador.

Não existe confusão nenhuma. O grande problema é o estudo. Quando você sabe o que fazer a tarefa é simples.
O fato é que usar java com essas tarefas implícitas acaba nos tornando muito preguiçosos. Eu mesmo já percebi isso, já que uso java profissionalmente. Quando trabalhava com pascal nem sentia o peso dessas tarefas.

Cara, não chamaria de preguiça, sinceramente eu prefiro não me preocupar com isso. Se for preguiça, daqui a pouco todos os programadores que não programam em C são preguiçosos.
Acho que isso é mais uma vantagem da linguagem que qualquer outra coisa.

A confusão a que me refiro é quando você trabalha em equipe. Se você trabalha solo, blz, mas numa equipe nem sempre todos os programadores estão no mesmo nível. Você até pode saber o que está fazendo, mas e os outros da sua equipe. Isso que me refiro quando digo que gera confusão. Se eu implementei não posso ficar confuso né. Agora e os outros membros da equipe estão no mesmo nivel de conhecimento do meu?

O java tirando isso dos ombros do programador facilita enormemente o trabalho. Como disse antes da para trabalhar com OO no Delphi, mas isso mais cuidado que no Java. É claro que com o tempo e experiência isso vai no automático, mas mesmo assim requer mais experiência do que eu teria para fazer em java.

Você colocou algo importante. Mas é o que eu respondi no meu post anterior. É implicito que um profissional saiba isso. Matéria de escola em estrutura de dados.
Creio que vira preguiça sim. O fato é que ambiente virtual deve ser visto como uma ferramente, não como algo genérico para que não haja alienação.

X

juliocbq:

Para criar software bem modelado não é necessário usar uma linguagem como java. Nem de longe java facilita nesse quesito. Existem implementações em c++ e pascal que dão um banho em muitas que são produzidas em linguagens modernas. Um exemplo disso é o proprio qt. Totalmente MVC.
Para construir software bom você tem que saber o que faz com as ferramentas que utiliza.

Concordo com você, mas o ponto que estou colocando é a facilidade de se implementar. Na verdade a facilidade de se programar usando OO no Delphi e no Java.
No Delphi é possivel sim se criar um sistema OO, mas não é mais fácil fazer isso no Java?
As referencias a objetos e o uso de interfaces são, a meu ver, os maiores problemas, a serem contornados no POO no delphi. Isso exige um conhecimento que a maioria dos programadores não tem!
Assim como se eu quero implementar um sistema DBware, é muito mais fácil fazer isso em Java, do que no Delphi (não estou discutindo se DBware é melhor ou pior do que OO)

X

juliocbq:

Você colocou algo importante. Mas é o que eu respondi no meu post anterior. É implicito que um profissional saiba isso. Matéria de escola em estrutura de dados.
Creio que vira preguiça sim. O fato é que ambiente virtual deve ser visto como uma ferramente, não como algo genérico para que não haja alienação.

Ai que tá, eu aprendi isso na marra, não tive isso em Estrutura de Dados I e II! Mas não quero discutir a falta ou não do conhecimento! O que coloco são as dificuldades de desenvolver usando OO no Delphi ou em outra linguagem que use GC.
Para mim as linguagens são como ferramentas e assim como as ferramentas ela evoluem para facilitar a vida do desenvolvedor. Novas ferramentas trazem novas facilidades e as tornas mais produtivas que as antigas. Isso faz com que possa me preocupar mais com o dominio do meu problema do que com as dificuldades da linguagem.

J

x@ndy:
juliocbq:

Para criar software bem modelado não é necessário usar uma linguagem como java. Nem de longe java facilita nesse quesito. Existem implementações em c++ e pascal que dão um banho em muitas que são produzidas em linguagens modernas. Um exemplo disso é o proprio qt. Totalmente MVC.
Para construir software bom você tem que saber o que faz com as ferramentas que utiliza.

Concordo com você, mas o ponto que estou colocando é a facilidade de se implementar. Na verdade a facilidade de se programar usando OO no Delphi e no Java.
No Delphi é possivel sim se criar um sistema OO, mas não é mais fácil fazer isso no Java?
As referencias a objetos e o uso de interfaces são, a meu ver, os maiores problemas, a serem contornados no POO no delphi. Isso exige um conhecimento que a maioria dos programadores não tem!
Assim como se eu quero implementar um sistema DBware, é muito mais fácil fazer isso em Java, do que no Delphi (não estou discutindo se DBware é melhor ou pior do que OO)

Não é mais fácil nem mais difícil, é a questão do conhecimento. Tem dois engenheiros que trabalham juntamente comigo aqui. Programam em assembly com facilidade de quem programa com java.
Se você sabe usar a ferramenta fica simples.

X

Boa colocação. Como eu sempre digo a ferramenta certa para o problema certo. Manda eles modelarem um sistema que usando OO daria uma dezena de classes em assembly. :smiley:
Vai ser mais “dificil” fazer em qual linguagem? Em qual vai ficar mais pronta mais rápido? Por que tudo que vocẽs tem ai não é feito em assembly?

Como você colocou, você programa em java ai. Então existe problemas ai que não podem ser resolvidos com assembly não é? Ou até podem, mas o trabalho seria infinitamente maior não?
Não estou colocando dificuldade como falta de conhecimento, mas dificulade de usar uma ferramenta quando ela não a é a ideal para o seu projeto.

G

a mesma coisa em pascal:

type
   Lutador = interface
      function estaVivo : boolean;
      function forcaDeAtaque : Integer;
      function nome : string;
      function numeroDeVidasAtual : Integer;
      procedure registrarObservador(observador : ObservadorDaLuta);
  end;
unit uJogador;

interface

uses
  uLutador, Classes, SysUtils;

type
  Jogador = class(TInterfacedPersistent, Lutador)
  private
    numeroDeVidas : Integer;
    fArma : TArma;
    fTesouro : TTesouro; 
    armadura : TArmadura;
    Fnome : string;
    observador : ObservadorDaLuta;
    estrategiaDeCombate : TEstrategiaDeCombate;
  public
    const efetividadeDoGolpe = 80;
  private
    procedure reiniciarNumeroDeVidas;
    procedure levantarExcecaoParametroNulo(parametro : TObject; nomeDoParametro : string);
  public
    constructor Create(nome : string); reintroduce;
    destructor Destroy; override;
    procedure beberPocaoDeVida;
    procedure golpeRecebido(inimigo : TInimigo; golpe : TGolpe);
    procedure golpear(inimigo : TInimigo);
    procedure definirEstrategiaDeCombate(estrategia : EstrategiaDeCombate);
    function segurarArma(arma : TArma) : TArma;
    function vestirArmadura(armadura : TArmadura) : TArmadura;
  public
    function estaVivo: Boolean;
    function forcaDeAtaque: Integer;
    function nome: string;
    function numeroDeVidasAtual: Integer;
    procedure registrarObservador(observador: TObject);
    function segurarTesouro(Tesouro : TTesouro) : TTesouro;
  public
    property Arma : TArma read fArma;
    property Tesouro : TTesouro read fTesouro;
  end;


implementation

{ Jogador }

constructor Jogador.Create(nome : string);
begin
  if Trim(nome) = '' then
    levantarExcecaoParametroNulo(nil, 'O campo nome não pode ser nulo');

  inherited Create;
  fArma := TArma.Create(TipoDeArma.FACA);
  fTesouro := null;
  armadura := TArmadura.Create(TipoDeArmadura.NENHUMA);
  fNnome := nome;
  reiniciarNumeroDeVidas;
end;

destructor Jogador.Destroy;
begin
  fArma.Free;
  armadura.Free;
  inherited;
end;

procedure Jogador.reiniciarNumeroDeVidas;
begin
  numeroDeVidas := 10;
end;

procedure Jogador.levantarExcecaoParametroNulo(parametro: TObject;
  nomeDoParametro: string);
begin
  if parametro = nil then
    raise Exception.CreateFmt('O parâmetro %s não pode ser nulo!', [nomeDoParametro]);
end;

procedure Jogador.beberPocaoDeVida;
begin
  if tesouro is TPocaoDeVida then
  begin
    reiniciarNumeroDeVidas;
    tesouro := nil;
  end;
end;

procedure Jogador.golpeRecebido(inimigo : TInimigo; golpe : TGolpe);
var
  danoCausado : Integer;
begin
  levantarExcecaoParametroNulo(inimigo, 'inimigo');
  levantarExcecaoParametroNulo(golpe, 'golpe');
  danoCausado := golpe.danoQueCausa - armadura.tipo.nivelDeProtecao;

  if danoCausado < 0
    danoCausado = 0;

  Dec(numeroDeVidas, danoCausado);

  if observador <> nil then
    observador.notificarContraAtaqueRecebido(inimigo, golpe, danoCausado);
end;

procedure Jogador.golpear(inimigo : TInimigo);
var
  golpe : TGolpe;
begin
  levantarExcecaoParametroNulo(inimigo, 'inimigo');

  if not estaVivo()) then
    raise IllegalStateException.Create('Operação illegal quando se está morto');

  if estrategiaDeCombate = nil then
    raise ExcecaoEstrategiaNaoDefinida.Create('');

  golpe := estrategiaDeCombate.gerarGolpe(self);
  inimigo.golpeadoPor(Self, golpe);
end;

procedure Jogador.definirEstrategiaDeCombate(estrategia : EstrategiaDeCombate);
begin
  levantarExcecaoParametroNulo(estrategia, 'estrategia');
  estrategiaDeCombate = estrategia;
end;

function Jogador.segurarArma(arma : TArma) : TArma;
begin
  levantarExcecaoParametroNulo(arma, 'arma');

  if arma.tipo.danosQueElaCausa > Self.arma.tipo.danosQueElaCausa() then
  begin
    Result = Self.arma;
    Self.arma = arma;
  end else
    Result = arma;
end;

function Jogador.vestirArmadura(armadura : TArmadura) : TArmadura;
begin
  levantarExcecaoParametroNulo(armadura, 'armadura');

  if armadura.tipo.nivelDeProtecao > Self.armadura.tipo.nivelDeProtecao then
  begin
    Result := Self.armadura;
    Self.armadura := armadura;
  end else
    Result := armadura;
end;

function Jogador.estaVivo: Boolean;
begin
  result := numeroDeVidas > 0;
end;

function Jogador.forcaDeAtaque: Integer;
begin
  Result := 2 + arma.tipo.danosQueElaCausa;
end;

function Jogador.nome: string;
begin
  Result := Self.nome;
end;

function Jogador.numeroDeVidasAtual: Integer;
begin
  Result := numeroDeVidas;
end;

procedure Jogador.registrarObservador(observador: TObject);
begin
  if observador = nil then
    raise IllegalArgumentException.Create('O parâmetro ''observador'' não pode ser nulo!');
  Self.observador := observador;
end;

function Jogador.segurarTesouro(tesouro : TTesouro) : TTesouro;
begin
  levantarExcecaoParametroNulo(tesouro, 'pocaoDeVida');
  Result := Self.tesouro;
  Self.tesouro := tesouro;
end;

end.

sobre não usar o contador de referencia. vc pode usar o TInterfacedPersistent como acima.

nos casos q vc precisa de usar a contagem de referencia é só usar interfacedobject tomando um unico cuidado.
sempre usar referencia do tipo interface pq é a q é contada.

no caso do link o erro tava justamente nisso.

X
GilsonNunes:
a mesma coisa em pascal:
unit uJogador;

interface

uses
  uLutador, Classes, SysUtils;

type
  Jogador = class(TInterfacedPersistent, Lutador)
Então não é só fazer
Jogador = class(Lutador)
Como você havia colocado antes.
GilsonNunes:
nos casos q vc precisa de usar a contagem de referencia é só usar interfacedobject tomando um unico cuidado. sempre usar referencia do tipo interface pq é a q é contada. no caso do link o erro tava justamente nisso.
Era isso que eu queria dizer. Em linguagens com gerenciamento de memória eu não necessito ter esse cuidado. Uma falha ai introduz um erro difícil de encontrar! Isso também introduz outro problema. Ao usar somente referencias do tipo interface eu não posso aumentar a responsabilidade de uma classe. Utilizando o exemplo do jogador eu não poderia fazer isso e ter a contagem de referencia;
public class Armadura implements Tesouro {
	private Random random = new Random();
	private TipoDeArmadura tipoDeArmadura;
	
	private void sortearArmadura(){
		int numeroDeArmaduras = TipoDeArmadura.values().length;
		tipoDeArmadura = TipoDeArmadura.values()[random.nextInt(numeroDeArmaduras - 1) + 1];
	}
	
	public Armadura(){
		sortearArmadura();
	}
	
	public Armadura(TipoDeArmadura tipo){
		if (tipo == null)
			throw new IllegalArgumentException("O parêmetro tipo não pode ser nulo");
		tipoDeArmadura = tipo;
	}
	
	@Override
	public Tesouro transferirPara(Jogador jogador) {
		return jogador.vestirArmadura(this);		
	}

	@Override
	public String nome() {
		return tipoDeArmadura.toString();
	}

	public TipoDeArmadura tipo() {
		return tipoDeArmadura;
	}
}
Nesse caso o eu necessito passar uma referencia a um objeto Jogador, pois ele implementa o método vestirArmadura(Armadura armadura). Não posso também fazer uma cópia. Uma forma de driblar isso em delphi seria passar como uma referência a lutador e fazer um type cast, mas além de aumentar a complexidade não seria o ideal. Uma forma de evitar isso e ter a contagem de referência é seria eu mesmo implementar a contagem de referencia em uma classe e extende-la ao invés de extender interfacedobject, mas isso também aumenta meu trabalho e também pode introduzir erros. Esse é um exemplo simples, na verdade a referencia a jogador se perde ao final de transferirPara(Jogador jogador) de modo que eu nem necessitaria de contagem de referência, mas serve para exemplificar o problema.
J

x@ndy:
juliocbq:

Não é mais fácil nem mais difícil, é a questão do conhecimento. Tem dois engenheiros que trabalham juntamente comigo aqui. Programam em assembly com facilidade de quem programa com java.
Se você sabe usar a ferramenta fica simples.

Boa colocação. Como eu sempre digo a ferramenta certa para o problema certo. Manda eles modelarem um sistema que usando OO daria uma dezena de classes em assembly. :smiley:
Vai ser mais “dificil” fazer em qual linguagem? Em qual vai ficar mais pronta mais rápido? Por que tudo que vocẽs tem ai não é feito em assembly?

Como você colocou, você programa em java ai. Então existe problemas ai que não podem ser resolvidos com assembly não é? Ou até podem, mas o trabalho seria infinitamente maior não?
Não estou colocando dificuldade como falta de conhecimento, mas dificulade de usar uma ferramenta quando ela não a é a ideal para o seu projeto.

Agora você está falando besteira. Assembly e c é para hardware. Utilizamos java e c++ para alto nível.

X

juliocbq:

Agora você está falando besteira. Assembly e c é para hardware. Utilizamos java e c++ para alto nível.

Por que besteira? Quer dizer que eu não posso utilizar C e Assembly para fazer programas em alto nível? Eu mesmo já criei interfaces gráficas para o windows e programas de alto nível utilizando C!
PS:
É necessário apenas ter o conhecimento necessário para fazer o programas de alto nível utilizando C. Com certeza não é uma tarefa fácil, exige um trabalho monstruoso, mas é possivel sim, agora porque eu vou fazer isso em C se existe linguagens e frameworks que já fizeram isso para mim?

G

x@ndy e juliocbq.
obrigado pela troca de informações.

estou aki pra aprender com vcs e juntos crescermos.

eu concordo plenamente q cada ferramenta tem sua utilidade e vc tem q usar a mais adequada.

e concordo q no java é melhor de se trabalhar com OO q no pascal.

porem o q me entristece são os absurdos q se vê por ai.

esses dias eu vi um artigo entitulado “Pascal x Java”

dentre tantas besteiras q vi. uma era Comparando o Object do java com Record do pascal. coisas mt distintas.
dps de acabar com o pascal (coitadinho do record) ele disse q no pascal tb tem o tipo class mas q tava fora do contexto do artigo.

X

GilsonNunes:
x@ndy e juliocbq.
obrigado pela troca de informações.

estou aki pra aprender com vcs e juntos crescermos.
eu concordo plenamente q cada ferramenta tem sua utilidade e vc tem q usar a mais adequada.
e concordo q no java é melhor de se trabalhar com OO q no pascal.


Obrigado também, aprendi coisas novas com você, realmente eu não conhecia o FreeNotifcation.
Como já disse antes, para mim também não existe melhor linguagem de programação, porém eu acredito que o java seja melhor para se programar OO que Delphi. Digo isso porque utilizo Delphi até hoje e tenho alguns sistemas OO modelados nele e o que eu relatei foi justamente os problemas que passei para desenvolve-los. Java também não é a melhor linguagem de programação do mundo (eu pessoalmente ainda não encontrei a melhor linguagem, se é que ela existe). Acho que foi até aqui que coloquei que esses tempos fui desenvolver uma árvore binária em java e vi o quão difici, se torna isso devido a ausência de ponteiros. PS: com dificil, quer dizer trabalhoso.

GilsonNunes:
porem o q me entristece são os absurdos q se vê por ai.
esses dias eu vi um artigo entitulado "Pascal x Java"
dentre tantas besteiras q vi. uma era Comparando o Object do java com Record do pascal. coisas mt distintas.
dps de acabar com o pascal (coitadinho do record) ele disse q no pascal tb tem o tipo class mas q tava fora do contexto do artigo.

:lol: Cara, se tu tiver, posta o link ai. Esse eu não li ainda. Pelo que tu disse da para ver que o cara é um especialista em programação…rsrsrsrs

G

meu prob não resolvido com o java é ele não compilar. só traduzir.

vc arrasta o prog e solta num descompilador(tradutor) ele mostra td seu fonte.

tem solução?

X
GilsonNunes:
meu prob não resolvido com o java é ele não compilar. só traduzir.

vc arrasta o prog e solta num descompilador(tradutor) ele mostra td seu fonte.

tem solução?
Realmente isso pode ser um problema se você distribui sua aplicação e não existe uma solução direta! O que existe são obfuscardores de código. O que eles fazem, resumidamente, é substituir os nomes de variaveis, classes e funções por cadeia de caracteres aleatorias. Também retiram os comentários e a quebra de linha de modo a tornar o código ilegivel. Segue um exemplo abaixo
import javax.swing.JOptionPane;

public class Program1
{
  public static void main(String args[]) {
    String first,second;
    double choice;
    double radius,width,area,length;
    String value = " "; //intialize the string
    value = JOptionPane.showInputDialog("Please chose one of the options:"+"\n"+"a)Enter 1 to calculate the area of the Circle"+"\n"+"b)Enter 2 to calculate the area of the Triangle"+"\n"+"c)Enter 3 to calculate the area of the Square"+"\n"+"d)Enter 4 to calculate the area of the Rectangle"+"\n"+"e)Enter 5 to calculate the area of the Cube"+"\n"+"f)Enter 6 to exit the program");
    choice = Double.parseDouble(value);
    while (choice != 6) {
      //if(choice!=1||choice!=2||choice!=3||choice!=4||choice!=5)
      // JOptionPane.showMessageDialog(null,"Wrong option entered",  " error",
      // JOptionPane.ERROR_MESSAGE);
      if (choice == 1) { //calculate the area of circle
        first = JOptionPane.showInputDialog("Enter the value of radius");
        radius = Double.parseDouble(first);
        area = Math.PI*radius*radius;
        //print out the result
        JOptionPane.showMessageDialog(null,"The area of the Circle:    "+area,"result",JOptionPane.INFORMATION_MESSAGE);
      } else
        if (choice == 2) { //calculate the area of triangle
          first = JOptionPane.showInputDialog("Enter the value of lenght");
          second = JOptionPane.showInputDialog("Enter the value of width");
          length = Double.parseDouble(first);
          width = Double.parseDouble(second);
          area = (width*length)/2;
          JOptionPane.showMessageDialog(null,"The area of triangle:     "+area,"result",JOptionPane.INFORMATION_MESSAGE);
        } else
          if (choice == 3) { //calculate the area of square
            first = JOptionPane.showInputDialog("Enter the value of length");
            length = Double.parseDouble(first); //ge string into integer
            area = length*length;
            JOptionPane.showMessageDialog(null,"The area of the square:    "+area," result",JOptionPane.INFORMATION_MESSAGE);
          } else
            if (choice == 4) { //calculate the area of rectangle
              first = JOptionPane.showInputDialog("Enter the value of length");
              second = JOptionPane.showInputDialog("Enter the value of width");
              length = Double.parseDouble(first);
              width = Double.parseDouble(second);
              area = width*length;
              JOptionPane.showMessageDialog(null,"The area of the rectangle:     "+area,"result",JOptionPane.INFORMATION_MESSAGE);
            } else
              if (choice == 5) { //calculat the area of cube
                first = JOptionPane.showInputDialog("Enter the value of length");
                length = Double.parseDouble(first);
                area = 6*length;
                JOptionPane.showMessageDialog(null,"The area of the cube:  "+area,"result",JOptionPane.INFORMATION_MESSAGE);
              }
      value = JOptionPane.showInputDialog("Please chose one of the options:"+"\n"+"a)Enter 1 to calculate the area of the Circle"+"\n"+"b)Enter 2 to calculate the area of the Triangle"+"\n"+"c)Enter 3 to calculate the area of the Square"+"\n"+"d)Enter 4 to calculate the area of the Rectangle"+"\n"+"e)Enter 5 to calculate the area of the Cube"+"\n"+"f)Enter 6 to exit the program");
      choice = Double.parseDouble(value);
    } //end of while loop
    System.out.println("Program terminated\n");
    System.exit(0);
  } //end of main
}
Após a obfuscação
import javax.swing.JOptionPane;

public class Program1
{
public static void main(String l1[]) {
String l10,O11;
double l100;
double O101,l110,l111,O1000;
String l1001 = " ";
l1001 = JOptionPane.showInputDialog("P\154\145\141se c\150o\163e\040\157ne of the \157\160\164i\157ns:" + "\012" + "\141\051\105\156t\145r\0401\040\164o\040\143alc\165late \164\150e\040\141r\145a\040of \164\150e\040C\151\162c\154e" + "\012" + "b\051Enter 2 t\157\040c\141lc\165l\141\164e the \141\162\145a\040o\146 t\150e\040Tr\151\141n\147\154e" + "\012" + "c\051Enter 3\040t\157 \143a\154\143ulate the ar\145\141 \157\146\040th\145 \123quar\145" + "\012" + "\144)\105\156\164\145r\0404\040t\157\040\143\141\154c\165\154a\164e\040t\150e\040ar\145a\040o\146 \164h\145 R\145c\164a\156g\154e" + "\012" + "\145)\105\156\164\145r\0405\040t\157\040\143\141\154c\165\154a\164\145\040\164h\145 \141\162ea\040o\146\040t\150e\040Cub\145" + "\012" + "\146)\105\156\164e\162 \066 \164o \145xit the p\162\157gr\141m");
l100 = Double.parseDouble(l1001);
while (l100 != 6) {
if (l100 == 1) {
l10 = JOptionPane.showInputDialog("\105n\164\145\162\040t\150e\040v\141\154\165\145\040o\146\040r\141\144iu\163");
O101 = Double.parseDouble(l10);
l111 = Math.PI * O101 * O101;
JOptionPane.showMessageDialog(null, "\124\150\145\040\141r\145a\040of\040\164\150e Ci\162\143l\145\072\040\040 \040" + l111, "result", JOptionPane.INFORMATION_MESSAGE);
} else
if (l100 == 2) {
l10 = JOptionPane.showInputDialog("Ent\145r\040\164\150e\040v\141l\165e \157\146\040\154en\147ht");
O11 = JOptionPane.showInputDialog("\105\156\164\145\162 \164h\145 value of\040width");
O1000 = Double.parseDouble(l10);
l110 = Double.parseDouble(O11);
l111 = (l110 * O1000) / 2;
JOptionPane.showMessageDialog(null, "T\150e area \157f\040t\162i\141\156g\154e:     " + l111, "re\163ult", JOptionPane.INFORMATION_MESSAGE);
} else
if (l100 == 3) {
l10 = JOptionPane.showInputDialog("\105\156\164\145\162 \164h\145 value\040of lengt\150");
O1000 = Double.parseDouble(l10);
l111 = O1000 * O1000;
JOptionPane.showMessageDialog(null, "\124he area \157f \164h\145 \163\161uare:    " + l111, " re\163ul\164", JOptionPane.INFORMATION_MESSAGE);
} else
if (l100 == 4) {
l10 = JOptionPane.showInputDialog("\105\156\164er t\150e\040v\141lu\145\040\157f len\147\164h");
O11 = JOptionPane.showInputDialog("E\156\164er the\040v\141l\165e \157\146 width");
O1000 = Double.parseDouble(l10);
l110 = Double.parseDouble(O11);
l111 = l110 * O1000;
JOptionPane.showMessageDialog(null, "T\150e are\141\040o\146 \164h\145 rectangle:     " + l111, "\162\145\163\165\154t", JOptionPane.INFORMATION_MESSAGE);
} else
if (l100 == 5) {
l10 = JOptionPane.showInputDialog("E\156ter t\150\145\040v\141l\165\145\040of lengt\150");
O1000 = Double.parseDouble(l10);
l111 = 6 * O1000;
JOptionPane.showMessageDialog(null, "T\150e area \157f\040t\150e\040\143\165\142e:  " + l111, "r\145sult", JOptionPane.INFORMATION_MESSAGE);
}
l1001 = JOptionPane.showInputDialog("P\154ease\040\143h\157s\145 \157ne of the options\072" + "\012" + "\141)\105\156\164e\162 \061 \164o c\141\154culat\145\040th\145 \141r\145a \157f\040th\145 \103i\162cl\145" + "\012" + "\142\051\105\156\164e\162 \062 to \143\141lculat\145\040th\145 \141re\141 \157f\040\164h\145 \124r\151an\147le" + "\012" + "c\051\105\156ter 3\040t\157 \143alc\165\154ate th\145\040ar\145a\040of\040t\150\145 \123q\165a\162e" + "\012" + "\144)Ente\162\0404\040t\157 \143alc\165\154ate th\145\040a\162\145\141\040o\146 \164\150e\040R\145c\164a\156g\154e" + "\012" + "\145)Ent\145\162 \065 \164o\040\143\141\154\143ula\164\145 \164\150\145\040a\162ea\040o\146 \164h\145 C\165b\145" + "\012" + "\146)\105\156\164e\162 \066 \164o \145\170it t\150e\040\160r\157\147r\141m");
l100 = Double.parseDouble(l1001);
}
System.out.println("\120r\157\147\162a\155 \164e\162mi\156a\164ed\012");
System.exit(0);
}
}
G

em dois tempos isso é “desofuscado” qse q por completo (Abrir e executar)

dps com a ajuda de um Refatorador vc faz o resto.

rsrs.

“distribui sua aplicação”

como seria pra trabalhar com PAF-ECF por exemplo?

J

x@ndy:
juliocbq:

Agora você está falando besteira. Assembly e c é para hardware. Utilizamos java e c++ para alto nível.

Por que besteira? Quer dizer que eu não posso utilizar C e Assembly para fazer programas em alto nível? Eu mesmo já criei interfaces gráficas para o windows e programas de alto nível utilizando C!
PS:
É necessário apenas ter o conhecimento necessário para fazer o programas de alto nível utilizando C. Com certeza não é uma tarefa fácil, exige um trabalho monstruoso, mas é possivel sim, agora porque eu vou fazer isso em C se existe linguagens e frameworks que já fizeram isso para mim?

Linguagem c é para sistemas, não para aplicações. Você não vai escrever alto nível com c porque a sintaxe foi feita para se fazer o que o assembly faz com recursos mais amigáveis. Você pode até usar um toolkit como gtk(que é escrito em c) mas para fazer aplicações é preferível usar uma ferramenta de alto nível. Eu citei o caso do assembly porque é uma ferramenta que você precisa até mesmo mapear os endereços de memória que vai utilizar para alocar uma variável ali. E o pessoal escreve com a mesma facilidade que eu escrevo java, c++ ou c. Falei do conhecimento objetivando mostrar que, quando você sabe o que fazer não existe tarefa difícil.

G

eu uso assembly pra desenvolver pra microcontrolador/microprocessador.
pq vc usando uma linguagem de nivel um pouco mais alto vc perde mt optimização.

mas agora eu to preferindo as vezes fazer em pascal, dado a complexidade do programa,
e dps fazendo intervenção em pontos mais criticos direto no assembly.
cheguei a fazer um descompilador q implementa uma especie de refatorador pra dps re-montar td já optimizado;

J

GilsonNunes:
meu prob não resolvido com o java é ele não compilar. só traduzir.

vc arrasta o prog e solta num descompilador(tradutor) ele mostra td seu fonte.

tem solução?

Se você usar um obfuscador vai resolver o problema. O proguard é uma ferramenta muito boa para esse tipo de solução.

Você vai ter que configurar alguns parâmetros porque o obfuscamento afeta o funcionamento do software que usa reflection, mas existe toda uma documentação adequada.

O obfuscamento funciona encriptpgrafando nome de classes e variáveis, criando uma tabela de referência.

getIntPoint(int x, y) pode se transformar em algo do tipo xyz(int o, int p);

Aqui, um bom artigo sobre.

J

GilsonNunes:
eu uso assembly pra desenvolver pra microcontrolador/microprocessador.
pq vc usando uma linguagem de nivel um pouco mais alto vc perde mt optimização.

mas agora eu to preferindo as vezes fazer em pascal, dado a complexidade do programa,
e dps fazendo intervenção em pontos mais criticos direto no assembly.
cheguei a fazer um descompilador q implementa uma especie de refatorador pra dps re-montar td já optimizado;

Você pode usar pascal e usar assembly inline para otimizar alguns trechos críticos. Por exemplo, já tive problemas com memcpy da api do proprio win, e consegui contornar o problema criando um similar usando asm inline.

X

GilsonNunes:
em dois tempos isso é “desofuscado” qse q por completo (Abrir e executar)
dps com a ajuda de um Refatorador vc faz o resto.
rsrs.
"distribui sua aplicação"
como seria pra trabalhar com PAF-ECF por exemplo?

Esse foi só um exemplo. Já vi código que fica totalmente ilegível. Refatorar o código não ia ajudar muito, pois você não saberia o que uma função ou variável faz, então renomear e ter algo que faça sentido vai demorar muito, vão ser necessários várias refatorações e muita dedicação e o tempo dedicado sera diretamente proporcional ao tamanho do sistema.

Aplicações web não necessitam de distribuição, por isso que falei se você “distribui sua aplicação”.

X

juliocbq:

Linguagem c é para sistemas, não para aplicações. Você não vai escrever alto nível com c porque a sintaxe foi feita para se fazer o que o assembly faz com recursos mais amigáveis. Você pode até usar um toolkit como gtk(que é escrito em c) mas para fazer aplicações é preferível usar uma ferramenta de alto nível. Eu citei o caso do assembly porque é uma ferramenta que você precisa até mesmo mapear os endereços de memória que vai utilizar para alocar uma variável ali. E o pessoal escreve com a mesma facilidade que eu escrevo java, c++ ou c. Falei do conhecimento objetivando mostrar que, quando você sabe o que fazer não existe tarefa difícil.

Concordo com você principalmente aqui: "Você pode até usar um toolkit como gtk(que é escrito em c) mas para fazer aplicações é preferível usar uma ferramenta de alto nível"
Ferramentas de alto nivel abstraem a complexidade e isso otimiza o trabalho mas não isenta o programador de saber como as coisas funcionam. Por isso que não acho que é preguiça utilizar uma linguagem que use gerenciamento automático de memória.
A meu ver, se estou desenvolvendo um sistema de cobrança, por exemplo, tenho que me preocupar em modelar o sistema da melhor maneira para esse dominio. Ao acrescentar ao projeto o gerenciamento de memória dos objetos desse dominio, estou colocando uma responsabilidade que não faz parte do dominio da aplicação.

G

juliocbq:
GilsonNunes:
eu uso assembly pra desenvolver pra microcontrolador/microprocessador.
pq vc usando uma linguagem de nivel um pouco mais alto vc perde mt optimização.

mas agora eu to preferindo as vezes fazer em pascal, dado a complexidade do programa,
e dps fazendo intervenção em pontos mais criticos direto no assembly.
cheguei a fazer um descompilador q implementa uma especie de refatorador pra dps re-montar td já optimizado;

Você pode usar pascal e usar assembly inline para otimizar alguns trechos críticos. Por exemplo, já tive problemas com memcpy da api do proprio win, e consegui contornar o problema criando um similar usando asm inline.

é isso mesmo.

sobre o ofuscador não é bem uma criptografia é uma troca de nomes. seria o mesmo q eu ja programasse com nomes estranhos (lógico q seria caos).
mas isso é balela pra quem ta acostumado mecher com descompilacao em assembly.
qdo olho pra um codigo java ofuscado eu vejo um codigo melhor q asm32 documentado (só vc ler e dar nomes aos bois com rafator).

M

Alguém sabe dizer se existe alguma ferramenta / framework para testes unitários em Delphi?

X

juliocbq:
GilsonNunes:
eu uso assembly pra desenvolver pra microcontrolador/microprocessador.
pq vc usando uma linguagem de nivel um pouco mais alto vc perde mt optimização.

mas agora eu to preferindo as vezes fazer em pascal, dado a complexidade do programa,
e dps fazendo intervenção em pontos mais criticos direto no assembly.
cheguei a fazer um descompilador q implementa uma especie de refatorador pra dps re-montar td já optimizado;

Você pode usar pascal e usar assembly inline para otimizar alguns trechos críticos. Por exemplo, já tive problemas com memcpy da api do proprio win, e consegui contornar o problema criando um similar usando asm inline.

Como você fez isso? Faz tempo que tentei acessar a porta paralela utilizando assembly inline e não consegui por que o windows estava bloqueando. Eu até conseguia fazer funcionar com o Win98, mas a partir do XP começou a bloquear! Como não era nada importante não fui atrás para saber o que aconteceu!

X

Ai você tem razão, se o cara é bom em descompilar em assembly, não vai fazer muita diferença. Mas isso não é qualquer um que faz isso né…

J

x@ndy:
juliocbq:

Linguagem c é para sistemas, não para aplicações. Você não vai escrever alto nível com c porque a sintaxe foi feita para se fazer o que o assembly faz com recursos mais amigáveis. Você pode até usar um toolkit como gtk(que é escrito em c) mas para fazer aplicações é preferível usar uma ferramenta de alto nível. Eu citei o caso do assembly porque é uma ferramenta que você precisa até mesmo mapear os endereços de memória que vai utilizar para alocar uma variável ali. E o pessoal escreve com a mesma facilidade que eu escrevo java, c++ ou c. Falei do conhecimento objetivando mostrar que, quando você sabe o que fazer não existe tarefa difícil.

Concordo com você principalmente aqui: "Você pode até usar um toolkit como gtk(que é escrito em c) mas para fazer aplicações é preferível usar uma ferramenta de alto nível"
Ferramentas de alto nivel abstraem a complexidade e isso otimiza o trabalho mas não isenta o programador de saber como as coisas funcionam. Por isso que não acho que é preguiça utilizar uma linguagem que use gerenciamento automático de memória.
A meu ver, se estou desenvolvendo um sistema de cobrança, por exemplo, tenho que me preocupar em modelar o sistema da melhor maneira para esse dominio. Ao acrescentar ao projeto o gerenciamento de memória dos objetos desse dominio, estou colocando uma responsabilidade que não faz parte do dominio da aplicação.


Sim, mas é válido quando você sabe como as coisas funcionam. Esse é o ponto. Você quer escrever um programa em pascal ou c++, ótimo, mas saiba como. A mesma idéia serve para qualquer outra ferramenta mesmo que seja de baixo nível. É questão de know how como dizem.

J

x@ndy:
juliocbq:
GilsonNunes:
eu uso assembly pra desenvolver pra microcontrolador/microprocessador.
pq vc usando uma linguagem de nivel um pouco mais alto vc perde mt optimização.

mas agora eu to preferindo as vezes fazer em pascal, dado a complexidade do programa,
e dps fazendo intervenção em pontos mais criticos direto no assembly.
cheguei a fazer um descompilador q implementa uma especie de refatorador pra dps re-montar td já optimizado;

Você pode usar pascal e usar assembly inline para otimizar alguns trechos críticos. Por exemplo, já tive problemas com memcpy da api do proprio win, e consegui contornar o problema criando um similar usando asm inline.

Como você fez isso? Faz tempo que tentei acessar a porta paralela utilizando assembly inline e não consegui por que o windows estava bloqueando. Eu até conseguia fazer funcionar com o Win98, mas a partir do XP começou a bloquear! Como não era nada importante não fui atrás para saber o que aconteceu!

Você só pode ler e escrever em registradores que não setam interrupções. As versões mais recentes do windows possuem uma máquina virtual que não te deixa escrever neles como medida de proteção.
No caso do memcpy é simplesmente mover valores em endereços de memória.

Se for fazer uma comparação de arquitetura, os sistemas POSIX(portable operating system interface) são bem melhores para programação de sistemas, pois todo dispositivo é um arquivo.

Ex: enviar dados na porta serial simplesmente abrindo o arquivo /dev/ttyx:

x = open("/dev/ttyx", O_RDWR)
x << “teste”;

ler do teclado ou hd, usb, porta setial é sempre a mesma coisa

open("/dev/device", O_RDWR);

já que dispositivos ou são dispositivos de caracteres(teclado, mouse, etc…) ou blocos(hd, usb e qualquer dispo de armazenamento).

Já com windows precisa da api da microsof, ou seja, um parto.

G

x@ndy:
juliocbq:
GilsonNunes:
eu uso assembly pra desenvolver pra microcontrolador/microprocessador.
pq vc usando uma linguagem de nivel um pouco mais alto vc perde mt optimização.

mas agora eu to preferindo as vezes fazer em pascal, dado a complexidade do programa,
e dps fazendo intervenção em pontos mais criticos direto no assembly.
cheguei a fazer um descompilador q implementa uma especie de refatorador pra dps re-montar td já optimizado;

Você pode usar pascal e usar assembly inline para otimizar alguns trechos críticos. Por exemplo, já tive problemas com memcpy da api do proprio win, e consegui contornar o problema criando um similar usando asm inline.

Como você fez isso? Faz tempo que tentei acessar a porta paralela utilizando assembly inline e não consegui por que o windows estava bloqueando. Eu até conseguia fazer funcionar com o Win98, mas a partir do XP começou a bloquear! Como não era nada importante não fui atrás para saber o que aconteceu!

eu não desenvolvo app pra comunicar com o PIC, eu desenvolvo o SO q vai rodar no PIC.

G

tipo:

;***************************************************************************************************************************
;*					Projeto: Automação com inteligencia (PIC 'A' comunicação com o PC)                                     *
;*					desenvolvido por: Gilson Nunes Para: Futura Soluções  						                           *
;***************************************************************************************************************************

;CRISTAL: 4MHz

;******************************** DEFINIÇÕES INICIAIS **********************************************************************
	INCLUDE <P16F877A.INC>  
	
	__CONFIG _CP_OFF & _DEBUG_OFF & _WRT_OFF  & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC 

	ERRORLEVEL -302		
;******************************** DECLARAÇÕES DE VARIAVEIS *****************************************************************

#DEFINE			BANCO_0 bcf status,rp0
#DEFINE			BANCO_1 bSf status,rp0
#DEFINE	LCD		PORTB			   	

#DEFINE	SET_RAM 	PORTC,0			
#DEFINE	E_RAM		PORTC,1			
#DEFINE	L_RAM		PORTC,5			
#DEFINE DADO_RAM	PORTD
X
juliocbq:
Se for fazer uma comparação de arquitetura, os sistemas POSIX(portable operating system interface) são bem melhores para programação de sistemas, pois todo dispositivo é um arquivo.

Ex: enviar dados na porta serial simplesmente abrindo o arquivo /dev/ttyx:

x = open("/dev/ttyx", O_RDWR)
x << "teste";

ler do teclado ou hd, usb, porta setial é sempre a mesma coisa

open("/dev/device", O_RDWR);

já que dispositivos ou são dispositivos de caracteres(teclado, mouse, etc..) ou blocos(hd, usb e qualquer dispo de armazenamento).

Já com windows precisa da api da microsof, ou seja, um parto.

Nunca tive a necessidade de acessar outros dispositivos além da porta serial e para algumas coisas a porta paralela. Mas para serial também acesso abrindo um arquivo:
FHandlePort := CreateFile(PChar(Format('COM%d',[FPort])),
      GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0, 0);
Agora para configurar os parâmetros de taxa de transferencia, bits de parada, etc, só acessando a API mesmo.
procedure TdtCustomSerialComm.SetupDCB;
var
  DCB: TDCB;
begin
  if FActive and not (csDesigning in ComponentState) then
  begin
    if not GetCommState(FHandlePort, DCB) then
      raise ESeriamComm.Create(SysErrorMessage(GetLastError));

    DCB.BaudRate := FBaudRate;

    DCB.Flags := 1;

    if FParity <> prNone then
      DCB.Flags := DCB.Flags or 2;

    DCB.Parity := Byte(FParity);

    case FFlowControl of
      fcNone: DCB.Flags := DCB.Flags or 0;
      fcXOnXOff: DCB.Flags := DCB.Flags or 896;
      fcRtsCts: DCB.Flags := DCB.Flags or 8196;
      fcDtrDsr: DCB.Flags := DCB.Flags or 40;
    end;

    case FStopBits of
      1: DCB.StopBits := 0;
      2: DCB.StopBits := 2;
    end;

    DCB.ByteSize :=  FDataBits;
    DCB.XONChar := FXONChar;
    DCB.XOFFChar := FXOFFChar;
    DCB.XONLim := FRxBuffer * FXOnLimDiv div 100;
    DCB.XOFFLim := FRxBuffer * FXoffLimDiv div 100;

    if not SetCommState(FHandlePort, DCB) then
      raise ESeriamComm.Create(SysErrorMessage(GetLastError));
  end;
end;
Como essas configurações são feitas em sistemas posix, como no linux?
J
GilsonNunes:
tipo:
;***************************************************************************************************************************
;*					Projeto: Automação com inteligencia (PIC 'A' comunicação com o PC)                                     *
;*					desenvolvido por: Gilson Nunes Para: Futura Soluções  						                           *
;***************************************************************************************************************************

;CRISTAL: 4MHz

;******************************** DEFINIÇÕES INICIAIS **********************************************************************
	INCLUDE <P16F877A.INC>  
	
	__CONFIG _CP_OFF & _DEBUG_OFF & _WRT_OFF  & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC 

	ERRORLEVEL -302		
;******************************** DECLARAÇÕES DE VARIAVEIS *****************************************************************

#DEFINE			BANCO_0 bcf status,rp0
#DEFINE			BANCO_1 bSf status,rp0
#DEFINE	LCD		PORTB			   	

#DEFINE	SET_RAM 	PORTC,0			
#DEFINE	E_RAM		PORTC,1			
#DEFINE	L_RAM		PORTC,5			
#DEFINE DADO_RAM	PORTD

Você não acha desperdício de tempo usar assembly num pic parrudo como o 16f877? O compilador da microship além de falcilitar pode otimizar o código que uma pessoa levaria dias para fazer.

J

GilsonNunes:

eu não desenvolvo app pra comunicar com o PIC, eu desenvolvo o SO q vai rodar no PIC.

SO não, firmware, ok?
O seu software não organiza processos de outros programas, nem organiza sistema de arquivos ou paginação deles na ram.

J
x@ndy:
Como essas configurações são feitas em sistemas posix, como no linux?
Você pode fazer um bind diretamente entre a serial e o console por exemplo: Dessa maneira tudo que chega na porta é redirecionado para o console
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
 
int main(int argc,char** argv)
{
        struct termios tio;
        struct termios stdio;
        int tty_fd;
        fd_set rdset;
 
        unsigned char c='D';
 
        printf("Please start with %s /dev/ttyS1 (for example)\n",argv[0]);
        memset(&stdio,0,sizeof(stdio));
        stdio.c_iflag=0;
        stdio.c_oflag=0;
        stdio.c_cflag=0;
        stdio.c_lflag=0;
        stdio.c_cc[VMIN]=1;
        stdio.c_cc[VTIME]=0;
        tcsetattr(STDOUT_FILENO,TCSANOW,&stdio);
        tcsetattr(STDOUT_FILENO,TCSAFLUSH,&stdio);
        fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);       // make the reads non-blocking
 
 
 
 
        memset(&tio,0,sizeof(tio));
        tio.c_iflag=0;
        tio.c_oflag=0;
        tio.c_cflag=CS8|CREAD|CLOCAL;           // 8n1, see termios.h for more information
        tio.c_lflag=0;
        tio.c_cc[VMIN]=1;
        tio.c_cc[VTIME]=5;
 
        tty_fd=open(argv[1], O_RDWR | O_NONBLOCK);      
        cfsetospeed(&tio,B115200);            // 115200 baud
        cfsetispeed(&tio,B115200);            // 115200 baud
 
        tcsetattr(tty_fd,TCSANOW,&tio);
        while (c!='q')
        {
                if (read(tty_fd,&c,1)>0)        write(STDOUT_FILENO,&c,1);              // if new data is available on the serial port, print it out
                if (read(STDIN_FILENO,&c,1)>0)  write(tty_fd,&c,1);                     // if new data is available on the console, send it to the serial port
        }
 
        close(tty_fd);
}

Tem um wiki book de onde eu tirei esse exemplo

http://en.wikibooks.org/wiki/Serial_Programming/Serial_Linux

G

o compilador da microship compila pascal?

G

chamei de SO usufluindo da licênça poética pra facilitar a analogia;

L

credo lazarus, isso ainda existe?? Lamentavel.

G

tabem acho lamentável!

mas e vc, prefere o q e substituição a ele? Creio q não seja c, c++, delphi ou coisa do tipo

J

GilsonNunes:
o compilador da microship compila pascal?

Existe o PMP, mas nunca usei.

http://www.pmpcomp.fr/

J

tabem acho lamentável!

mas e vc, prefere o q e substituição a ele? Creio q não seja c, c++, delphi ou coisa do tipo

não alimente trolls. Com aquele avatar é inegável que seja um.

L

tabem acho lamentável!

mas e vc, prefere o q e substituição a ele? Creio q não seja c, c++, delphi ou coisa do tipo

não alimente trolls. Com aquele avatar é inegável que seja um.

troll e sua M@# seu boboca, vc deve ser um profissional frustrado e mediocre, por isso fica chamando os outros de trolls, qual o problema de eu achar o lazarus lamentave? è so a minha opiniao, vc tem a sua e eu a minha, e com certeza prefiro delphi a lazarus.

C

Bom, acredito que a evolução do FreePascal/Lazarus e Delphi é grande, o que esta faltando e aqui neste forum é falta de conhecimento das plataforma de desenvolvimento. Estão dizendo sobre componentes que falta, faça pesquisa na internet, busque informações.
Pois se até a Própria Embarcadeiro está usando o FreePascal para compilar seus aplicativos no Mac. O que parece é que estão esperando o prato feito, pronto na mesa.

C

Bom, acredito que a evolução do FreePascal/Lazarus e Delphi é grande, o que esta faltando e aqui neste forum é falta de conhecimento das plataforma de desenvolvimento. Estão dizendo sobre componentes que falta, faça pesquisa na internet, busque informações.
Pois se até a Própria Embarcadeiro está usando o FreePascal para compilar seus aplicativos no Mac. O que parece é que estão esperando o prato feito, pronto na mesa.

P

essa parada ainda nao morreu?

Criado 14 de julho de 2011
Ultima resposta 25 de jul. de 2012
Respostas 128
Participantes 10