Refatoração de código - Obtendo encapsulamento Exemplo de codificação DELPHI A refatoração de código é uma forma de obter uma boa estrutura. Por meio da refatoração, podemos melhorar a qualidade do código e aumentar o grau de reutilização do código, mantendo as funções inalteradas. Aqui está um exemplo concreto de como melhorar a qualidade do código e obter encapsulamento. (O exemplo usa DELPHI) Função de código: Definir um filtro para o conjunto de dados (TClientDataSet). O usuário pode selecionar o campo a ser filtrado em um TComboBox, e então inserir o valor a ser filtrado em uma caixa Tedit. Conforme mostrado na Figura 1: O método mais comum é codificar os nomes dos campos em nosso conjunto de dados no atributo Items do TComboBox e, em seguida, adicionar muitas instruções case ou if ao código para determinar os campos selecionados pelo usuário para definir filtros para o dispositivo de conjunto de dados. ...... case ComboBox1.ItemIndex of0: ClientDataSet.Filtered := False ClientDataSet.Filter := ' F_CODE = ''' + Edit2.Text + ''''; .Filtrado := Falso; ClientDataSet.Filter := ' F_CHINESE_NAME = ''' + Edit2.Text + ''''; ClientDataSet.Filtered := True;... end; Ou use... if ComboBox1.Text = 'Material Code' então comece ClientDataSet.Filtered := False ClientDataSet.Filter := ' F_CODE = ''' + Edit2.Text; + ''''; ClientDataSet.Filtered := True;endelse if ComboBox1.Text = 'name' thenbegin ClientDataSet.Filtered := False; ClientDataSet.Filter := ' F_CHINESE_NAME = ''' + Edit2.Text + ''''; ClientDataSet.Filtered := True;end... Este código também implementa filtros de configuração para o conjunto de dados por meio de codificação rígida. atende às necessidades, mas o código acima é inflexível. Se o conjunto de dados tiver muitos campos, o codificador deverá inserir os campos um por um em Itens, e a ordem deverá ser verificada ao escrever o caso, caso contrário, o filtro do conjunto estará errado e será fácil para os desenvolvedores introduzi-lo. ERRO. Também é doloroso manter um grande número de instruções if ao usar if, e não oferece suporte a alterações de demanda. Quando o usuário solicita a alteração do nome de exibição em chinês do campo do conjunto de dados, ele também deve se lembrar de alterar os dados codificados. em itens do TComboBox. Se você esquecer, o BUG será introduzido. Então na primeira reconstrução, tentei carregar dinamicamente os dados no TComboBox Items, e ao mesmo tempo, para conseguir comparar quando o usuário seleciona após o carregamento. Eu adicionei um FFields privado: array[0..20, 0..2] of string field a este FORM de consulta para salvar os dados de informações do campo no conjunto de dados. Ao mesmo tempo, um processo de carregamento de dados é implementado: PRocedure TFrmSPARealStorageQuery.GetQueryFields;var i, iFieldsCount: Integer;begin iFieldsCount := 0; with DBGride1.DataSource.DataSet do start for i := 0 to Fields.Count - 1 faça se Fields[ i].Visible então comece FFields[iFieldsCount, 0] := Fields[i].FieldName; (FFields[i, 1]); end;end; Isso permite o carregamento dinâmico de informações de campo em tempo de execução. Portanto, minhas configurações de filtro são assim. if ComboBox1.Text <> '' thenbeginClientDataSet.Filtered := False; ClientDataSet.Filter := FFields[ComboBox1.ItemIndex, 0] + '''' + Edit2.Text + ''''; end; Este método sem dúvida aumenta a flexibilidade do código e aumenta a capacidade de reutilização do código, porque o código está bem isolado da alteração de dados. Portanto, pode-se dizer que é conveniente, desde que você adicione o campo privado FFields: array[0..20, 0..2] de string em outro FORM que também queira implementar esta função e use o processo acima de dinamicamente o carregamento dos campos do conjunto de dados é alcançado. Mas esta reutilização não é muito boa porque não conseguimos um bom encapsulamento. Isso leva à duplicação de código espalhado por todo o seu programa (você costuma usar COPY para obter a reutilização desta função, porque o código acima não possui um bom encapsulamento). Se um dia você quiser modificar a função de carregamento de dados terá que encontrar algum lugar para copiar a função - e terá que modificar o código espalhado em outros lugares. Então, refatorei-o novamente e encapsulei ainda mais o código. O código é o seguinte: unit uDataSetFieldsInfo; // Descrição: A unidade inclui a classe TDataSetFieldsInfo, que encapsula a aquisição de informações do subsegmento do conjunto de dados. // E fornece uma interface de método para exibir informações no campo de exibição da lista de combobox e obter o nome da subseção correspondente // Criado: wuchhao // Data: 2003.5interfaceuses Classes, DBClient, StdCtrls;type TDataSetFieldsInfo = class private FFieldsList: TStrings public constructor; Criar; destruidor Destruir; procedimento GetDataSetFields (Fonte: TClientDataSet); procedimento ShowFieldsInfo(Target: TComboBox); função GetFieldsNameByDisplayLabel(DisplayLabel: string): string; implementação{ TDataSetFieldsInfo }construtor TDataSetFieldsInfo.Create;begin FFieldsList := TStringList.Create;end;destruidor TDataSetFieldsInfo.Destroy;begin FFieldsList.Free;herdado;end;procedure TDataSetFieldsInfo.GetDataSetFields(Fonte: TClientDataSet);var i: Integer;begin FFieldsList.Clear; Campos[i].Visible então comece FFieldsList.Add(Fields[i].DisplayLabel); FFieldsList.Add(Fields[i].FieldName); = ''; índice := FFieldsList.IndexOf(DisplayLabel); <> -1 then Resultado := FFieldsList.Strings[index+1] ;end;procedure TDataSetFieldsInfo.ShowFieldsInfo(Target: TComboBox);var i: Integer;begin Target.Items.Clear; .Count começa Target.Items.Add(FFieldsList.Strings[i]); i:= i+ 2; end;end;end. A unidade uDataSetFieldsInfo encapsula os dados e métodos relacionados à realização das funções descritas neste artigo e os encapsula em uma classe, realizando assim o princípio Open - Close no design orientado a objetos. A classe se torna uma caixa preta, para que possa ser facilmente reutilizada (reutilização de caixa preta) sem se preocupar com a duplicação de código. Ao mesmo tempo, por encapsular informações relacionadas à função, as responsabilidades da classe são claramente definidas (responsabilidade única) e possuem granularidade suficiente e bom encapsulamento. TdataSetFieldsInfo isola efetivamente a caixa de combinação de alterações de dados, melhorando, em última análise, o grau de reutilização de código e reduzindo as responsabilidades da classe FORM e a quantidade de números mágicos codificados. Aqui está o novo código: Primeiro declare uma referência à classe TdataSetFieldsInfo no FORM. ...Chame quando o FORM for criado: FFieldsInfo := TDataSetFieldsInfo.Create;FFieldsInfo.GetDataSetFields(cdMaster);FFieldsInfo.ShowFieldsInfo(ComboBox1); := Falso; ClientDataSet.Filter := FFieldsInfo.GetFieldsNameByDisplayLabel(ComboBox1.Text) + '''' + Edit2.Text + '''' ClientDataSet.Filtered := True;end; nome. Este artigo é um exemplo simples de refatoração de código. Acho que a classe que implementei acima pode ser escrita de várias maneiras e ter algoritmos melhores. Isto é apenas para fornecer uma ideia sobre a refatoração do código. A fim de melhorar a qualidade do nosso código e sua capacidade de manutenção e escalabilidade, exploraremos ideias sobre o método de programação OOD.