280 likes | 383 Views
Orientação a Objetos na Prática. Erick Sasse Cadena Sistemas erick.sasse@cadena.com.br. interface. Por que OO? Dicas básicas de OO em Delphi Encapsulando componentes de terceiros Coleções (listas de objetos) Templates em Delphi (Generics cover) OPFs Prevalência Interfaces. Erick Sasse.
E N D
Orientação a Objetos na Prática Erick SasseCadena Sistemaserick.sasse@cadena.com.br
interface • Por que OO? • Dicas básicas de OO em Delphi • Encapsulando componentes de terceiros • Coleções (listas de objetos) • Templates em Delphi (Generics cover) • OPFs • Prevalência • Interfaces
Erick Sasse • De Americana, SP • Desenvolvedor há uns 15 anos (Clipper, Delphi) • Delphi desde a primeira versão • Desenvolvedor PalmOS (PocketStudio) • Aventuras em C# (VS.NET), PHP (pequenos projetos) • Analista de sistemas, MBA em TI pela FGV/Ohio University • Palestrante BorCon, DDD, FDD • Ex-MSX (Expert DDPlus) • Ex-BBSeiro • Aspirante a mergulhador
Por que OO? • Para simplificar o desenvolvimento de software, que obrigatoriamente ficam mais complexos a cada dia. • Sistema operacional evolui • Equipamentos evoluem • Softwares evoluem • Centralizar lógica em pequenos componentes independentes. • Aumentar reutilização de código. • Ame ou odeie, mas você tem que entender como funciona. • .NET é totalmente OO. • Muitos desenvolvedores Delphi não tem noção do poder que têm em mãos. • Não seja um plugador de componentes!
Pilares da OO • Abstração • Polimorfismo • Herança • Encapsulamento
Dicas básicas para OO em Delphi • Um form é uma classe, não um objeto! • Desabilite o auto-create dos forms e delete a variável global que o Delphi cria para os forms, pois só serve para dificultar o entendimento de OO. type TForm1 = class(TForm) private { Private declarations } public { Public declarations } end; var Form1: TForm1; Remova isso!
Dicas básicas - Variáveis globais • Variáveis globais (declaradas na interface das units) são do mal, evite ao máximo. • Utilize variáveis privadas (declaradas em private) para guardar dados de um form (ou outra classe qualquer). • Utilize variáveis locais (declaradas na implementation das units) para compartilhar dados entre várias instâncias de um mesmo form. • Quando precisar compartilhar dados entre forms de tipos diferentes, crie uma classe global. • Mão na massa!
Errado Delphi faz “errado” • O Delphi na tentativa de ajudar o programador iniciante, expõe todos os componentes dos forms, violando o principio básico de OO, o encapsulamento. • Os componentes deveriam ser privados. type TForm1 = class(TForm) Button1: TButton; Edit1: TEdit; Label1: TLabel; private { Private declarations } public { Public declarations } end;
Dicas básicas - Propriedades em forms • Evite acessar componentes de um outro form diretamente. • Quando possível, exponha suas propriedades através de propriedades do form. • Propriedades lhe dão muito mais poder, podem incluir código adicional quando se lê e quando se grava um valor. • Mão na massa!
Dicas básicas - Métodos estáticos • São executados independentes de uma instância de classe, ou seja, não precisa existir um objeto para que funcionem. • Mão na massa! • Exemplo: Form Executável
TSQLF – Formatando dados para SQL • Centralizando a formatação de dados para composição de instruções SQL válidas para o banco em uso. • Mão na massa!
Dicas básicas – Owner (dono do objeto) • O owner, quando destruido, é responsável por destruir qualquer objeto que ele possua. • É importante entender o conceito de owner para usar corretamente. • Especialmente importante para programação Win32, quando objetos não destruidos provocam memory leaks (vazamento de memória). • Mão na massa!
Construtores e Destrutores • São os métodos chamados no momento que o objeto é criado, e no momento em que é destruído. • Os construtores são usados para criar objetos internos e configurar o estado inicial do objeto. • Os destrutores são usados para liberar os objetos internos e executar qualquer operação adicional na finalização do objeto. • O construtor normalmente é sobrecarregado e tem várias versões, para facilitar. • Mão na massa!
Encapsulando componentes de terceiros • Você não deixa seu código dependente de componentes de terceiros. • Você consegue trocar de componente com extrema facilidade. • Mão na massa! • Encapsulando envio de mail, relatórios simples e compactação de arquivos.
Sobrecarga de métodos • Permite que um mesmo método seja chamado com parâmetros diferentes. TPessoa.Create; TPessoa.Create(‘João’); TPessoa.Create(‘João’, ‘Rua Martins Fontes, 71’, ‘São Paulo, SP’);
Desenvolvimento 100% OO • Substituição de registros e tabelas por objetos e lista de objetos. • Objetos de negócio • TCliente • TProduto • TUsuario • Listas de objetos no lugar de DataSets. • Muito trabalhoso, porém, muito poderoso. • O banco de dados passa a ser um mero armazenador, com muito menos importância. • Poucos usam. • A principal barreira é a persistência dos objetos em bancos de dados relacionais. Possíveis soluções: • OPFs (Object Persistence Frameworks) • Prevalência.
Coleções (listas de objetos) • Agrupa objetos do mesmo tipo como o TDataSet faz com os registros de uma tabela. • Não tipadas, aceitam qualquer objeto: • VCL (Win32 e .NET): TObjectList • .NET (FCL): ArrayList • Mão na massa!
Coleções tipadas • Checagem de tipo pelo compilador. • Evitam casts no código. • Precisam ser criadas na mão. • Em Win32, criar uma classe que encapsule um TObjectList e implementar os métodos necessários ou herdar de TList. Prefiro a primeira opção. • Em .NET, herdar de CollectionBase, que já implementa interfaces úteis no .NET. • Generics (.NET 2.0) permite “tipar” coleções na declaração da variável. • Mão na massa!
Templates no Delphi • Em Win32 provavelmente nunca teremos Generics e mesmo em .NET, enquanto não temos, podemos usar uma estratégia interessante. type TCliente = class ... end; _ITEM_TYPE_ = TCliente; {$I ListTemplateClass.inc} TClienteList = _LIST_IMPL_CLASS_; • Onde ListTemplateClass.inc contem a implementação genérica de uma lista tipada. • Mão na massa!
OPFs • Frameworks de persistência de objetos. • Mapeiam objetos para tabelas de bancos de dados relacionais. • Win32 • tiOPF • DePO, mantido pelo brasileiro César Romero. • .Net • Borland ECO (muito mais que um OPF) • NHibernate • NEO • WilsonORMapper • ObjectSpaces (Microsoft, ainda não lançado)
Prevalência • Todos os objetos ficam em memória no “servidor de objetos”. • Não existe necessidade de um banco de dados. • Win32 • XDA • .NET • XPrevail (http://xprevail.sourceforge.net/), mantido pelo brasileiro FernandoVM.
Interfaces • Recurso extremamente poderoso. • Possibilita a criação de classes mais “desacopladas” (independentes), diminuindo a utilização de herança. • Permite desenvolver classes ainda mais flexíveis e reutilizáveis. • “Malas” para usar em Win32 devido a contagem de referência. • Muito mais simples em .NET.
Interfaces IImprimivel = interface procedure Imprimir; procedure Visualizar; end; • Quando um objeto implementa a interface IImprimivel, ele é obrigado a implementar os dois métodos da interface (Imprimir e Visualizar). • Desta forma, uma outra classe que receba objetos para impressão, pode saber se o objeto é imprimível ou não checando se ele implementa a interface IImprimivel.
Interfaces TDocumento = class(System.Object, IImprimivel) ... public ... procedure Imprimir; procedure Visualizar; end; TClienteLista = class(CollectionBase, IImprimivel) ... public ... procedure Imprimir; procedure Visualizar; end;
Interfaces TImpressora = class public procedure Imprimir(Obj: System.&Object); end; procedure TImpressora.Imprimir(Obj: TObject); begin if Supports(Obj, IImprimivel) then (Obj as IImprimivel).Imprimir else MessageBox.Show(‘Objeto não suporta impressão!'); end;
Conclusão • Boas práticas em OO requerem mais código do que simplesmente ligar componentes e codificar eventos. • Mas esse é o preço para desenvolver software mais robusto e flexível. • Se ficou mais difícil com objetos, você provavelmente está fazendo errado. • SEMPRE obtive melhores resultados quando usei OO corretamente.
Referências • OODesignhttp://www.oodesign.com.br/ • Templates em Delphihttp://bdn.borland.com/article/0,1410,27603,00.html • SQLFhttp://delphi.about.com/od/adptips2005/qt/sqlformatvalue.htm • Design Patterns em Delphihttp://bdn.borland.com/borcon2004/article/paper/0,1963,32129,00.html • Borland NewsGroupsnntp://newsgroups.borland.com • Crítica a OOhttp://www.geocities.com/tablizer/oopbad.htm
Obrigado! • Erick Sasse • erick.sasse@cadena.com.br • www.ericksasse.com.br (meu blog)