Code Reconstruction - Get encapsulation Delphi encoding example
Code Reconstruction is a good way to achieve a good structure. By reconstructing, we improve the quality of the code and improve the degree of complex code in the case of maintaining the failure. Here is a specific example of obtaining improved code quality and obtaining encapsulation. (Example Using Delphi)
Code function:
To set up a filter, the user can select the field you want to filter in a TcomboBox, and then enter the value you want to filter in a TEDit box. Figure 1:
The most common approach is to write to the field names in our data set in TcomboBox's items properties, and then add a large number of case or if statements to the code to determine the user-selected field to set the filter.
......
Case ComboBox1.ItemIndex of
0:
ClientDataSet.Filtered: = false;
ClientDataSet.Filter: = 'f_code =' '' edit2.text '' ';
ClientDataSet.Filtered: = true;
1:
ClientDataSet.Filtered: = false;
ClientDataSet.filter: = 'f_chinese_name =' '' edit2.text '' ';
ClientDataSet.Filtered: = true;
......
END;
Use
.... ...
IF ComboBox1.text = 'Material Code' Then
Begin
ClientDataSet.Filtered: = false;
ClientDataSet.Filter: = 'f_code =' '' edit2.text '' ';
ClientDataSet.Filtered: = true;
end
Else if ComboBox1.text = 'Name' Then
Begin
ClientDataSet.Filtered: = false;
ClientDataSet.filter: = 'f_chinese_name =' '' edit2.text '' ';
ClientDataSet.Filtered: = true;
end
......
Such a code also implements the function of setting the filter to the dataset by hard code, which satisfies the need, but the above code is not flexible. If the field of the data set requires a field that the coder is entered in items, and in writing case, it must check the order of the order. Otherwise, the filter is incorrect, and it is easily introduced by the developer into bugs. Maintaining a large amount of IF is also painful when using an IF statement, and does not support demand changes, and when the user requests to change the Chinese display name of the Dataset field, you must also remember the hard code data in the Tcombobox. Items, if Once you forget, you will introduce bugs.
So I am in the first reconstruction, trying to dynamically load the data in the TcomboBox. Items, while implementing the control when the user is selected. I added a private ffields: array [0..20, 0..2] of String; fields to save the field information data in the data set. At the same time, a process of loading data is implemented:
Procedure tfrmspareAlStorageQuery.getQueryfields; var
I, IFIELDSCOUNT: INTEGER;
Begin
Ifieldscount: = 0;
With dbgride1.datasource.dataset do
Begin
For i: = 0 to Fields.count - 1 DO
IF fields [i] .visible kil
Begin
Ffields [ifieldscount, 0]: = Fields [i] .fieldname;
Ffields [ifieldscount, 1]: = Fields [i] .displayLabel
INC (IFIELDSCOUN);
END;
ComboBOBOX1.ITEMS.CLEAR;
For i: = 0 to ifIeldscount - 1 DO
ComboBoX1.Items.Add (ffields [i, 1]);
END;
END;
This enables dynamic loading field information during runtime. So my filter settings become like this.
IF ComboBox1.text <> 'Then
Begin
ClientDataSet.Filtered: = false;
ClientDataSet.filter: = ffields [comboBOX1.ItemIndex, 0] '' '' edit2.text '' ';
ClientDataSet.Filtered: = true;
END;
This method undoubtedly increases the flexibility of the code while increasing the complexity of the code because the code is very good to isolate the changed data. Therefore, as long as the other is also a function of this function, it is convenient to add private fields ffields: array [0..20, 0..2] of String and use the above dynamic load data set field process. Reuse. But this reuse is not very good because we have not achieved good encapsulation. Caused a repetitive code in your program (you often get the reuse of this function through COPY, because the above code is not good encapsulation). If one day you want to modify the data load function, you must go everywhere to copy the function - you have to modify the code that scattered elsewhere. So I made another reconstruction and further encapsulated by the code.
code show as below:
Unit udatasetfieldsinfo;
// Description: The unit includes TDataSetFieldsInfo classes, which encapsulates to obtain data set segment information.
/ / And provide a method interface that displayed in the ComboBox list display field and obtaining a corresponding sub-segment name
// Created: wuchhao
// Date: 2003.5
Interface
Uses classes, dbclient, stdctrls;
Type
TDataSetfieldsInfo = Class
Private
Ffieldslist: tstrings;
public
Constructor crete;
DESTRUCTOR DESTROY; OVERRIDE;
Procedure getDataSetfields (Source: TclientDataSet);
Procedure ShowfieldsInfo (Target: Tcombobox);
Function GetfieldsNameByDisplayLabel (DisplayLabel: String): String;
END;
IMPLEMENTATION
{TDataSetfieldsInfo}
Constructor tdataratedfieldsinfo.create;
BeginffieldsList: = TSTRINGLIST.CREATE;
END;
Destructor TdataSetfieldsInfo.destroy;
Begin
Ffieldslist.free;
inherited;
END;
Procedure TDataSetfieldsInfo.getDataSetfields (Source: TclientDataSet);
VAR
i: integer;
Begin
Ffieldslist.clear;
WITH SOURCE DO
Begin
For i: = 0 to Fields.count - 1 DO
IF fields [i] .visible kil
Begin
FfieldsList.Add (Fields [i] .displayLabel);
FfieldsList.Add (Fields [i] .fieldname);
END;
END;
END;
Function TDataSetfieldsInfo.getfieldsNameBydisplayLabel
DisplayLabel: String;
VAR
Index: Integer;
Begin
Result: = '';
Index: = ffieldslist.indexof (DisplayLabel);
IF index <> -1 Then
Result: = ffieldslist.strings [INDEX 1];
END;
Procedure tdatasetfieldsinfo.showfieldsinfo (Target: tcomboBox);
VAR
i: integer;
Begin
Target.Items.clear;
I: = 0;
While i Begin Target.Items.Add (ffieldslist.strings [i]); I: = i 2; END; END; End. Unit UDataSetfieldsInfo encapsulates data and methods related to the functions described herein, encapsulating them in a class, thereby achieving Open - Close principles in object-oriented design. The class has become a black box, so it is convenient to reuse, but don't worry about the repetition of the code. At the same time, because of the encapsulation of information related information, the class's responsibilities are clear (single duty), and there is sufficiently suitable particle size and good encapsulation. TDataSetfieldsInfo is very good to isolate the combo box with changes, and ultimately increase the degree of complexing of the code while reducing the role of the FORM class and the amount of MAGIC Number hardcodes. Below is a new code: First declare a reference to the TDataSetfieldsInfo class in Form. ...... Call when Form created: Ffieldsinfo: = TDataSetfieldsInfo.create; Ffieldsinfo.getDataSetfields (cdmaster); Ffieldsinfo.showfieldsInfo (ComboBoX1); At this time, my filter setting turns: IF ComboBox1.text <> 'Then Begin ClientDataSet.Filtered: = false; ClientDataSet.Filter: = ffieldsinfo.getfieldsNameByDisPlayLabel (ComboBox1.text) '' ' Edit2.Text ' ''; ClientDataSet.Filtered: = true; END; Get the corresponding sub-segment name by calling the interface process of the FfieldsInfo object. This article is a simple example of a refactoring code. I want this class I achieved to have many ways to write and better algorithms. Here is just a thinking about the reconstruction code, in order to improve our writing code quality and its maintenanceability, scalability, discuss the ideas of OOD programming methods. Reference: 3. "Refactoring: improving the design of evigning code" Martin Fowler 1999 4. "Design Mode" Machinery Press 2000