Einzelnen Beitrag anzeigen

Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#17

AW: statt x-fache „if then else“-Abfragen eine intelligentere Lösung gesucht

  Alt 2. Jun 2013, 12:36
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
Intellekt ist das Verstehen von Wissen. Verstehen ist der wahre Pfad zu Einsicht. Einsicht ist der Schlüssel zu allem.
  Mit Zitat antworten Zitat