Membuat kode delphi lebih mudah dibaca menggunakan kelas pembantu:
Panggilan klasik:
StoreDataset ( 1 , mysqlDataSet, true);Panggilan yang lebih mudah dibaca:
mysqlDataSet.StoreSelected_StopAfterFirstError(
function():boolean
begin
Result := mysqlDataSet.FieldByName( ' Status ' ). Value = ' 1 '
end ), fDataStorer);Tbytes Helper - Hasilkan Angka, Kompres Zlib, Base64 Encode, Calc CRC32
uses
Helpers.TBytes;
type
TUploadImageCommand = record
Image: string;
ControlSum: integer;
end ;
procedure SendCommandToRestServer ( const aCommand: TUploadImageCommand);
begin
writeln( ' Use RestClient or IdHttpClient to send POST request ' );
writeln( ' POST /rest/upload-image/ TUploadImageCommand ' );
writeln( ' TUploadImageCommand: ' );
writeln( ' ControlSum = ' , aCommand.ControlSum);
writeln( ' Image Length = ' , Length(aCommand.Image));
writeln( ' Image = ' , aCommand.Image);
end ;
var
bytes: TBytes;
idx: integer;
memoryStream: TMemoryStream;
command := TUploadImageCommand;
begin
bytes.Size := 1000 ;
for idx := 0 to bytes.Size- 1 do
bytes[idx] := idx div 10 ;
memoryStream := TMemoryStream.Create();
bytes := CompressToStream(memoryStream);
command.Image := bytes.GenerateBase64Code();
command.ControlSum := bytes.GetSectorCRC32( 0 , bytes.Size);
SendCommandToRestServer(command);
end .Tbytes Helper : Simpan dan muat tbytes dari aliran atau file. Memuat dan memverifikasi gambar png
uses
Helpers.TBytes;
var
bytes: TBytes;
idx: integer;
memoryStream: TMemoryStream;
command := TUploadImageCommand;
begin
bytes.InitialiseFromBase64String( ' U2FtcGxlIHRleHQ= ' );
bytes.SaveToFile( ' notes.txt ' ); // save: Sample text
memoryStream:= bytes.CreateStream();
// memoryStream.Size = 11
memoryStream.Free;
// -----------------
s := bytes.GetSectorAsString( 0 , 6 ); // ASCII only text
bytes := [ 0 , 0 , 15 , 16 , $A0, 255 , 0 , 0 , 0 , 0 , 1 ];
if bytes.GetSectorAsHex( 2 , 4 ) = ' 0F 10 A0 FF ' then
begin
memoryStream := TMemoryStream.Create();
memoryStream.LoadFromFile( ' small.png ' );
memoryStream.Position := 0 ;
signature.LoadFromStream(memoryStream, 8 );
if (signature.GetSectorAsHex = ' 89 50 4E 47 0D 0A 1A 0A ' ) and
(signature.GetSectorAsString( 1 , 3 ) = ' PNG ' ) then
begin
memoryStream.Position := 0 ;
pngImage := TPngImage.Create;
pngImage.LoadFromStream(memoryStream);
// Image1.Picture := pngImage;
pngImage.Free;
end ;
memoryStream.Free;
end ;
end ;Helper TDateTime : Informasi tentang TDATETIME
uses
Helpers.TDateTime;
var
date: TDateTime;
begin
date := EncodeDate( 1989 , 06 , 04 );
writeln(date.AsYear); // 1989
writeln(date.AsMonth); // 06
writeln(date); // 06/04/1989
writeln(EncodeDate( 2017 , 10 , 24 ).DayOfWeek); // 3
writeln(date.IncMonth( 5 ).ToString( ' yyyy-mm-dd ' ); // 1989-11-04
writeln(date.AsStringDateISO); // 1989-06-04
date := EncodeDate( 2019 , 10 , 24 ) + EncodeTime( 18 , 45 , 12 , 0 );
writeln(date.AsStringDateISO); // 2019-10-24T18:45:12.000Z
end .TDataSet Helper : Foreachrow, LoadData <>, Savedata <>
uses
Helpers.TDataSet;
type
TCity = class
public
id: Integer;
City: string;
Rank: Variant;
visited: Variant;
end ;
var
dataset: TDataSet;
cityNames: TArray<string>;
idx: integer;
cities: TObjectList<TCityForDataset>;
begin
dataset := GivenDataSet(fOwner, [
{ } [ 1 , ' Edinburgh ' , 5.5 , EncodeDate( 2018 , 05 , 28 )],
{ } [ 2 , ' Glassgow ' , 4.5 , EncodeDate( 2015 , 09 , 13 )],
{ } [ 3 , ' Cracow ' , 6.0 , EncodeDate( 2019 , 01 , 01 )],
{ } [ 4 , ' Prague ' , 4.9 , EncodeDate( 2013 , 06 , 21 )]]);
SetLength(cityNames, dataset.RecordCount);
idx := 0 ;
dataset.ForEachRow(
procedure
begin
cityNames[idx] := dataset.FieldByName( ' city ' ).AsString;
inc(idx);
end );
writeln(string.Join( ' , ' , citiecityNamess));
cities := dataset.LoadData<TCityForDataset>();
witeln(cities.Count); // 4
witeln(cities[ 0 ].City); // Edinburgh
witeln(cities[ 3 ].Rank); // 4.9
cities[ 2 ].Rank := 5.8 ;
cities[ 2 ].visited := EncodeDate( 2020 , 7 , 22 );
cities.Add(TCity.Create());
cities[ 4 ].id := 5 ;
cities[ 4 ].City := ' Warsaw ' ;
dataset.SaveData<TCity>(cities);
// SaveData updated Cracow record and added Warsaw
endTSTRINGGRID HELPER : Isi dan ubah ukuran TSTRINGGRID
// StringGrid1: TStringGrid;
// StringGrid2: TStringGrid;
procedure TForm1.Button1Click (Sender: TObject);
var
structure, rows: string;
begin
StringGrid1.ColCount := 4 ;
StringGrid1.RowCount := 3 ;
StringGrid1.ColsWidth([ 40 , 100 , 90 , 110 , 80 ]);
StringGrid1.FillCells([
[ ' 1 ' , ' Jonh Black ' , ' U21 ' , ' 34 ' ],
[ ' 2 ' , ' Bogdan Polak ' , ' N47 ' , ' 28 ' ]]);
structure :=
' {"column": "no", "caption": "No.", "width": 30}, ' +
' {"column": "mesure", "caption": "Mesure description", "width": 200}, ' +
' {"column": "value", "caption": "Value", "width": 60} ' ;
rows :=
' {"no": 1, "mesure": "Number of DI Containers", "value": 120}, ' +
' {"no": 2, "mesure": "Maximum ctor injection", "value": 56} ' ;
data
jsData := TJSONObject.ParseJSONValue(Format(
' {"structure": [%s], "data": [%s]} ' , [structure, rows])
) as TJSONObject;
StringGrid2.FillWithJson(jsData);
end ;Pembantu RTL:
| Satuan | Deskripsi pembantu |
|---|---|
| Helper.tbytes | Memungkinkan untuk memanipulasi array byte: ukuran, muat & simpan, getter & setter |
| Helper.tdataset | Fungsi TDataset tambahan seperti: iterasi melalui dataset atau loadData / savedata - memungkinkan untuk memetakan daftar objek ke dataset |
| Helper.tdatetime | Metode yang memungkinkan dengan mudah memanipulasi tanggal dan waktu |
| Helper.tfield | Memungkinkan untuk memuat data base64 ke dalam bidang gumpalan atau memverifikasi tanda tangan dari data yang disimpan |
| Helper.tjsonObject | Metode Membaca Data atau Menyimpan dalam Struktur DOM JSON, seperti isValidisodate (FieldName) |
| Helper.tstream | Metode yang memfasilitasi membaca dan menulis data ke stream |
Vcl helpers:
| Kelas yang diperluas | Deskripsi pembantu |
|---|---|
| Tapplikasi | Sampel helper yang mengandung metode eksperimental seperti: InDeveloperMode . |
| Tdbgrid | Metode memanipulasi kolom DBGRID, seperti: AutosizeColumns - secara otomatis mengatur dengan setiap kolom |
| Tform | Metode Mengelola Timer: SetInterval dan SetTimeout |
| Tpicture | Izinkan untuk menetapkan Tbytes dan Tblobfield untuk melakukan tpicture dengan pengenalan format gambar otomatis |
| TStringGrid | Mengisi dan Mengkonfigurasi Kontrol Grid String: Memuat Data, Mengatur Lebar Kolom, Membersihkan Konten Sel atau Baris |
| Twincontrrol | Metode utilitas untuk mencari kontrol anak berdasarkan jenis atau nama. Terlihat untuk semua keturunan twincontrrol: tform, tpanel, dll. |
Pembantu Lainnya:
| Kelas yang diperluas | Deskripsi pembantu |
|---|---|
| Helper.tfdconnection | |
| Helper.tfdcustomManager |
Konvensi penamaan helper adalah untuk menambahkan Helper Suffix ke nama kelas yang diperluas, apa artinya penolong kelas untuk TDataSet akan memiliki nama TDataSetHelper .
Setiap penolong disimpan dalam file terpisah dan unit namanya adalah Helper.<ExpanedClassName>.pas .
Semua unit helper disimpan di subfolder src - pergi ke lokasi itu.
examples/01-playground/ - Pergi ke lokasi ituHelperPlayground.dprHelper.TStringGrid.pasHelper.TDataSet.pas dan Helper.TDBGrid.pasHelper.TBytes.pas dan Helper.TStream.pasexamples/02-formhelper/ - Pergi ke lokasi ituHelpersMiniDemo.dprHelper.TForm.pas dan penggunaan timer metode pembantuSejumlah besar kode VCL (FMX) dapat dihapus menggunakan penolong kelas, yang sebenarnya merupakan teknik refactoring yang mudah dengan risiko rendah untuk proyek yang kompleks. Menggunakan metode ini, tim dapat mulai meningkatkan proyek warisan mereka bahkan tanpa unit tes jaring pengaman. Selain itu, verifikasi pembantu yang baru dibuat dapat dengan mudah dilakukan dengan tes unit. Pendekatan ini memungkinkan untuk mengajar pengembang cara menulis tes unit dengan cara yang benar (belajar dalam praktik prinsip pertama atau lainnya). Tim juga dapat dengan mudah menerapkan proses pengembangan TDD (tes tulis terlebih dahulu dan kemudian mengimplementasikan fungsionalitas) dengan cara yang menyenangkan dan non-invasif.
Terkadang pembantu kelas juga bisa berbahaya jika digunakan secara tidak benar. Untuk alasan ini diperlukan untuk menerapkan proses pengembangan dan pengiriman yang lebih disiplin, saran yang terhubung dengan area itu tercakup dalam bagian berikut.
Manfaat Pembantu Kelas:
Sejak awal (Delphi 2006) hingga Delphi Berlin / 10.1 versi ada bug helper kelas yang cukup populer, yang memungkinkan untuk mengakses bidang pribadi dan metode pribadi menggunakan pembantu. Karena bug ini banyak pengembang mengidentifikasi ekstensi bahasa yang menarik ini dengan peretasan seperti itu. Penyalahgunaan pembantu kelas telah menyebabkan nilai solusi super kuat ini diremehkan.
Salah satu tujuan penting menggunakan pembantu kelas adalah kemampuan mengekstrak kode yang berguna dan dapat digunakan kembali, dan kemudian menutupinya dengan tes unit. Pengembang bahkan dapat dengan mudah menggunakan TDD, pendekatan yang didorong oleh pengujian di mana pertama -tama kita perlu menulis tes unit dan kemudian menerapkan logika
Repositori itu menunjukkan cara mempraktikkan pendekatan TDD. Setiap kelas dan helper rekaman memiliki tes Dunitx. Set uji unit dapat dengan mudah diperluas untuk memberikan cakupan tes yang lebih baik. Untuk memiliki pengalaman pengujian unit yang lebih baik, disarankan untuk menginstal TDD Delphi Ide Extension TestInsight terbaik - gratis dan platform yang sangat produktif yang dibuat oleh Stefan Gelienke. Kemuliaan untuk penulis! Tautan ke Repo TestInsight: Pergi ke situs Bitbucket
Tes unit sampel dapat ditemukan di folder repositori tests - pergi ke lokasi itu
Tes sampel TStringGrid HELPER HELPER ColsWidth METODE:
procedure TestTStringGridHelper.FiveColumns_ColsWidth ;
begin
fGrid.ColCount := 5 ;
fGrid.ColsWidth([ 50 , 100 , 90 , 110 , 80 ]);
Assert.AreEqual( 110 , fGrid.ColWidths[ 3 ]);
Assert.AreEqual( 80 , fGrid.ColWidths[ 4 ]);
end ;Pembantu kelas terlihat sangat menjanjikan dalam mengemis dan sebenarnya ada solusi hebat, tetapi ketika Anda membuat dan menggunakan lebih banyak dan lebih dari mereka, Anda akan mulai melihat beberapa hambatan. Untuk alasan ini, praktik yang baik harus diadaptasi dari awal untuk membantu menghindari potensi masalah.
Salah satu praktik yang disarankan saat menggunakan pembantu kelas adalah merencanakan pemeliharaan proyek yang baik, termasuk kontrol versi dan manajemen rilis. Langkah -langkah terbukti termasuk dua poin penting:
Proyek GitHub ini adalah contoh langsung dari teknik penyebaran tersebut. Kami menggunakan model percabangan yang terinspirasi oleh posting blog Vincent Driessen: model percabangan git yang sukses bersama dengan model perencanaan dan pengiriman yang terinspirasi oleh metode Kanban.
Model Cabang Proyek Pembantu Kelas

is021-grid-column-restore adalah untuk fitur baru: Metode LoadColumnsFromJsonString di TDBGrid Class Helper, yang memungkinkan untuk memulihkan konfigurasi kolom (pesanan, keterangan judul, lebar dan visibilitas) yang disimpan dalam string JSON. Definisi fitur ditulis dalam edisi gitub #21is014-doc-dark-side adalah bagian dokumentasi baru di file README.md utama.Proyek Pembantu Kelas Dewan Kanban

Dewan Kanban dan sesi perencanaan adalah teknik yang disarankan untuk dicapai - pengiriman tambahan. Proyek Pembantu Kelas tidak dapat disampaikan terlalu sering, karena biaya integrasi (Repositori Helper Kelas Integrasi dengan Proyek Delphi Final). Dan dari sisi lain pengiriman versi baru seharusnya tidak terlalu lama, karena semua proyek harus menggunakan keuntungan pembantu baru (reusability tinggi).
Pembantu kelas terlihat sangat bagus pada kontak pertama, tetapi mereka memiliki beberapa efek samping yang berbahaya. Di bagian ini Anda dapat lebih memahami kelemahan solusi ini. Jika Anda mencoba mendefinisikan dua pembantu kelas yang memperluas kelas dasar yang sama, Anda akan melihat bahwa hanya satu dari mereka yang akan terlihat. Lebih dari itu Anda tidak dapat memperluas fungsionalitas penolong kelas dengan warisan. Anda juga tidak dapat mendefinisikan memori tambahan (bidang) di penolong kelas.
Anda dapat melindungi proyek Anda dari efek kelemahan ini. Sebelum mendefinisikan penolong kelas baru, Anda harus mengajukan beberapa pertanyaan kepada diri sendiri:
TButton ) bukan untuk lebih umum ( TControl , TComponent , dll.).