segunda-feira, 31 de janeiro de 2011

Desbloqueio de Samsung Galaxy S

Update na parte de cima porque tem gente que não sabe ler: 

Recebo uma quantidade absurda de mimimi de gente que não sabe usar um celular e vem desesperado me perguntar o que fazer, então, atenção para algumas regrinhas básicas:

1) Esse procedimento necessita de um reset de fábrica, ou factory reset no seu celular.
2) Todos os seus dados, videos, arquivos e bugigangas serão apagados irrecuperavelmente.
3) Não me responsabilizo por danos causados no seu aparelho.
4) Se não se sentir seguro ou não tiver conhecimento técnico suficiente, ou não entendeu alguma palavra do que eu disse, NÃO FAÇA O PROCEDIMENTO.
5) Isso é um blog, não um fórum.
6) Isso é um blog, E NÃO UM FÓRUM POW!.
7) O procedimento foi realizado com um Samsung Galaxy S, versão 2.1 do Android, modelo GT-I9000B, kernel 2.6.29, n° de compilação ECLAIR.VJJG9. Nunca fiz o procedimento em outro aparelho, nunca nem vi outro. Portanto se o seu aparelho for UM MILÍMETRO, UMA LETRINHA, diferente desse, NÃO ME PERGUNTE, EU NÃO SEI, NÃO TENTE FAZER O PROCEDIMENTO.
8) Eu não sou funcionário, técnico, atendente ou SAC da samsung. Se quiser o SAC da samsung está aqui: http://www.samsung.com/br/
9) Existe um grande site, que pode resolver todas as suas dúvidas e te ajudar a desbloquear qualquer celular, é este aqui http://migre.me/5gLGb
10) Se não sabe o que é Android ou não tem conta no google, faça o favor: nem tente.

Quando comprei um Samsung Galaxy S com linha da VIVO eu ainda tinha um chip pré-pago da OI, e tinha optado por fazer a portabilidade do meu número. Mas como a portabilidade demoraria uns 5 dias, eu queria já usar o meu celular novo, e tentei colocar nele o chip da OI. Nada feito. O sistema estava bloqueado pela VIVO e pedia pin e tal. Mas nem o pin da VIVO nem o da OI servia.
Fiquei com minha linha no chip da OI que não funcionava no celular novo, e o chip novo da VIVO que ainda não tinha meu número, e iria demorar 5 dias. O que fazer? Voltar para o celular antigo por 5 dias?

Para usar meu chip da OI nesses 5 dias no meu celular VIVO tive que fazer o que por lei seria obrigação das lojas e operadoras, mas que eles não fazem por negligência, incompetência e claro desrespeito às leis.

Primeiro de tudo leia esse post http://vitorrubio.blogspot.com/2011/01/dicas-e-codigos-para-celulares.html para saber alguns códigos úteis para seu celular, como o reset de fábrica, por exemplo.


Baixe o programa sgs unlock pelo android market, ou via rapidshare nesse link http://piratamania.com/desbloquear-samsung-galaxy-s-tmn/ (particularmente eu usei  o market)
rodar o programa e no botão do menu escolher uma das opções, com ou sem root. (dá pra fazer sem root) Você receberá dois códigos de 8 digitos, um de unlock e um de unfreeze. Anote-os.

Desligue o celular, tire o chip dele (por ex.: vivo) e coloque o seu chip de outra operadora (por ex.: oi) e quando ligar novamente pedirá o código para desbloqueio de rede sim.

Use o código "unlock" anotado do programa. Caso não funcione execute no discador o código para resetar e *2767*3855# e quando ligar (reboot) coloque o código de "unlock".

Pronto, seu chip pre-pago da OI está pronto para ser usado no seu celular novo, agora desbloqueado, até que a portabilidade ocorra. Depois é só colocar seu chip novo.

Dicas e códigos para celulares

Código para ver se a rede está bloqueada (faça no teclado numérico do discador)
*#7465625#

Com isso aparecerá uma lista de opções e se cada uma delas está bloqueada ou não.


Código para resetar a rede (no discador)
*2767*3855# (isso dará um factory reset no celular, apagando suas configurações e apps salvas)

Código para mudar o pin do seu chip:
* * 04 * pin atual * pin novo * pin novo#



Obtendo o IMEI:

Para bloquear o celular em caso de roubo:
O imei vem anotado em um código barras abaixo da bateria, na parte de dentro, mas você pode discar *#06# que o imei aparecerá. Anote esse número. Caso seu celular seja roubado, ligue na operadora ou na anatel e peça para bloquear esse imei. O ladrão não vai poder usar esse celular nem trocando o chip.




Códigos padrões de pins de operadoras
TIM - 1010
Claro - 3636
OI - 8888
BrT GSM - 1414
Amaz/Telemig - 1414
CTBC - 1212
VIVO - 8486


Também podem ser usados como padrão:
0000
00000
1234
12345


Fontes

Existem 1001 maneiras de preparar SINGLETON - parte2

No último post desta série mostramos como preparar um singleton que funciona tanto em Delphi como em Lazarus.

Neste post veremos como criar um singleton mais elegante que funcione sem métodos ou variáveis estáticas. Usaremos class vars e class methods para isso. Porém a lógica será a mesma do exemplo anterior.

Objeto Único:

unit uSingleton;

interface

uses
  DateUtils, SysUtils, Windows, dialogs;

type



  TObjetoUnico = class
  private
    FDataHora: string;
    class var  FObjetoUnico: TObjetoUnico;
    class var  FContador: Integer;
    class function GetObjetoUnico: TObjetoUnico; static;
    class function GetContador: integer; static;
  public
    constructor Create;
    destructor Destroy; override;
    function GetDataHora: string; virtual;

    class property ObjetoUnico:  TObjetoUnico read GetObjetoUnico;
    class property Contador: integer read GetContador;
    property DataHora: string read GetDataHora write FDataHora;
  end;

procedure VerificaObjetoUnicoCriado;

implementation


procedure VerificaObjetoUnicoCriado;
begin
  //Uso do FObjetoUnico aqui porque se usasse ObjetoUnico o método acessor
  //GetObjetoUnico seria automaticamente executado, criando o objeto
  if (TObjetoUnico.FContador >= 1) and (TObjetoUnico.FObjetoUnico <> nil) then
    ShowMessage('=========== verificação ===========' + #13#10 +
    'Nome da classe: ' + TObjetoUnico.FObjetoUnico.ClassName+ #13#10 +
    'Hora de Criação: ' + TObjetoUnico.FObjetoUnico.DataHora + #13#10 +
    'Endereço na memória: ' + IntToStr(Integer(TObjetoUnico.FObjetoUnico))
  );
end;


{ TObjetoUnico }

constructor TObjetoUnico.Create;
begin

    //essa verificação impede uma segunda chamada a create
    //se não verificar, ou se deixar crar para se disparar a excessão depois
    //da verificação corre-se o risco de ter criado mais um antes da excessão
    //e aí não será possível destruir, causando um leak
    if (FContador = 0) and (FObjetoUnico = nil) then
    begin
      inherited Create;  //aqui tudo bem usar o inherited create e destroy porque a classe base não faz nada de mais
      InterlockedIncrement(FContador);
      DataHora := FormatDateTime('yyyy-mm-dd hh:nn:ss', now);
    end
    else
      raise Exception.Create('Ei! Não use esse constructor, use o CreateUnico!');
    //o inherited fica dentro do if assim o objeto não será criado caso ja esteja o contador > 0

end;



destructor TObjetoUnico.Destroy;
begin

  FObjetoUnico := nil;
  InterlockedDecrement(FContador);
  inherited;

end;

class function TObjetoUnico.GetContador: integer;
begin
  Result := FContador;
end;

function TObjetoUnico.GetDataHora: string;
begin
  Result := FDataHora;
end;



//como a propriedade  ObjetoUnico executa esse get e esse get le o class var e
//o instancia caso seja nil a propriedade ObjetoUnico tem uma proteção
//natural contra nil e sempre será instanciada, nunca será igual a nil
class function TObjetoUnico.GetObjetoUnico: TObjetoUnico;
begin
  //aqui a mesma verificação é feita para não se executar o create duas vezes
  //mas devolver o objeto existente ou devolvê-lo assim que criado
  if (FContador = 0) and (FObjetoUnico = nil) then
    FObjetoUnico := TObjetoUnico.Create;
  Result := FObjetoUnico;
end;

initialization
  //a initilization não é necessária

finalization
  if (TObjetoUnico.FObjetoUnico <> nil) then
  try
    //leia o comentário abaixo para saber porque o campo privado FObjetoUnico
    //é usado aqui em vez da propriedade ObjetoUnico
    TObjetoUnico.FObjetoUnico.Free;
  except
    //tratamento de excessão
  end;

  //por causa da proteção "natural" contra nil você pode destruir
  //o singleton com
  //TObjetoUnico.ObjetoUnico.Free;
  //mas isso causa um overhead porque se o FObjetoUnico não estiver criado (nil)
  //ele será criado só para ser destruído.
  //É bonito de se ver, mas feio do ponto de vista do algoritmo

end.

Objeto Único Derivado:

unit uSingletonDerivado;

interface

uses
  uSingleton, SysUtils, DateUtils, Windows, dialogs;

type


  TObjetoUnicoDerivado = class(TObjetoUnico)
  private
    class var FObjetoUnico: TObjetoUnicoDerivado;
    class var  FContador: Integer;
    class function GetContador: integer; static;
    class function GetObjetoUnico: TObjetoUnicoDerivado;  static;
  public
    destructor Destroy; override;
    constructor Create; reintroduce;   

    class property ObjetoUnico: TObjetoUnicoDerivado  read GetObjetoUnico;
    class property Contador: integer read GetContador;
    function GetDataHora: string; override;

    property DataHora: string read GetDataHora;
  end;

 

procedure VerificaObjetoUnicoDerivadoCriado;

implementation



procedure VerificaObjetoUnicoDerivadoCriado;
begin
  if (TObjetoUnicoDerivado.FContador >= 1) and (TObjetoUnicoDerivado.FObjetoUnico <> nil) then
    ShowMessage('=========== verificação ===========' + #13#10 +
    'Nome da classe: ' + TObjetoUnicoDerivado.ObjetoUnico.ClassName+ #13#10 +
    'Hora de Criação pelo método: ' + TObjetoUnicoDerivado.ObjetoUnico.GetDataHora + #13#10 +
    'Hora de Criação pela propriedade: ' + TObjetoUnicoDerivado.ObjetoUnico.DataHora + #13#10 +
    'Endereço na memória: ' + IntToStr(Integer(TObjetoUnicoDerivado.ObjetoUnico))
  );
end;


{ TObjetoUnicoDerivado }


constructor TObjetoUnicoDerivado.Create;
begin
    if (FContador = 0) and (FObjetoUnico = nil) then
    begin
      InterlockedIncrement(FContador);
      DataHora := FormatDateTime('yyyy-mm-dd hh:nn:ss', now);
    end
    else
      raise Exception.Create('Ei! Não use esse constructor, use o CreateUnico!');
end;


destructor TObjetoUnicoDerivado.Destroy;
begin
  FObjetoUnico := nil;
  InterlockedDecrement(FContador);
end;

class function TObjetoUnicoDerivado.GetContador: integer;
begin
  Result := FContador;
end;



function TObjetoUnicoDerivado.GetDataHora: string;
begin
  Result := 'acréscimo ' + inherited;
end;


class function TObjetoUnicoDerivado.GetObjetoUnico: TObjetoUnicoDerivado;
begin
  if (FContador = 0) and (FObjetoUnico = nil) then
    FObjetoUnico := TObjetoUnicoDerivado.Create;
  Result := FObjetoUnico;
end;


initialization

finalization
  //aqui há um exemplo de como o objeto único pode ser destruido
  TObjetoUnicoDerivado.FObjetoUnico.Free;

end.


Os testes podem ser feitos da mesma maneira que o exemplo anterior:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Menus, uSingleton, uSingletonDerivado;

type


  TfrmUmaInstancia = class(TForm)
    btUnico: TButton;
    btDerivado: TButton;
    btVerificaUnico: TButton;
    btVerificaDerivado: TButton;
    procedure btUnicoClick(Sender: TObject);
    procedure btDerivadoClick(Sender: TObject);
    procedure btVerificaUnicoClick(Sender: TObject);
    procedure btVerificaDerivadoClick(Sender: TObject);
  public
  end;



var
  frmUmaInstancia: TfrmUmaInstancia;

implementation



{$R *.dfm}



procedure TfrmUmaInstancia.btDerivadoClick(Sender: TObject);
var FObjetoUnico: TObjetoUnicoDerivado;
begin
  //veja que é possivel executar o create
  //Mas dessa forma não é garantido que o objeto seja unico
  //para garantir que seja único é imprescindível o uso do método  CreateUnico

  FObjetoUnico := TObjetoUnicoDerivado.ObjetoUnico;

  //mostrando a classe do objeto, hora de criação e endereço do objeto
  //veja que é sempre igual
  ShowMessage('Nome da classe: ' + FObjetoUnico.ClassName+ #13#10 +
    'Hora de Criação: ' + FObjetoUnico.DataHora + #13#10 +
    'Endereço na memória: ' + IntToStr(Integer(FObjetoUnico))
  );

end;

procedure TfrmUmaInstancia.btUnicoClick(Sender: TObject);
var FObjetoUnico: TObjetoUnico;
begin

  //veja que é possivel executar o create
  //Mas dessa forma não é garantido que o objeto seja unico
  //para garantir que seja único é imprescindível o uso do método  CreateUnico

  FObjetoUnico := TObjetoUnico.ObjetoUnico;

  //mostrando a classe do objeto, hora de criação e endereço do objeto
  //veja que é sempre igual
  ShowMessage('Nome da classe: ' + FObjetoUnico.ClassName+ #13#10 +
    'Hora de Criação: ' + FObjetoUnico.DataHora + #13#10 +
    'Endereço na memória: ' + IntToStr(Integer(FObjetoUnico))
  );

end;




procedure TfrmUmaInstancia.btVerificaDerivadoClick(Sender: TObject);
begin
  VerificaObjetoUnicoDerivadoCriado;
end;

procedure TfrmUmaInstancia.btVerificaUnicoClick(Sender: TObject);
begin
  VerificaObjetoUnicoCriado;
end;

end.


Da mesma forma que o primeiro exemplo, todos os métodos devem ser re-escritos, e praticamente substituidos sem menção ou referência a inherited. Um override completo.
O único método que pode ser aproveitar dos dois lados do polimorfismo (herdar um método, modificá-lo com override mas ainda assim aproveitar-se de parte do código do método ancestral) e agregar alguma coisa nova no código antigo é o GetDataHora, que é público e virtual.

Também é possível que GetDataHora seja privado, como geralmente um método acessor no Delphi deve ser, mas se crie um novo na classe derivada para servir de método acessor à nova propriedade DataHora. E a DataHora do objeto ancestral pode ser obtida com inherited.
Passamos o método GetDataHora para private tanto no TObjetoUnico como no TObjetoUnicoDerivado, e este método não será mais virtual ou dinâmico nem será mais sobrescrito.

TObjetoUnico = class
  private
    FDataHora: string;
    class var  FObjetoUnico: TObjetoUnico;
    class var  FContador: Integer;
    class function GetObjetoUnico: TObjetoUnico; static;
    class function GetContador: integer; static;
    function GetDataHora: string;

  public
    constructor Create;
    destructor Destroy; override;

    class property ObjetoUnico:  TObjetoUnico read GetObjetoUnico;
    class property Contador: integer read GetContador;
    property DataHora: string read GetDataHora write FDataHora;
  end;

{...}

  TObjetoUnicoDerivado = class(TObjetoUnico)
  private
    class var FObjetoUnico: TObjetoUnicoDerivado;
    class var  FContador: Integer;
    class function GetContador: integer; static;
    class function GetObjetoUnico: TObjetoUnicoDerivado;  static;
    function GetDataHora: string;
  public
    constructor Create; reintroduce;
    destructor Destroy; override;

    class property ObjetoUnico: TObjetoUnicoDerivado  read GetObjetoUnico;
    class property Contador: integer read GetContador;
    property DataHora: string read GetDataHora;

  end;

Mas o método GetDataHora do TObjetoUnicoDerivado é diferente. E ele consegue substituir o acessor da propriedade DataHora mesmo que esta propriedade não esteja declarada no TObjetoUnicoDerivado e não tenhamos um FDataHora. Fazemos isso por usar o inherited de DataHora, onde é possível obter o valor ancestral de DataHora.

function TObjetoUnicoDerivado.GetDataHora: string;
begin
Result := 'acréscimo ' + inherited DataHora;
end;

O ponto fraco dessa abordagem é que se você tiver um objeto TObjetoUnicoDerivado instanciado em uma variável TObjetoUnico, o GetDataHora que será executado é o do TObjetoUnico e não o do TObjetoUnicoDerivado. A única forma de se resolver isso é tornar GetDataHora público e virtual. Assim ele pode ser "sobrescrito" e mesmo uma variável TObjetoUnico pode referenciar o método GetDataHora correto caso este seja um TObjetoUnicoDerivado. Mas a única maneira de se fazer isso sem gerar um access violation caso o método ou propriedade referenciados ainda não estejam na memória ou ainda não tenham sido sobrescritos é retirar do singleton derivado a propriedade DataHora e sobrescrever o método GetDataHora. Somente assim a propriedade DataHora lerá o acessor GetDataHora mesmo em um TObjetoUnicoDerivado instanciado em uma variável do tipo TObjetoUnico.

Ou seja, o final da brincadeira ficará assim:

unit uSingleton;

interface

uses
  DateUtils, SysUtils, Windows, dialogs;

type



  TObjetoUnico = class
  private
    FDataHora: string;
    class var  FObjetoUnico: TObjetoUnico;
    class var  FContador: Integer;
    class function GetObjetoUnico: TObjetoUnico; static;
    class function GetContador: integer; static;


  public
    constructor Create;
    destructor Destroy; override;
    function GetDataHora: string; virtual;

    class property ObjetoUnico:  TObjetoUnico read GetObjetoUnico;
    class property Contador: integer read GetContador;
    property DataHora: string read GetDataHora write FDataHora;
  end;

procedure VerificaObjetoUnicoCriado;

implementation


procedure VerificaObjetoUnicoCriado;
begin
  //Uso do FObjetoUnico aqui porque se usasse ObjetoUnico o método acessor
  //GetObjetoUnico seria automaticamente executado, criando o objeto
  if (TObjetoUnico.FContador >= 1) and (TObjetoUnico.FObjetoUnico <> nil) then
    ShowMessage('=========== verificação ===========' + #13#10 +
    'Nome da classe: ' + TObjetoUnico.FObjetoUnico.ClassName+ #13#10 +
    'Hora de Criação pelo método: ' + TObjetoUnico.FObjetoUnico.GetDataHora + #13#10 +
    'Hora de Criação pela propriedade: ' + TObjetoUnico.FObjetoUnico.DataHora + #13#10 +
    'Endereço na memória: ' + IntToStr(Integer(TObjetoUnico.FObjetoUnico))
  );
end;


{ TObjetoUnico }

constructor TObjetoUnico.Create;
begin

    //essa verificação impede uma segunda chamada a create
    //se não verificar, ou se deixar crar para se disparar a excessão depois
    //da verificação corre-se o risco de ter criado mais um antes da excessão
    //e aí não será possível destruir, causando um leak
    if (FContador = 0) and (FObjetoUnico = nil) then
    begin
      inherited Create;  //aqui tudo bem usar o inherited create e destroy porque a classe base não faz nada de mais
      InterlockedIncrement(FContador);
      DataHora := FormatDateTime('yyyy-mm-dd hh:nn:ss', now);
    end
    else
      raise Exception.Create('Ei! Não use esse constructor, use o CreateUnico!');
    //o inherited fica dentro do if assim o objeto não será criado caso ja esteja o contador > 0

end;



destructor TObjetoUnico.Destroy;
begin

  FObjetoUnico := nil;
  InterlockedDecrement(FContador);
  inherited;

end;

class function TObjetoUnico.GetContador: integer;
begin
  Result := FContador;
end;

function TObjetoUnico.GetDataHora: string;
begin
  Result := FDataHora;
end;



//como a propriedade  ObjetoUnico executa esse get e esse get le o class var e
//o instancia caso seja nil a propriedade ObjetoUnico tem uma proteção
//natural contra nil e sempre será instanciada, nunca será igual a nil
class function TObjetoUnico.GetObjetoUnico: TObjetoUnico;
begin
  //aqui a mesma verificação é feita para não se executar o create duas vezes
  //mas devolver o objeto existente ou devolvê-lo assim que criado
  if (FContador = 0) and (FObjetoUnico = nil) then
    FObjetoUnico := TObjetoUnico.Create;
  Result := FObjetoUnico;
end;

initialization
  //a initilization não é necessária

finalization
  if (TObjetoUnico.FObjetoUnico <> nil) then
  try
    //leia o comentário abaixo para saber porque o campo privado FObjetoUnico
    //é usado aqui em vez da propriedade ObjetoUnico
    TObjetoUnico.FObjetoUnico.Free;
  except
    //tratamento de excessão
  end;

  //por causa da proteção "natural" contra nil você pode destruir
  //o singleton com
  //TObjetoUnico.ObjetoUnico.Free;
  //mas isso causa um overhead porque se o FObjetoUnico não estiver criado (nil)
  //ele será criado só para ser destruído.
  //É bonito de se ver, mas feio do ponto de vista do algoritmo

end.


unit uSingletonDerivado;

interface

uses
  uSingleton, SysUtils, DateUtils, Windows, dialogs;

type


  TObjetoUnicoDerivado = class(TObjetoUnico)
  private
    class var FObjetoUnico: TObjetoUnicoDerivado;
    class var  FContador: Integer;
    class function GetContador: integer; static;
    class function GetObjetoUnico: TObjetoUnicoDerivado;  static;
  public
    constructor Create; reintroduce;
    destructor Destroy; override;
    function GetDataHora: string; override;

    class property ObjetoUnico: TObjetoUnicoDerivado  read GetObjetoUnico;
    class property Contador: integer read GetContador;

  end;

procedure VerificaObjetoUnicoDerivadoCriado;

implementation



procedure VerificaObjetoUnicoDerivadoCriado;
begin
  if (TObjetoUnicoDerivado.FContador >= 1) and (TObjetoUnicoDerivado.FObjetoUnico <> nil) then
    ShowMessage('=========== verificação ===========' + #13#10 +
    'Nome da classe: ' + TObjetoUnicoDerivado.FObjetoUnico.ClassName+ #13#10 +
    'Hora de Criação pelo método: ' + TObjetoUnicoDerivado.FObjetoUnico.GetDataHora + #13#10 +
    'Hora de Criação pela propriedade: ' + TObjetoUnicoDerivado.FObjetoUnico.DataHora + #13#10 +
    'Endereço na memória: ' + IntToStr(Integer(TObjetoUnicoDerivado.FObjetoUnico))
  );
end;


{ TObjetoUnicoDerivado }


constructor TObjetoUnicoDerivado.Create;
begin
    if (FContador = 0) and (FObjetoUnico = nil) then
    begin
      InterlockedIncrement(FContador);
      DataHora := FormatDateTime('yyyy-mm-dd hh:nn:ss', now);
    end
    else
      raise Exception.Create('Ei! Não use esse constructor, use o CreateUnico!');
end;


destructor TObjetoUnicoDerivado.Destroy;
begin
  FObjetoUnico := nil;
  InterlockedDecrement(FContador);
end;

class function TObjetoUnicoDerivado.GetContador: integer;
begin
  Result := FContador;
end;



function TObjetoUnicoDerivado.GetDataHora: string;
begin
  Result := 'acréscimo ' + inherited GetDataHora;
end;


class function TObjetoUnicoDerivado.GetObjetoUnico: TObjetoUnicoDerivado;
begin
  if (FContador = 0) and (FObjetoUnico = nil) then
    FObjetoUnico := TObjetoUnicoDerivado.Create;
  Result := FObjetoUnico;
end;


initialization

finalization
  //aqui há um exemplo de como o objeto único pode ser destruido
  TObjetoUnicoDerivado.FObjetoUnico.Free;

end.

A maior lição aprendida aqui é que se desejamos sobrescrever os métodos acessores, para poder usufruir de todos os recursos da herança e do polimorfismo e poder agregar código ao método da classe base ainda usando parte do código da classe base devemos fazer como no Java e em outras linguagens Orientadas a Objetos e criar métodos acessores públicos e virtuais.

Além disso, isso é extremamente necessário, indispensável, para se criar interfaces com propriedades. Em interfaces as propriedades só podem ler e escrever métodos, e nunca campos privados, mas os métodos de uma interface, mesmo que acessores, PRECISAM SER PÚBLICOS E VIRTUAIS para que possam ser implementados.

Essa última alteração pode ser testada com mais um botão que cria uma instância de TObjetoUnicoDerivado dentro de uma variável ancestral, do tipo TObjetoUnico.

procedure TfrmUmaInstancia.brCriaDerivadoEmAncestralClick(Sender: TObject);
var FObjetoUnico: TObjetoUnico;
begin


  FObjetoUnico := TObjetoUnicoDerivado.ObjetoUnico;

  ShowMessage('Nome da classe: ' + FObjetoUnico.ClassName+ #13#10 +
    'Hora de Criação: ' + FObjetoUnico.DataHora + #13#10 +
    'Endereço na memória: ' + IntToStr(Integer(FObjetoUnico))
  );

end;

Quem quiser conferir esse exemplo é só baixá-lo aqui: http://www.vitorrubio.com.br/downloads/Exemplo_Singleton_2.7z

Have fun ;)

Links úteis, leia todos ;)



Existem 1001 maneiras de preparar SINGLETON, invente uma! - Parte 1

http://blog.vitorrubio.com.br/2010/11/existem-1001-maneiras-de-preparar.html

Existem 1001 maneiras de preparar SINGLETON, invente uma! - Parte 2

http://blog.vitorrubio.com.br/2011/01/existem-1001-maneiras-de-preparar.html

Existem 1001 maneiras de preparar SINGLETON, invente uma! - Parte 3

http://blog.vitorrubio.com.br/2011/02/existem-1001-maneiras-de-preparar.html

Existem 1001 maneiras de preparar SINGLETON, invente uma! - Parte 4
http://blog.vitorrubio.com.br/2011/02/existem-1001-maneiras-de-preparar_08.html

Criando uma classe singleton verdadeira em delphi

http://www.comofazertudo.com.br/computadores-e-internet/criando-uma-classe-singleton-verdadeira-em-delphi

Creating a real singleton class in Delphi 5

http://edn.embarcadero.com/article/22576

Introdução: Singleton - Design Pattern Delphi - Parte 1

http://www.devmedia.com.br/post-17889-Introducao--Singleton-Design-Pattern-Delphi-Parte-1.html

Tentativa de Singleton usando Delphi

http://www.marcosdellantonio.net/2006/12/01/tentativa-de-singleton-usando-delphi/

Implementing the Singleton pattern in delphi

http://www.delphi3000.com/articles/article_1736.asp?SK=

Essa é uma abordagem nova que eu nunca imaginei:

http://stackoverflow.com/questions/1409593/creating-a-singleton-in-delphi-using-the-new-features-of-d2009-and-d2010

Class (, Static, or Shared) Constructors (and Destructors)

http://blogs.embarcadero.com/abauer/2009/09/03/38898

Design Patterns in Delphi

http://delphi.about.com/od/oopindelphi/a/aa010201a.htm

No forum antigo:

Tópico no forum devmedia sobre singleton

no forum novo:

http://www.devmedia.com.br/forum/viewtopic.asp?id=374670

sexta-feira, 28 de janeiro de 2011

O santo graal da memória não volátil

Caminhava eu para a praça Silvio Romero a fim de  resolver minha pugna minha com a receita federal e, precavido que sou, levei minha declaração do imposto de renda E a retificação da dita cuja em duas cópias, uma em DVD e uma em pendrive.

O porque da peleja? não consigo transmitir minha maldita declaração do IR. Recebo essa mensagem de erro:

erro ao enviar arquivo
É esta a mensagem de erro


Optei por essas mídias porque ligando no 146, de Brasília, fui informado de que poderia ser em pendrive. Ao chegar lá, após pegar a senha de pré - atendimento, peguei a de ATENDIMENTO. Foi o tempo de passar 21 telas do angrybirds. Minha senha era AMF XX, AMF de Auxílio Malha Fina.

Chegando lá, a gentil e capacitada funcionária pública da receita disse que eu deveria trazer a declaração para ser transmitida por lá.  Saquei a declaração do bolso, e então ela disse que eu deveria pegar uma senha e um formulário para a retransmissão da declaração.

Peguei novamente duas senhas.

Ao ser atendido novamente (milhares de porquinhos depois) o atendente, também incrivelmente capacitado e inteligente, me passou um telefone: (11) 3757-6508. Você consegue ligar? Nem eu. Ele me disse que poderia fazer a transmissão pra mim.

Quando saquei meu DVD desperdiçado com um único arquivo de míseros 2 kb, o atendente, balançando a cabeça, disse: "- cd não pode senhor". "porque?" perguntei. "Porque cd é somente leitura e precisamos gravar o recibo de envio". Eu nem questionei, saquei meu pendrive de 8 GB e disse:  - esse grava, e muito.

- Não pode ser pendrive senhor.

- Oras,   e o que pode então?

- Disquete.

- O quê? (whaaaaaaaat)?

- Disquete senhor. Desse tipo aqui: 

- Karaleo, onde vou arrumar um desses? Tem antiquário por aqui? Tem certeza que o senhor não quer um relógio cuco ou um soldado de terracota? Onde vou arrumar uma coisa dessas.

Pois é, o cara queria um disquete

- Porque não pode ser o pendrive?

- Porque pendrives são muito suscetíveis a virus.

- E um disquete também não pode ter virus?

-NÃO.  (sério, ele disse que não)

De fato, para um virus contaminar um disquete, ele tem que ser menor que um disquete.  O que é raro para esses trojans modernos. A maioria tem mais de 1.5 MB.

Outra dificuldade é um virus ENCONTRAR um disquete. Dificuldade esta que abracei. Saí da receita alucinado em busca de um disquete. Foi uma verdadeira QUEST de RPG, daquelas que você tem que falar com todos os habitantes do vilarejo para ver se descola alguma dica útil. Cada um falando uma coisa diferente e te mandando ir em um lugar diferente. O Ferreiro te manda para o Alfaiate, que te manda para o Açougueiro, que manda para o Artesão, o Boticário, o Curandeiro, o Padre, a Bruxa .... fui em 3 papelarias e 2 lan houses. Não encontrei. Nas lan houses foi pior, porque fizeram chacota do problema: "você veio da receita né? mwuhauahuaahuau. Desista, mesmo se você tivesse um disquete você nunca, NUNCA vai encontrar um computador com drive de disquete por aqui." (de fato os computadores das duas lan houses, mesmo os servidores ou os caixas, não tinham o drive de disquete).

Disquetes são dispositivos ancestrais, que vem de tempos imemoriais. Foram criados
pouco tempo depois da roda
no alvorecer de nossa civilização, na era de ouro. Mas na inquisição quase todos foram destruídos, já que poderiam ser usados para transportar o alcorão. Dos 5 que restaram, apenas dois vieram para o Brasil nas caravelas, em 1500.  Dizem que o portador de um destes pode desvendar todos os segredos do universo. E que todos os segredos do universo têm apenas 1.44 kb e todas as outras ciências são mero  enchimento de linguiça.

Então é isso. Depois de meio dia de trabalho perdido fui comer um black dog e jogar umas partidas de fliper na Lords. Quem sabe um dia eu encontro um disquete em algum sítio arqueológico e faço a transmissão da minha declaração.... até lá acho que vou ficar sem minha restituição do IR ...

quinta-feira, 20 de janeiro de 2011

Revista Clube Delphi 125

A revista Clube Delphi 125 já está disponível aos assinantes e no site.
Essa revista tem uma introdução muito interessante ao desenvolvimento de aplicações para iPhone utilizando MonoDevelop, MonoTouch e a SDK do iPhone. Desenvolver aplicações para iPhone não é fácil se comparado ao desenvolvimento Win32/Windows Forms com técnicas RAD, mas a matéria explica quais são as diferenças e introduz bem o tema.
Há também um artigo sobre o Firebird 2.5. Eu já usava o 2.1 mas nem imaginava que ele tinha alguns recursos avançados, desses que você pode encontrar no MS SQL.
O artigo de capa fala sobre o Codesite. Se quer aprender a rastrear e corrigir bugs leia-o.
E há um artigo meu sobre criação de experts (plugins) para a IDE do Delphi. É um mundo totalmente novo para quem nunca viu. Há a possibilidade de interagir com units, formulários e componentes em tempo de design e automatizar tarefas, ou apresentar formulários que, se preenchidos, criam arquivos de configuração, units etc.

Vale a pena para quem quiser entrar nesse mundo de Experts e desenvolver ferramentas para programadores. Se seus usuários forer programadores também, 100% de chance de diminuir todos os seus problemas com a "destreza" alheia.

O glorioso retorno do bom senso

Bom, desde minha volda das férias esse é o meu primeiro post técnico, ou quase.

Bom senso está relacionado à razoabilidade. E vale para tudo, de saúde à tecnologia.

Ando vendo por aí muitas pessoas preocupadas demais com o monte de buzzwords do mercado, são as metodologias e certificações de qualidade (ITIL, PMBOK, RUP, Open UP, XP, Scrum, laranja, abacaxi, batatinha) outras relacionadas a linguagens de programação (Java, Python, C#, Ruby) e cada linguagem de programação se desdobrando em infinitos frameworks para os mais diversos assuntos (Hibernate, Fluent, Linq, velocity, rails, django, makumba, spring).

Para complicar há ainda diversos sistemas operacionais, de windows a bada. E por falar em bada, diversos tipos de mobile (android, symbian, windows 7, bada, iOS, McDonalds, China in Box ).

E as ferramentas para documentação de código ou criação de diagramas? ArgoUML, Poseidon, Model Maker...

Nós, que lidamos com tecnologia, somos curiosos por natureza. Mas a curiosidade pode ser uma faca de dois gumes. Ela pode te levar a destruir sua produtividade.

Você que aprender todas as linguagens, metodologias e frameworks? Quer pelo menos conhecer?

Chamemos essa sopa de letrinhas de siglas e neologismos que nascem aos montes todo dia simplesmente de buzz-tools. Algumas realidades  sobre eles que podem ser dolorosas:

1) Você não vai ficar rico se souber todas as buzz-tools.
2) Você não vai ganhar mais dinheiro que seu colega por sua buzz-tool ser melhor ou mais nova.
3) Aprender todas as buzz-tools é como aprender todas as linguagens naturais. Não importa se você tenha pós doutorado na área de Ciência da computação ou áreas correlatas, a verdade é que nem todo pós doutor em letras, por exemplo, fala mais de 10 idiomas. Alguns sabem fluentemente 3 e olhe lá. Todos os idiomas da Terra então, impossível.
Médicos pós doutores também não podem lhe dar vida eterna, nem novos olhos ou novas pernas.
4) Se tentar estudar todas as buzz-tools não se aprofundará em nenhuma delas, não fará nada produtivo e será um especialista em "Hello World", pois será só isso que irá fazer.
5) Convenhamos, se a cada dia aparece uma nova buzz-tool, chegará um momento em que existirá no mundo todo apenas meia dúzia de projetos feito em cada ferramenta, já que o número de ferramentas é tão grande.

O ponto onde quero chegar é que nem todas as buzz-tools precisam ser estudadas. Não que elas não sejam boas (algumas realmente não o são) ou que não mereçam ser estudadas. Mas é que você não vai aplicar todos os seus conhecimentos em todos os projetos. E perceberá que os seus melhores projetos serão os que você usou SEUS conhecimentos, SUAS idéias e SUA criatividade, sem usar padrões, metodologias e buzz-tools. (ou independentemente da que use).

Nenhuma revista, tutorial, fórum ou livro de buzz-tools pode te ensinar a ter criatividade e imaginação. Talvez um litro de cachaça te ensine mais sobre imaginação do que uma enciclopédia de assembly e todos os livros do Dijkstra e Tanembaum juntos.

Pense nisso. Buzz-tools são soluções, ferramentas. Você nunca criará uma solução ou ferramenta se o seu foco for em outras soluções ou ferramentas. Você deve ter o foco no problema. Para criar um bom programa você deve TER um PROBLEMA, FOCAR  no PROBLEMA e desenvolver a SUA SOLUÇÃO. Não outro  problema. Os únicos softwares que fogem a essa regra são os softwares para fins lúdicos como os games. Esses são mais complicados porque você não deve criar uma solução, mas sim criar um problema (de preferência solucionável com uma certa dificuldade).

Para desenvolver algo realmente complexo, útil e bem feito deve-se desprender totalmente das buzz-tools, abraçar o abstrato e seguir em frente, mesmo que seja em VB6 .... pronto, falei.

NÃO EXISTE MELHOR FERRAMENTA QUE O BOM SENSO.

A alma do programador

Certa vez, no curso de pós graduação da FATEC-SP, um professor que eu admiro muito, ao ser interrogado sobre quando teria uma janela para reposição de uma aula, sacou seu smartphone para conferir sua agenda e disse:

" - Deixe-me primeiro consultar minha prótese cognitiva."

Interessante, ele considerava o seu celular como uma prótese cognitiva. Não sabia em que lugar ir ou quando ir se não fosse por ele, o celular.

Isso não é de todo ruim se você levar em consideração a filosofia geral que permeava a classe dos Samurais (Saburau ou Bushi) no Japão Feudal dos anos 1200 aproximadamente até 18xx (aproximadamente). Eles tinham um extenso e complexo código de ética/conduta verbal. Era o Bushido, ou caminho do Servidor.

Os Samurais eram, em sua maioria, militares de alta patente, guarda costas, juízes e executores. A maioria deles era muito bem versado nas artes marciais, mas também na poesia e na caligrafia. Todos eram guerreiros no sentido mais amplo da palavra, mas nem todos estavam envolvidos em guerras. Todos os guerreiros, soldados, generais do exército eram Samurais, mas nem todo Samurai era guerreiro. Como a palavra Samurai quer dizer "Servidor", a maioria era servidor público. (Não compare com os servidores públicos de hoje no Brasil).

Os Samurais consideravam sua ferramenta de trabalho (seja a espada para o guerreiro ou a pena para os burocratas) como uma extensão do próprio corpo, ou até mais do que isso, como sua alma. Um guerreiro que perdesse ou danificasse sua espada em uma luta poderia se considerar como se estivesse com um membro amputado, ou pior: um corpo sem vida, sem alma, uma casca vazia.

Ao dizer que meu celular, computador etc são minhas próteses cognitivas, estou afirmando que fazem parte do meu corpo, que são extensão dele. Se você considerar suas ferramentas de trabalho e sua capacidade de usá-las como parte do seu corpo, sua própria alma, você já deu o primeiro passo para se tornar exímio naquilo que faz.

Sim, meu computador é minha alma. Não o computador físico em sentido literal, esse que estou usando para digitar esse texto, mas sim qualquer computador que eu venha a usar, a minha capacidade de lidar com tecnologia, digamos assim.

A idéia é mais abstrata. Um Samurai, aristocrata, ordenava um ferreiro famoso confeccionar uma katana (espada longa) e muitos rituais e formalidades eram envolvidos no processo. A "espada" tinha "alma própria, vida".

Se você der alma, SUA ALMA, à sua ferramenta de trabalho, encontrará um caminho prazeiroso e recompensador.

segunda-feira, 10 de janeiro de 2011

De volta das férias, e desperdiçando energia

Boa noite a todos. Depois de umas merecidas férias em Natal (uma vez a cada 5 anos precisa mesmo) estou de volta (fotos em breve) e  VIVO. Vivo mas com uma baita úlcera. A causa primária de minha úlcera por incrível que pareça não é a comida forte porém deliciosamente bem temperada de Natal.

A causa-mor de minhas dores é a famigerada Telefonica e aquilo que eles chamam de conexão. Cheguei de viajem dia 23/01/2011 e hoje já é dia 10/01/2011 e eu estou quase sem conexão à internet. Digo quase porque as vezes a conexão vem, mas fica funcionando apenas por alguns minutos e aí eu tenho que fazer todo o circo de liga desliga parafernalha para ver se volta.

Por causa disso criei um blog para fazer um protesto contra esse abuso. http://manifestoderepudioatelefonica.blogspot.com/

São três anos lutando e desperdiçando dinheiro, por uma conexão de 300 k, um pouco melhor que a discada, e que quando funciona fica apenas alguns minutos no ar.

Sabe, não gosto de aparecer, e nesses 12 anos de Internet nunca me passei por troll ou hatter. Quem me conhece sabe disso. Mas a Telefonica está merecendo absolutamente tudo o que eu conseguir criar de ruim para eles. Por isso, canalizarei todas as minhas energias negativas para que cada mísero funcionário que me atendeu porcamente sofra terríveis dores e gemidos de agonia. Que morram todos com um tumor maligno bem lá no *

Em breve farei mais posts técnicos, como a prometida continuação do assunto sobre Singleton e alguns posts rápidos de Lazarus e MonoDevelop. De quebra mostrarei alguns programinhas de segurança legais.

Have fun ;)

quarta-feira, 5 de janeiro de 2011

Postagens populares

Marcadores

delphi (60) C# (31) poo (21) Lazarus (19) Site aos Pedaços (15) sql (13) Reflexões (10) .Net (9) Humor (9) javascript (9) ASp.Net (8) api (8) Básico (6) Programação (6) ms sql server (5) Web (4) banco de dados (4) HTML (3) PHP (3) Python (3) design patterns (3) jQuery (3) livros (3) metaprogramação (3) Ajax (2) Debug (2) Dicas Básicas Windows (2) Pascal (2) games (2) linguagem (2) música (2) singleton (2) tecnologia (2) Anime (1) Api do Windows (1) Assembly (1) Eventos (1) Experts (1) GNU (1) Inglês (1) JSON (1) SO (1) datas (1) developers (1) dicas (1) easter egg (1) firebird (1) interfaces (1) introspecção (1) memo (1) oracle (1) reflexão (1)