Depois de ler o "Criando código bem projetado (baseado em Delphi/VCL)" que escrevi da última vez, muitos amigos me disseram que eu sentia que poderia aceitar os pontos de vista nele, mas parecia ser muito simples e não específico o suficiente; alguns amigos também expressaram dúvidas sobre isso. Um pequeno exemplo de algumas objeções. Daí este artigo.
Da última vez, o exemplo que dei foi este: Suponha que você queira pegar uma lista de strings de algum lugar e depois exibi-la em um TListBox. O código que recomendo é:
ObjectXXX := TObjectXXX.Create;
ListBox1.Items := ObjectXXX.GetStringList;
ObjetoXXX.Free;
Na verdade, admito que, a julgar apenas por essas três linhas de código, parece haver suspeita de "abuso de objeto". Talvez o exemplo seja muito simples, dando a impressão de que TObjectXXX possui apenas uma função de membro público, GetStringList. Se isso for verdade, é realmente "abuso de objeto". Uma classe é uma abstração de um objeto, e um objeto é composto por uma coleção de estados e operações (ou seja, dados e operações sobre dados). Portanto, um objeto sem estado não é um objeto! O projeto de uma classe sem membros de dados privados é um projeto falho (que não é uma classe, mas uma interface).
Ok, deixe-me dar um exemplo detalhado para ilustrar como separar o código de interface e o código de função.
Suponha que eu queira fazer um software simples de gerenciamento de catálogo de endereços pessoal. Obviamente, todo o software é dividido em duas partes: uma parte é orientada ao usuário, que é a chamada parte de interface, posso fornecer quatro botões (respectivamente "adicionar". , ""Excluir", "Modificar", "Pesquisar") e uma caixa de edição (exibindo informações do catálogo de endereços e aceitando entrada do usuário) são usadas para interagir com o usuário; a outra parte é funcional, ou seja, a operação de acesso do catálogo de endereços dentro do software.
Portanto, existe uma classe TAddrBook, que é uma abstração da parte funcional.
TAddrBook=classe
Privado
//Alguns membros privados
público
construtor Criar;
destruidor Destruir; substituir;
GetCount: Inteiro;
FindRecord(strString): Inteiro;
GetRecord(nIndex:Integer): String;
SetRecord(nIndex:inteiro; strRec:String): Boolean;
AddRecord(strRec:String): Boolean;
DelRecord(nIndex): Booleano;
//Outras funções de membro compartilhadas
fim;
A razão pela qual os membros privados não podem ser determinados depende principalmente da implementação desta classe.
Desta forma, a lógica das operações de acesso ao catálogo de endereços pode ser encapsulada. O código na parte da interface não envolverá essas lógicas de acesso. O código da peça da interface é o seguinte:
var
Formulário1: TForm1;
AddrBook: TAddrBook;
nCurRec: Inteiro;
implementação
procedimento TForm1.FormCreate(Remetente: TObject);
começar
AddrBook := TAddrBook.Create;
nCurRec := AddrBook.GetCount;
fim;
procedimento TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
começar
AddrBook.Free;
fim;
//Botão Adicionar
procedimento TForm1.Button1Click(Remetente: TObject);
começar
se não for AddrBook.AddRecord(memo1.Text) então
ShowMessage("erro");
fim;
//Botão Excluir
procedimento TForm1.Button2Click(Remetente: TObject);
começar
se não for AddrBook.DelRecord(nCurRec) então
ShowMessage("erro");
fim;
//botão modificar
procedimento TForm1.Button3Click(Remetente: TObject);
começar
se não for AddrBook.SetRecord(nCurRec, memo1.Text) então
ShowMessage("erro");
fim;
//Botão Localizar
procedimento TForm1.Button4Click(Remetente: TObject);
começar
memo1.Text := AddrBook.GetRecord(AddrBook.FindRecord(memo1.Text));
fim;
O código na parte da interface acima não envolve nenhuma lógica de acesso. O código de cada módulo é simples, fácil de entender e manter. Na verdade, o código da interface não sabe se o catálogo de endereços está salvo em um banco de dados ou em um arquivo de texto. Se um banco de dados for usado, se o banco de dados é acessado por meio de ODBC, ADO ou BDE, o código da interface não sabe. Na verdade, essas lógicas de acesso dependem da implementação da classe TAddrBook. A implementação da classe TAddrBook pode ser colocada em um arquivo .pas separado. Quaisquer alterações na implementação da classe TAddrBook não afetarão a parte da interface. Ao manter o código, é aconselhável limitar as alterações a um único módulo.
Nicrosoft([email protected]) em 14/07/2001