Uli*_*rdt 0 delphi refactoring extract try-finally
如何将例程中的嵌套try/finally块"提取"到可重用的实体中?说我有
procedure DoSomething;
var
Resource1: TSomeKindOfHandleOrReference1;
Resource2: TSomeKindOfHandleOrReference2;
Resource3: TSomeKindOfHandleOrReference3;
begin
AcquireResource1;
try
AcquireResource2;
try
AcquireResource3;
try
// Use the resources
finally
ReleaseResource3;
end;
finally
ReleaseResource2;
end;
finally
ReleaseResource1;
end;
end;
Run Code Online (Sandbox Code Playgroud)
并想要类似的东西
TDoSomething = record // or class
strict private
Resource1: TSomeKindOfHandleOrReference1;
Resource2: TSomeKindOfHandleOrReference2;
Resource3: TSomeKindOfHandleOrReference3;
public
procedure Init; // or constructor
procedure Done; // or destructor
procedure UseResources;
end;
procedure DoSomething;
var
Context: TDoSomething;
begin
Context.Init;
try
Context.UseResources;
finally
Context.Done;
end;
end;
Run Code Online (Sandbox Code Playgroud)
我希望它具有与嵌套原件相同的异常安全性.是否足以将ResourceN变量初始化为零TDoSomething.Init并进行一些if Assigned(ResourceN) then检查TDoSomething.Done?
关于类的三件事使这个成语变得安全和容易:
Free空引用始终是安全的,因此您永远不需要先检查Assigned.由于析构函数可以依赖所有字段来获取已知值,因此Free无论构造函数在崩溃之前获得多远,它都可以安全地调用所有字段.每个字段将保留一个有效的对象引用,或者它将是nil,无论哪种方式,都可以安全地释放它.
constructor TDoSomething.Create;
begin
Resource1 := AcquireResource1;
Resource2 := AcquireResource2;
Resource3 := AcquireResource3;
end;
destructor TDoSomething.Destroy;
begin
Resource1.Free;
Resource2.Free;
Resource3.Free;
end;
Run Code Online (Sandbox Code Playgroud)
使用它与使用任何其他类的方式相同:
Context := TDoSomething.Create;
try
Context.UseResources;
finally
Context.Free;
end;
Run Code Online (Sandbox Code Playgroud)