私が知っている非常にきびきびとしたタイトル。
特定の操作を特定の順序で実行する必要がある一連のテキスト行があります。次のレコード構造を定義することで、これを行う方法を考え出しました。
TProcessOrderRecord = record
RecordTypes: TByteSet;
InitialiseProcedure: TPreScanProc;
ProcessProcedure: TProcessRecord;
FinaliseProcedure: TEndScanProc;
end;
AProcessOrderArray = array of TProcessOrderRecord;
Initialiseは、ホストオブジェクトのフィールドに入力するコンストラクターを呼び出す傾向があります。
プロセスは、RecordTypesのレコードタイプの1つに一致するテキスト行ごとに呼び出されるオブジェクトのプロシージャになります。
Finalizeは、デストラクタを呼び出す傾向があり、レコードの完全なセットが処理されたことを認識したときに、チェックを実行する可能性があります。
この配列を処理する手段は非常に簡単です。
procedure TImport.ScanTransferFile;
var
i: integer;
lArrayToProcess: AProcessOrderArray;
begin
lArrayToProcess := SetUpProcessingOrder(NLPGApp.ImportType);
for i := low(lArrayToProcess) to high(lArrayToProcess) do
begin
ProcessRecordType(lArrayToProcess[i].RecordTypes, lArrayToProcess[i].InitialiseProcedure, lArrayToProcess[i].ProcessProcedure, lArrayToProcess[i].FinaliseProcedure);
end;
end;
procedure TImport.ProcessRecordType(const RecordTypesToFind: TByteSet; PreScanProcedure: TPreScanProc; OnFindRecord: TProcessRecord; OnCompleteScan: TEndScanProc);
var
lLineOfText: string;
lIntegerRecordID: byte;
begin
if Assigned(PreScanProcedure) then PreScanProcedure;
try
if assigned(OnFindRecord) then
begin
Reader.GoToStartOfFile;
while not Reader.EndOfFile do
begin
lLineOfText := Reader.ReadLine;
lIntegerRecordID := StrToIntDef(GetRecordID(lLineOfText), 0);
if lIntegerRecordID in RecordTypesToFind then
begin
try
OnFindRecord(lLineOfText);
except
on E: MyAppException do
begin
// either raise to exit or log and carry on
end;
end;
end;
end;
end;
finally
// OnCompleteScan usually contains calls to destructors, so ensure it's called
if Assigned(OnCompleteScan) then OnCompleteScan;
end;
end;
私の問題は、レコードを次のように定義したいということです。
RecordTypes = [10]
InitialiseProcedure = ProcToCreateFMyObj
ProcessProcedure = FMyObj.do
FinaliseProcedure = ProcToFreeFMyObj
これは正常にコンパイルされますが、ProcessProcedureが呼び出されると、ProcessProcedureが設定されているときにFMyObjがnilであったため、FMyObjが設定されていてもTMyObjのインスタンスはnilになります。最初の割り当て時ではなく、呼び出し時にFMyObjのインスタンスを指すようにレコードを取得するクリーンな方法はありますか?
現在、ホストオブジェクトに「caller」メソッドを使用して、必要に応じてFMyObjインスタンスを呼び出すことができますが、これにより、多数の単一行メソッドを含む非常に肥大化したオブジェクトが作成されます。
問題を明確化/複雑化するために編集する
の1つのインスタンスがFObj
、複数のタイプのレコードを処理できる場合があります(通常、マスターと詳細の関係がある場合)。この場合、InitialiseProcedure
最初のレコードタイプのが作成さFObj
れ、FinaliseProcedure
2番目のレコードのが解放さFObj
れ、各レコードは(および)ProcessProcedure
の異なるプロシージャを参照できます。FObj
do1
do2