AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi statt x-fache „if then else“-Abfragen eine intelligentere Lösung gesucht
Thema durchsuchen
Ansicht
Themen-Optionen

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

Ein Thema von juergen · begonnen am 29. Mai 2013 · letzter Beitrag vom 2. Jun 2013
Antwort Antwort
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.176 Beiträge
 
Delphi 11 Alexandria
 
#1

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

  Alt 29. Mai 2013, 21:17
Hallo zusammen,

wer kennt das nicht: Man fängt ein Projekt an und dann wird im Laufe der Zeit immer mehr hinten "dran gebastelt".
Ich bin nun an einem Punkt wo ich gar keine Lust mehr habe weiter zu machen, da eine bestimmte Procedure total unübersichtlich ist.

Folgende Gegebenheiten zur Umbenennung von Dateien:
Ich habe als Basis ca. 8 verschiedene MP3-Tag's (Interpret, Titel, Album usw.). Der Anwender kann momentan in einer Radio-Groupbox von ca. 10 Möglichkeiten eine Auswahl treffen, wie der Dateiname zusammengesetzt werden soll, also
a) welche MP3-Tag's überhaupt verwendet werden sollen
b) in welcher Reihenfolge der Dateiname zusammengestellt werden soll. Z.B. Interpret - Titel.mp3 oder Album - CdNr - TrackNr - Interpret - Titel.mp3

Dabei nutze ich als "Trenner" im Dateinamen jeweils " - " (Leerzeichen Bindestrich Leerzeichen).
Momentan habe ich für die gebräuchlichsten Dateinamen-Muster ein Radio-Group-Item erstellt und prüfe jedes einzelne Item über eine If then else Abfrage!
Der ganze Code wiederholt sich dann pro If-Abfrage, nur die Reihenfolge und die Anzahl der MP3-Tag's sind halt in jeder If-Abfrage anders.
Ich möchte dem Anwender keine RegEx-Ausdrücke oder dergleichen anbieten, es soll eben EINFACH und durch Lieschen Müller bedien bar sein.

Ich habe einige "nebulöse" Ansätze, wollte aber erst mal hier die Profis fragen wie sowas am besten umgesetzt werden kann um meinen völlig unübersichtlichen und sich ständig wiederholenden Code endlich richtig aufzuräumen.


Für Denkanstöße wäre ich sehr dankbar!
Jürgen
Indes sie forschten, röntgten, filmten, funkten, entstand von selbst die köstlichste Erfindung: der Umweg als die kürzeste Verbindung zwischen zwei Punkten. (Erich Kästner)
  Mit Zitat antworten Zitat
Benutzerbild von lbccaleb
lbccaleb

Registriert seit: 25. Mai 2006
Ort: Rostock / Bremen
2.037 Beiträge
 
Delphi 7 Enterprise
 
#2

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

  Alt 29. Mai 2013, 21:25
Also ich würde wohl so vorgehen, dass ich die CheckBoxen in einer Case Anweisung abfrage, und für die sich wiederholenden if Klauseln, eine separate Funktion erstelle.

Mehr fällt mir im mom auch nicht ein
Martin
MFG Caleb
TheSmallOne (MediaPlayer)
Die Dinge werden berechenbar, wenn man die Natur einer Sache durchschaut hat (Blade)
  Mit Zitat antworten Zitat
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.176 Beiträge
 
Delphi 11 Alexandria
 
#3

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

  Alt 29. Mai 2013, 21:39
@lbccaleb,
danke für deine Antwort.
Genau das war auch mein erster Ansatz. Ich hätte dann pro Checkbox eine Funktion.
Ich hoffe auf einen "dynamischere" Lösung, quasi nur eine Procedur oder dergleichen, welche bestimmte Parameter übergeben bekommt und dann alles richtig zusammenstellt....
Aber wie genau das gehen soll, da fehlt mir moementan der Ansatz.
Jürgen
Indes sie forschten, röntgten, filmten, funkten, entstand von selbst die köstlichste Erfindung: der Umweg als die kürzeste Verbindung zwischen zwei Punkten. (Erich Kästner)
  Mit Zitat antworten Zitat
Benutzerbild von lbccaleb
lbccaleb

Registriert seit: 25. Mai 2006
Ort: Rostock / Bremen
2.037 Beiträge
 
Delphi 7 Enterprise
 
#4

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

  Alt 29. Mai 2013, 21:45
Da kann man bestimmt auch weiter helfen, da müsste man aber halt wohl ein wenig sehen was genau du in deiner jetzigen Funktion/Procedure machst. Dann kann man das bestimmt ein wenig zusammen fassen und ggf. in separate Funktionen packen.
Martin
MFG Caleb
TheSmallOne (MediaPlayer)
Die Dinge werden berechenbar, wenn man die Natur einer Sache durchschaut hat (Blade)
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#5

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

  Alt 29. Mai 2013, 21:51
Auch wenn du dem Benutzer keine RegExen aufbürden willst, so kannst du das doch im Code verwenden.

Du kannst ja jedem RadioItem einen String zuweisen wie "<<I>> - <<T>> (<<Y>>)". (Zur Not über die Tag-Property und ein separates Array)
Anschließend lässt du für den konkreten Dateinamen einfach ein Suchen&Ersetzen über diesen String früberlaufen. <<I>> wird durch den Interpreten ersetzt usw.

Oder du benutzt direkt die integrierte string-Format Funktion, die kann ja auch bestimmte Indices ansprechen.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

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

  Alt 29. Mai 2013, 23:12
Baue dir doch einen Builder, der eben diese Dateinamen erstellt.

Die gewünschten Teile (Interpret, Titel, ...) und deren Reihenfolge einfach dem Builder übergeben und dann damit durch die Dateien laufen.
Für Vorbelegungen (Radiogroup) kannst du pro Eintrag eine Builder-Instanz hinterlegen und diese dann benutzen.

Delphi-Quellcode:
unit FilenameBuilder;

interface

uses
  Classes,
  Generics.Collections,
  SysUtils;

type
  TMP3Meta = record
    Interpret : string;
    Titel : string;
    Album : string;
    CdNr : Integer;
    TrackNr : Integer;
  end;

  IFilenamePart = interface
    ['{281FA130-B641-454D-8E9A-58D0C02F4C14}']
    function Build( const AData : TMP3Meta ) : string;
  end;

  TFilenamePartFactory = class
  private
    FParts : TDictionary<string, IFilenamePart>;
  public
    constructor Create;
    destructor Destroy; override;

    function GetPart( const AKey : string ) : IFilenamePart;
  end;

  TFilenameBuilder = class
  private
    FParts : TList<IFilenamePart>;
  public
    constructor Create;
    destructor Destroy; override;

    procedure AddPart( APart : IFilenamePart );
    procedure Clear;

    function GetFilename( const AData : TMP3Meta ) : string;
  end;

implementation

type
  TFilenamePart = class( TInterfacedObject, IFilenamePart )
  protected
    function Build( const AData : TMP3Meta ) : string; virtual; abstract;
  end;

  TInterpretPart = class( TFilenamePart )
  protected
    function Build( const AData : TMP3Meta ) : string; override;
  end;

  TTitelPart = class( TFilenamePart )
  protected
    function Build( const AData : TMP3Meta ) : string; override;
  end;

  TAlbumPart = class( TFilenamePart )
  protected
    function Build( const AData : TMP3Meta ) : string; override;
  end;

  TCdNrPart = class( TFilenamePart )
  protected
    function Build( const AData : TMP3Meta ) : string; override;
  end;

  TTrackNrPart = class( TFilenamePart )
  protected
    function Build( const AData : TMP3Meta ) : string; override;
  end;

  { TFilenameBuilder }

procedure TFilenameBuilder.AddPart( APart : IFilenamePart );
begin
  FParts.Add( APart );
end;

procedure TFilenameBuilder.Clear;
begin
  FParts.Clear;
end;

constructor TFilenameBuilder.Create;
begin
  inherited Create;
  FParts := TList<IFilenamePart>.Create;
end;

destructor TFilenameBuilder.Destroy;
begin
  FParts.Free;
  inherited;
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
        if LIdx > 0
        then
          LBuilder.Append( '-' );

        LBuilder.Append( FParts[LIdx].Build( AData ) );
      end;

    Result := LBuilder.ToString;

  finally
    LBuilder.Free;
  end;
end;

{ TInterpretPart }

function TInterpretPart.Build( const AData : TMP3Meta ) : string;
begin
  Result := AData.Interpret;
end;

{ TTitelPart }

function TTitelPart.Build( const AData : TMP3Meta ) : string;
begin
  Result := AData.Titel;
end;

{ TAlbumPart }

function TAlbumPart.Build( const AData : TMP3Meta ) : string;
begin
  Result := AData.Album;
end;

{ TCdNrPart }

function TCdNrPart.Build( const AData : TMP3Meta ) : string;
begin
  Result := IntToStr( AData.CdNr );
end;

{ TTrackNrPart }

function TTrackNrPart.Build( const AData : TMP3Meta ) : string;
begin
  Result := IntToStr( AData.TrackNr );
end;

{ TFilenamePartFactory }

constructor TFilenamePartFactory.Create;
begin
  inherited Create;
  FParts := TDictionary<string, IFilenamePart>.Create;

  FParts.Add( 'Interpret', TInterpretPart.Create );
  FParts.Add( 'Titel', TTitelPart.Create );
  FParts.Add( 'Album', TAlbumPart.Create );
  FParts.Add( 'CdNr', TCdNrPart.Create );
  FParts.Add( 'TrackNr', TTrackNrPart.Create );
end;

destructor TFilenamePartFactory.Destroy;
begin
  FParts.Free;
  inherited;
end;

function TFilenamePartFactory.GetPart( const AKey : string ) : IFilenamePart;
begin
  Result := FParts[AKey];
end;

end.
Das sieht zwar wild aus, ist aber in der Anwendung relativ zahm
Delphi-Quellcode:
program FilenameBuilderTest;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils,
  FilenameBuilder in 'FilenameBuilder.pas';

var
  PartFactory : TFilenamePartFactory;

procedure Test;
var
  LFilenameBuilder : TFilenameBuilder;
  LData : TMP3Meta;
begin

  LData.Interpret := 'Testinterpret';
  LData.Titel := 'Testtitel';
  LData.Album := 'TestAlbum';
  LData.CdNr := 1;
  LData.TrackNr := 10;

  LFilenameBuilder := TFilenameBuilder.Create;
  try

    LFilenameBuilder.AddPart( PartFactory.GetPart( 'TrackNr' ) );
    LFilenameBuilder.AddPart( PartFactory.GetPart( 'CdNr' ) );
    LFilenameBuilder.AddPart( PartFactory.GetPart( 'Album' ) );
    LFilenameBuilder.AddPart( PartFactory.GetPart( 'Interpret' ) );
    LFilenameBuilder.AddPart( PartFactory.GetPart( 'Titel' ) );

    WriteLn( LFilenameBuilder.GetFilename( LData ) );

    LFilenameBuilder.Clear;

    LFilenameBuilder.AddPart( PartFactory.GetPart( 'CdNr' ) );
    LFilenameBuilder.AddPart( PartFactory.GetPart( 'TrackNr' ) );
    LFilenameBuilder.AddPart( PartFactory.GetPart( 'Interpret' ) );
    LFilenameBuilder.AddPart( PartFactory.GetPart( 'Titel' ) );

    WriteLn( LFilenameBuilder.GetFilename( LData ) );

  finally
    LFilenameBuilder.Free;
  end;

end;

begin
  try

    PartFactory := TFilenamePartFactory.Create;
    try

      Test;

    finally
      PartFactory.Free;
    end;

  except
    on E : Exception do
      WriteLn( E.ClassName, ': ', E.Message );
  end;

  ReadLn;

end.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (29. Mai 2013 um 23:19 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:16 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz