Dazu würde ich einfach einen neuen TFileNamePart erstellen und entsprechend anwenden.
Ich hatte mir so etwas vorgestellt:
Delphi-Quellcode:
unit FilenameBuilder;
interface
uses
Classes,
Generics.Collections,
SysUtils;
// ...
TFilenamePartFactory =
class
private
FParts : TDictionary<
string, IFilenamePart>;
public
constructor Create;
destructor Destroy;
override;
function GetPart(
const AKey :
string ) : IFilenamePart;
// >>
function GetConstantPart(
const AString :
string ) : IFilenamePart;
// <<
end;
// ...
implementation
// ...
TConstantPart =
class( TFilenamePart )
public
contructor create(AString:
String);
protected
function Build(
const AData : TMP3Meta ) :
string;
override;
private
constantString:
string;
end;
// ...
function TFilenameBuilder.GetFilename(
const AData : TMP3Meta ) :
string;
var
LBuilder : TStringBuilder;
LIdx : Integer;
begin
LBuilder := TStringBuilder.Create;
try
for LIdx := 0
to FParts.Count - 1
do
begin
// "-" entfernt
LBuilder.Append( FParts[LIdx].Build( AData ) );
end;
Result := LBuilder.ToString;
finally
LBuilder.Free;
end;
end;
// ...
{ TConstantPart }
constructor TConstantPart.create(AString:
string)
begin
constantString := AString;
end;
function TConstantPart.Build(
const AData : TMP3Meta ) :
string;
begin
Result := constantString;
end;
{ TFilenamePartFactory }
// ...
function TFilenamePartFactory.GetConstantPart(
const AString :
string ) : IFilenamePart;
begin
Result := TConstantPart.create(AString);
end;
end.
Dann könnte man wie folgt für den Builder eine Factory schreiben:
Delphi-Quellcode:
type TFilenameBuilderFactory = class
public
constructor create(AFactory: TFilenamePartFactory; ownsFactory: boolean = true);
destructor destroy; override;
(** Returns a *new* object, caller handles destruction. *)
function createBuilder(AString : string): TFilenameBuilder;
private
FFactory: TFilenamePartFactory;
FOwnsFactory: boolean;
// non-constant state
FInVariable: boolean;
FBuffer: string; // invariant: length(FBuffer) = 0
FBuilder: TFilenameBuilder; // invariant: FBuilder = nil
// methods
procedure flushBuffer;
end;
constructor TFilenameBuilderFactory.create(AFactory: TFilenamePartFactory; ownsFactory: boolean);
begin
FFactory = AFactory;
FOwnsFactory = ownsFactory;
setLength(buffer, 0);
FBuilder = nil;
end;
destructor TFilenameBuilderFactory.destroy
begin
if FOwnsFactory then FFactory.free();
end;
procedure TFilenameBuilderFactory.flushBuffer;
var
tempPart: IFilenamePart;
begin
if (length(FBuffer) > 0) then
begin
if inVariable
then tempPart := AFactory.GetPart(FBuffer) // not sure what TDirectory.getItem does when key does not exist!!!
else tempPart := AFactory.GetConstantPart(FBuffer);
ABuilder.add(tempPart);
end;
setLength(FBuffer, 0);
end;
function TFilenameBuilderFactory.createBuilder(AString : string): TFilenameBuilder;
var
position: integer;
begin
FBuilder = TFilenameBuilder.create();
inVariable = false;
for position := 1 to length(string) do
begin
if (AString[position] = '%') then
begin
flushBuffer();
inVariable = not inVariable;
end else begin
FBuffer := FBuffer + AString[position];
end;
end;
flushBuffer();
result = FBuilder;
FBuilder = nil;
end;
Dar Parser lässt noch viel Raum für Verbesserung, sollte aber als zur Verdeutlichung taugen.
Achtung:
Ich habe lange kein Delphi mehr benutzt, sind also wahrscheinlich Fehler drin.
Anmerkung zur Code-Qualität sind natürlich erwünscht