코드 리팩토링 - 캡슐화 얻기 DELPHI 코딩 예제 코드 리팩토링은 리팩토링을 통해 기능을 변경하지 않은 채 코드 품질을 향상시키고 코드 재사용 정도를 높일 수 있는 방법입니다. 다음은 코드 품질을 향상하고 캡슐화하는 방법에 대한 구체적인 예입니다. (예제는 DELPHI를 사용합니다.) 코드 기능: 데이터 세트(TClientDataSet)에 대한 필터를 설정합니다. 사용자는 TComboBox에서 필터링할 필드를 선택한 다음 Tedit 상자에 필터링할 값을 입력할 수 있습니다. 그림 1에서 볼 수 있듯이 가장 일반적인 방법은 TComboBox의 Items 속성에 있는 데이터 세트의 필드 이름을 하드 코딩한 다음 코드에 많은 Case 또는 if 문을 추가하여 사용자가 선택한 필드를 결정하는 것입니다. 데이터 세트에 대한 필터를 설정합니다. ...... 사례 ComboBox1.ItemIndex of0: ClientDataSet.Filtered := False; ClientDataSet.Filter := ' F_CODE = ''' + Edit2.Text + '''' := True;1: ClientDataSet .Filtered := False; ClientDataSet.Filter := ' F_CHINESE_NAME = ''' + Edit2.Text + ''''; ClientDataSet.Filtered := True;... end; 또는 사용... if ComboBox1.Text = 'Material Code'이면 시작 ClientDataSet.Filtered := ClientDataSet.Filter := ' F_CODE = ''' + Edit2.Text + ''''; ClientDataSet.Filtered := True;endelse if ComboBox1.Text = 'name'이면 시작 ClientDataSet.Filtered := False; ClientDataSet.Filter := ' F_CHINESE_NAME = ''' + Edit2.Text + ''''; ClientDataSet.Filtered := True;end... 이 코드는 또한 하드 코딩을 통해 데이터 세트에 대한 설정 필터를 구현합니다. 요구 사항을 충족하지만 위 코드는 유연성이 없습니다. 데이터 세트에 필드가 많은 경우 코더는 항목에 필드를 하나씩 입력해야 하며 케이스 작성 시 순서를 확인해야 합니다. 그렇지 않으면 설정된 필터가 잘못되어 개발자가 도입하기 쉽습니다. 벌레. if 문을 사용할 때 많은 수의 if 문을 유지하는 것도 고통스럽고 수요 변경을 지원하지 않습니다. 사용자가 데이터 세트 필드의 중국어 표시 이름을 변경하도록 요청할 때 하드 이름도 변경해야 합니다. TComboBox 항목에 코딩된 데이터를 잊어버리면 BUG가 발생합니다. 그래서 첫 번째 재구성에서는 TComboBox.Items에 데이터를 동적으로 로드하는 동시에 사용자가 로드 후 선택할 때 비교를 수행하려고 했습니다. 데이터 세트에 필드 정보 데이터를 저장하기 위해 이 쿼리 FORM에 private FFields: array[0..20, 0..2] of string; 필드를 추가했습니다. 동시에 데이터 로드 프로세스가 구현됩니다. PRocedure TFrmSPARealStorageQuery.GetQueryFields;var i, iFieldsCount: Integer;begin iFieldsCount := 0; with DBGride1.DataSource.DataSet do start for i := 0 to Fields.Count - 1 if Fields[ i].Visible 그런 다음 FFields[iFieldsCount, 0] 시작 := Fields[i].FieldName; FFields[iFieldsCount, 1] := Fields[i].DisplayLabel; Inc(iFieldsCount); end; for i := 0 to iFields.Add (FFields[i, 1]); end;end; 이를 통해 런타임 시 필드 정보를 동적으로 로드할 수 있습니다. 그래서 내 필터 설정은 다음과 같습니다. if ComboBox1.Text <> '' thenbeginClientDataSet.Filtered := False; ClientDataSet.Filter := FFields[ComboBox1.ItemIndex, 0] + '''' + Edit2.Text + ''''; end; 이 방법은 의심할 여지 없이 코드의 유연성을 높이고 코드의 재사용성을 높입니다. 왜냐하면 코드가 변경되는 데이터로부터 잘 격리되기 때문입니다. 따라서 이 함수를 구현한 또 다른 FORM에 문자열의 private 필드 FFields: array[0..20, 0..2]를 추가하고, 위의 동적인 데이터 로딩 과정을 활용하면 편리하다고 할 수 있다. 필드를 설정하면 재사용이 가능합니다. 그러나 이러한 재사용은 좋은 캡슐화를 달성하지 못했기 때문에 그리 좋지 않습니다. 이로 인해 프로그램의 모든 곳에 중복된 코드가 흩어지게 됩니다. (위 코드는 캡슐화 상태가 좋지 않기 때문에 이 함수를 재사용하기 위해 종종 COPY를 사용합니다.) 어느 날 데이터 로딩 함수를 수정하고 싶다면 함수를 복사할 곳을 찾아야 하고, 다른 곳에 흩어져 있는 코드를 수정해야 할 것입니다. 그래서 다시 리팩토링하고 코드를 더욱 캡슐화했습니다. 코드는 다음과 같습니다: unit uDataSetFieldsInfo; // 설명: 이 유닛에는 데이터 세트 하위 세그먼트 정보 획득을 캡슐화하는 TDataSetFieldsInfo 클래스가 포함되어 있습니다. // 콤보박스 목록 표시 필드에 정보를 표시하고 해당 하위 섹션 이름을 얻기 위한 메서드 인터페이스를 제공합니다. // 생성: wuchhao // 날짜: 2003.5interfaceuses Classes, DBClient, StdCtrls; type TDataSetFieldsInfo = class private FFieldsList: TStrings; 생성, 소멸자, 재정의, GetDataSetFields(소스: TClientDataSet); 프로시저 ShowFieldsInfo(대상: TComboBox); function GetFieldsNameByDisplayLabel(DisplayLabel: string): string; end;implementation{ TDataSetFieldsInfo }constructor TDataSetFieldsInfo.Create;begin FFieldsList := TStringList.Create;end;destructor TDataSetFieldsInfo.Destroy;begin FFieldsList.Free; 상속됨;end;procedure TDataSetFieldsInfo.GetDataSetFields(Source: TClientDataSet);var i: Integer;begin FFieldsList.Clear; 소스 do start for i := 0 to Fields.Count - 1 do if Fields[i].Visible 다음 시작 FFieldsList.Add(Fields[i].DisplayLabel); FFieldsList.Add(Fields[i].FieldName); end; end;function TDataSetFieldsInfo.GetFieldsNameByDisplayLabel(DisplayLabel: string): 문자열;var index: Integer;begin 결과: = ''; 인덱스 := FFieldsList.IndexOf(DisplayLabel); <> -1 then Result := FFieldsList.Strings[index+1] ;end;procedure TDataSetFieldsInfo.ShowFieldsInfo(Target: TComboBox);var i: Integer;begin Target.Items.Clear while i < FFieldsList; .Count 시작 Target.Items.Add(FFieldsList.Strings[i]); i:= i+ 2; end;end;end uDataSetFieldsInfo 유닛은 본 글에서 설명하는 기능의 구현과 관련된 데이터와 메소드를 캡슐화하여 클래스에 캡슐화함으로써 객체지향 설계의 Open - Close 원칙을 구현합니다. 클래스가 블랙박스가 되어 코드 중복 걱정 없이 쉽게 재사용(블랙박스 재사용)할 수 있습니다. 동시에, 함수 관련 정보를 캡슐화하기 때문에 클래스의 책임이 명확하게 정의되어 있고(단일 책임) 충분한 세분성과 캡슐화가 잘 되어 있습니다. TdataSetFieldsInfo는 데이터 변경으로부터 콤보 상자를 효과적으로 격리하여 궁극적으로 코드 재사용 정도를 향상시키는 동시에 FORM 클래스의 책임과 하드 코딩 매직 넘버의 양을 줄입니다. 다음은 새 코드입니다. 먼저 FORM에서 TdataSetFieldsInfo 클래스에 대한 참조를 선언합니다. ...FORM이 생성될 때 호출: FFieldsInfo := TDataSetFieldsInfo.Create;FFieldsInfo.GetDataSetFields(cdMaster);FFieldsInfo.ShowFieldsInfo(ComboBox1); 이때 필터 설정은 다음과 같습니다: if ComboBox1.Text <> '' thenbeginClientDataSet.Filtered := 거짓; ClientDataSet.Filter := FFieldsInfo.GetFieldsNameByDisplayLabel(ComboBox1.Text) + '''' + Edit2.Text + ''''; ClientDataSet.Filtered := True;end; 이름. 이 글은 코드를 리팩토링하는 간단한 예입니다. 위에서 구현한 클래스는 여러 가지 방법으로 작성할 수 있고 더 나은 알고리즘을 가질 수 있다고 생각합니다. 이는 코드 리팩토링에 대한 아이디어를 제공하기 위한 것이며 코드의 품질과 유지 관리성 및 확장성을 향상하기 위해 OOD 프로그래밍에 대한 아이디어를 탐색할 것입니다.