Neste contexto, Interface não tem a ver com o conceito embutido na palavra chave interface do Delphi. Aqui ele se refere à forma com que a função se relaciona com o mundo exterior, isto é, quais parâmetros deverão ser informados por outras partes do programa para se obter a instância desejada. A interface padrão é, então, uma função bem conhecida que centraliza a criação de instâncias para uma família de classes.
Tome, por exemplo, as classes representadas no diagrama abaixo:Há uma classe TWForma que é base para 3 heranças conhecidas (TWCirculo, TWQuadrado e TWTriangulo). Em Delphi, essa relação seria declarada como segue:
type
TWForma = class
{ ... }
procedure Desenha;virtual;
end;
TWCirculo = class(TWForma)
{ ... }
procedure Desenha;override;
end;
TWQuadrado = class(TWForma)
{ ... }
procedure Desenha;override;
end;
TWTriangulo = class(TWForma)
{ ... }
procedure Desenha;override;
end;
TWForma = class
{ ... }
procedure Desenha;virtual;
end;
TWCirculo = class(TWForma)
{ ... }
procedure Desenha;override;
end;
TWQuadrado = class(TWForma)
{ ... }
procedure Desenha;override;
end;
TWTriangulo = class(TWForma)
{ ... }
procedure Desenha;override;
end;
A outra classe existente no esquema é a TWFormaFactory. Através dela implementaremos um único método - o Factory Method - que é declarado como um método de classe, isto é, não é preciso instanciar a classe para utilizá-lo. Esse método é o coração do Design Pattern Factory Method pois é nele que fica a inteligência para instanciar as classes. Veja a declaração:
type
TWTipoForma = (tfCirculo, tfQuadrado, tfTriangulo);
TWFormaFactory = class
class function GetTWForma (ATipo: TWTipoForma): TWForma;
end;
implementation
class function TWFormaFactory.GetTWForma (ATipo: TWTipoForma): TWForma;
begin
Result := Nil;
case ATipo Of
tfCirculo: Result := TWCirculo.Create;
tfQuadrado: Result := TWQuadrado.Create;
tfTriangulo: Result := TWTriangulo.Create;
end;
end;
TWTipoForma = (tfCirculo, tfQuadrado, tfTriangulo);
TWFormaFactory = class
class function GetTWForma (ATipo: TWTipoForma): TWForma;
end;
implementation
class function TWFormaFactory.GetTWForma (ATipo: TWTipoForma): TWForma;
begin
Result := Nil;
case ATipo Of
tfCirculo: Result := TWCirculo.Create;
tfQuadrado: Result := TWQuadrado.Create;
tfTriangulo: Result := TWTriangulo.Create;
end;
end;
Aqui, a interface padrão para criar instâncias do TWForma é o método GetTWForma. Repare que ele tem conhecimento prévio sobre as classes que serão criadas. Por causa do polimorfismo, o método pode ser declarado de forma a retornar um ponteiro para a classe base TWForma e o resto do programa não precisa se preocupar com qual tipo foi realmente instanciado já que a classe TWForma introduziu acesso a todo o comportamento que é esperado. Isso configura o cenário ideal para usar o padrão Factory Method: classes com relação de herança e conhecimento prévio das classes a instanciar.
Usar esse padrão tem um clara vantagem se comparada a usar simplesmente o constructor de cada classe: se novas heranças de TWForma forem declaradas, haverá um único ponto do código para ser alterado.
Uma forma de usar o exemplo seria incluir um Combo num Form para permitir que o usuário adicione um nova forma a uma lista e essa lista controle o que será desenhado em tela:
tpForma := TWTipoForma (ComboBox1.ItemIndex);
forma := TWFormaFactory.GetTWForma (tpForma);
ListaFormas.Add (forma);
{ ... }
forma.Desenha;
forma := TWFormaFactory.GetTWForma (tpForma);
ListaFormas.Add (forma);
{ ... }
forma.Desenha;
2 comentários :
Dicas valiosas aqui no seu blog. Muito obrigado por compartilhar o conhecimento.
Parabéns Luis. Seus artigos são nota 10 !!!
Postar um comentário
OBS: Os comentários enviados a este Blog são submetidos a moderação. Por isso, eles serão publicados somente após aprovação.
Observação: somente um membro deste blog pode postar um comentário.