클래스 헬퍼를 사용하여 Delphi 코드를 더 읽을 수 있도록하십시오.
클래식 콜 :
StoreDataset ( 1 , mysqlDataSet, true);더 읽기 쉬운 전화 :
mysqlDataSet.StoreSelected_StopAfterFirstError(
function():boolean
begin
Result := mysqlDataSet.FieldByName( ' Status ' ). Value = ' 1 '
end ), fDataStorer);tbytes 헬퍼 - 생성 숫자, Zlib compress, base64 인코딩, 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 도우미 : 스트림 또는 파일에서 tbytes를 저장하고로드하십시오. 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 ;TDATETIME 도우미 : 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 도우미 : 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 헬퍼 : 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 ;RTL 도우미 :
| 단위 | 도우미 설명 |
|---|---|
| 도우미 | 바이트 배열을 조작 할 수 있습니다 : 크기,로드 및 저장, 게터 및 세터 |
| 도우미 .tdataset | 다음과 같은 추가 TDATASET 기능 : DataSet 또는 LoadData / Savedata를 통한 반복 - 객체 목록을 데이터 세트에 매핑 할 수 있습니다. |
| 도우미 | 날짜와 시간을 쉽게 조작 할 수있는 방법 |
| 도우미 .tfield | Base64 데이터를 Blob 필드에로드하거나 저장된 데이터의 서명을 확인할 수 있습니다. |
| Helper.tjsonObject | 방법 데이터를 읽거나 isvalidisodate (FieldName)와 같은 JSON DOM 구조에 저장 |
| 도우미 | 스트림에 대한 데이터 읽기 및 쓰기를 용이하게하는 방법 |
VCL 헬퍼 :
| 확장 된 수업 | 도우미 설명 |
|---|---|
| tapplication | InDeveloperMode 와 같은 실험 방법을 포함하는 샘플 도우미. |
| tdbgrid | 방법 DBGRID 열 조작 : : AutosizeColumns- 각 열의 자동 배열 |
| tform | 메소드 관리 타이머 : SetInterval 및 Settimeout |
| tpicture | 자동 이미지 형식 인식으로 tbytes 및 tblobfield를 tpicture에 할당하십시오. |
| tstringgrid | 문자열 그리드 제어 채우기 및 구성 : 데이터로드, 열 너비 설정, 셀 또는 행의 내용 지우기 |
| Twincontrol | 유형 또는 이름별로 자식 제어를 검색하는 유틸리티 방법. 모든 두 번의 제어 후손에 대한 보이는 : tform, tpanel 등 |
기타 도우미 :
| 확장 된 수업 | 도우미 설명 |
|---|---|
| 헬퍼 .tfdConnection | |
| Helper.tfdCustomManager |
도우미 명명 컨벤션은 확장 클래스의 이름에 접미사 Helper 추가하는 것입니다. 이는 TDataSet 의 클래스 도우미가 TDataSetHelper 라는 이름을 가지고 있음을 의미합니다.
각 도우미는 별도의 파일에 저장되고 유닛의 이름은 Helper.<ExpanedClassName>.pas .
모든 헬퍼 장치는 src 하위 폴더에 저장됩니다. 해당 위치로 이동하십시오.
examples/01-playground/ - 해당 위치로 이동하십시오HelperPlayground.dprHelper.TStringGrid.pasHelper.TDataSet.pas 및 Helper.TDBGrid.pasHelper.TBytes.pas 및 Helper.TStream.pasexamples/02-formhelper/ - 해당 위치로 이동하십시오HelpersMiniDemo.dprHelper.TForm.pas 및 타이머 사용 도우미 방법클래스 헬퍼를 사용하여 엄청난 양의 VCL (FMX) 코드를 지울 수 있으며, 실제로는 복잡한 프로젝트에 대한 위험이 낮은 쉬운 리팩토링 기술입니다. 이 방법을 사용하여 팀은 단위 테스트 안전망 없이도 레거시 프로젝트를 업그레이드 할 수 있습니다. 또한 새로 생성 된 도우미의 검증은 단위 테스트로 쉽게 수행 할 수 있습니다. 이 접근법은 개발자에게 올바른 방식으로 단위 테스트를 작성하는 방법 (실제로 첫 번째 원칙 또는 기타 학습)을 가르 칠 수 있습니다. 팀은 또한 재미 있고 비 침습적 인 방식으로 TDD 개발 프로세스 (먼저 테스트를 작성 한 다음 기능을 구현)를 쉽게 적용 할 수 있습니다.
때로는 수업 도우미가 부적절하게 사용되면 위험 할 수 있습니다. 이러한 이유로 좀 더 훈련 된 개발 및 전달 프로세스를 적용해야합니다. 해당 영역과 관련된 제안은 다음 섹션에서 다루어집니다.
클래스 도우미 혜택 :
처음부터 (Delphi 2006)까지 Delphi Berlin / 10.1 버전까지는 인기있는 클래스 헬퍼 버그가 있었는데,이를 통해 헬퍼를 사용하여 개인 필드 및 개인 메소드에 액세스 할 수 있습니다. 이 버그로 인해 많은 개발자들이 그러한 해킹 으로이 흥미로운 언어 확장을 식별했습니다. 클래스 도우미의 오용으로 인해이 강력한 솔루션의 가치가 과소 평가되었습니다.
클래스 헬퍼를 사용하는 중요한 목적 중 하나는 유용하고 재사용 가능한 코드를 추출한 다음 단위 테스트로 다루는 능력입니다. 개발자는 먼저 단위 테스트를 작성한 다음 논리를 구현 해야하는 TDD, 테스트 중심 접근 방식을 쉽게 사용할 수도 있습니다.
이 저장소는 TDD 접근법을 연습하는 방법을 보여줍니다. 각 클래스와 레코드 도우미에는 Dunitx 테스트가 있습니다. 더 나은 테스트 범위를 제공하기 위해 단위 테스트 세트를 쉽게 확장 할 수 있습니다. 더 나은 단위 테스트 경험을 얻으려면 최고의 TDD Delphi IDE Extension Testinsight를 설치하는 것이 좋습니다. 무료 및 Stefan Glienke가 만든 매우 생산적인 플랫폼을 설치하는 것이 좋습니다. 저자에게 영광! TestInsight Repo에 대한 링크 : Bitbucket 사이트로 이동
샘플 단위 테스트는 tests 리포지토리 폴더에서 찾을 수 있습니다. 해당 위치로 이동하십시오.
TStringGrid 클래스 도우미 ColsWidth 방법의 샘플 테스트 :
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 ;클래스 도우미는 구걸에서 정말 유망한 것처럼 보이며 실제로 훌륭한 해결책이 있지만 점점 더 많은 것을 만들고 사용함에 따라 몇 가지 장애물을 알아 차리기 시작합니다. 이러한 이유로 잠재적 인 문제를 피하기 위해 처음부터 모범 사례를 조정해야합니다.
클래스 헬퍼를 사용할 때 권장되는 관행 중 하나는 버전 제어 및 릴리스 관리를 포함하여 우수한 프로젝트 유지 보수를 계획하는 것입니다. 두 가지 중요한 점을 포함한 입증 된 단계 :
이 GitHub 프로젝트는 이러한 배포 기술의 실시간 예입니다. 우리는 Vincent Driessen 블로그 게시물에서 영감을 얻은 분기 모델을 사용하고 있습니다 : Kanban Method에서 영감을 얻은 플래닝 및 배달 모델과 함께 성공적인 GIT 분기 모델.
클래스 도우미 프로젝트 분기 모델

is021-grid-column-restore 새로운 기능입니다. 메소드로드 LoadColumnsFromJsonString tdbgrid 클래스 도우미에서 JSON 문자열에 저장된 열 구성 (순서, 제목 캡션, 너비 및 가시성)을 복원 할 수 있습니다. 기능 정의는 GitHub 문제 #21에 작성되었습니다is014-doc-dark-side Main README.md 파일의 새 문서 섹션입니다.클래스 도우미 프로젝트 Kanban Board

Kanban Board 및 Planning Sessions는 증분 전달을 달성하기위한 기술입니다. 통합 비용 (최종 델파이 프로젝트와 통합 클래스 헬퍼 저장소)으로 인해 클래스 헬퍼 프로젝트를 너무 자주 제공 할 수 없습니다. 다른 프로젝트는 새로운 버전의 장점을 사용해야하기 때문에 새로운 버전의 다른 쪽에서는 너무 오래 걸리지 않아야합니다 (높은 재사용 성).
클래스 도우미는 첫 번째 접촉에서 정말 멋지게 보이지만 위험한 부작용이 있습니다. 이 섹션에서는이 솔루션의 약점을 더 잘 이해할 수 있습니다. 동일한 기본 클래스를 확장하는 두 개의 클래스 도우미를 정의하려고하면 그 중 하나만 보일 것임을 알 수 있습니다. 또한 상속을 통해 클래스 도우미 기능을 확장 할 수 없습니다. 또한 클래스 도우미에서 추가 메모리 (필드)를 정의 할 수 없습니다.
이러한 약점의 영향으로부터 프로젝트를 보호 할 수 있습니다. 새로운 클래스 도우미를 정의하기 전에 몇 가지 질문을해야합니다.
TButton )의 헬퍼를 더 일반 (tbutton)에 정의하십시오 ( TControl , TComponent 등).