Ich würde dir empfehlen eine abstrakte Klasse zu bauen, wo die konkreten Ableitungen jeweils die alten und neuen Varianten kapseln.
Bei geschickter Implementierung kannst du mit
FooNew.Assign( FooOld );
deine Daten konvertieren und auch in Zukunft noch die alten Daten lesen und (prinzipiell) sogar noch schreiben.
Delphi-Quellcode:
// Der abstrakte Teil, der auch immer wieder erweitert wird, und den aktuellen Stand repräsentiert
unit Settings;
interface
uses
System.Classes;
type
TSettings =
class abstract( TPersistent )
private
procedure AssignToSettings( Dest: TSettings );
protected
// der Getter kann hier auch virtuell implementiert werden
// damit bei neuen Eigenschaften wenigstens ein Default-Wert
// übermittelt wird, wenn der in den alten Informationen
// gar nicht verfügbar oder ableitbar ist
function GetBaud: Byte;
virtual;
abstract;
procedure SetBaud(
const Value: Byte );
virtual;
abstract;
procedure AssignTo( Dest: TPersistent );
override;
public
property Baud: Byte
read GetBaud
write SetBaud;
end;
implementation
{ TSettings }
procedure TSettings.AssignTo( Dest: TPersistent );
begin
if Dest
is TSettings
then
AssignToSettings( Dest
as TSettings )
else
inherited;
end;
procedure TSettings.AssignToSettings( Dest: TSettings );
begin
Dest.SetBaud( Self.GetBaud );
end;
end.
Implementierung eines alten Daten-Records
Delphi-Quellcode:
unit Settings.v1_0;
interface
uses
Settings;
type
T_Settings_XE4 =
Packed Record
ID: Byte;
Baud: Byte;
Line: Byte;
TSN1: Byte;
TSN2: Byte;
TSN3: Byte;
TSN4: Byte;
TSN5: Byte;
TSN6: Byte;
Description: ShortString;
ConnectionDef: ShortString;
end;
TSettings_V1_0 =
class( TSettings )
private
FData: T_Settings_XE4;
protected
function GetBaud: Byte;
override;
procedure SetBaud(
const Value: Byte );
override;
public
constructor Create( Data: T_Settings_XE4 );
end;
implementation
{ TSettings_V1_0 }
constructor TSettings_V1_0.Create( Data: T_Settings_XE4 );
begin
inherited Create;
FData := Data;
end;
function TSettings_V1_0.GetBaud: Byte;
begin
Result := FData.Baud;
end;
procedure TSettings_V1_0.SetBaud(
const Value: Byte );
begin
FData.Baud := Value;
end;
end.
Implementierung eines neuen Daten-Objekts
Delphi-Quellcode:
unit Settings.v2_0;
interface
uses
Settings;
type
T_Settings_Data =
class
private
FBaud: Integer;
public
property Baud: Integer
read FBaud
write FBaud;
end;
TSettings_v2_0 =
class( TSettings )
private
FData: T_Settings_Data;
FOwnsObject: Boolean;
protected
function GetBaud: Byte;
override;
procedure SetBaud(
const Value: Byte );
override;
public
constructor Create( Data: T_Settings_Data; OwnsObject: Boolean = True );
destructor Destroy;
override;
end;
implementation
{ TSettings_v2_0 }
constructor TSettings_v2_0.Create( Data: T_Settings_Data; OwnsObject: Boolean );
begin
inherited Create;
FData := Data;
FOwnsObject := OwnsObject;
end;
destructor TSettings_v2_0.Destroy;
begin
if FOwnsObject
then
FData.Free;
inherited;
end;
function TSettings_v2_0.GetBaud: Byte;
begin
Result := FData.FBaud;
end;
procedure TSettings_v2_0.SetBaud(
const Value: Byte );
begin
FData.FBaud := Value;
end;
end.
ein kleiner Test zum Hin- und Herumschubsen der Daten
Delphi-Quellcode:
program dp_182543;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
Settings
in '
Settings.pas',
Settings.v1_0
in '
Settings.v1_0.pas',
Settings.v2_0
in '
Settings.v2_0.pas';
procedure Main;
var
LOldSetting: T_Settings_XE4;
LNewSetting: T_Settings_Data;
LSettingOld, LSettingNew: TSettings;
begin
// die try..finally Blöcke habe ich der Übersichtlichkeit halber weggelassen!
LOldSetting.Baud := 24;
// Wert im alten Format gespeichert
LSettingOld := TSettings_V1_0.Create( LOldSetting );
// Wrapper drumherum
LNewSetting := T_Settings_Data.Create;
// neues Format
LSettingNew := TSettings_v2_0.Create( LNewSetting );
// Wrapper drumherum
LSettingNew.Assign( LSettingOld );
// einfach zuweisen
Writeln( LNewSetting.Baud );
// und schon ist auch im neuen Format der Wert :o)
end;
begin
try
Main;
except
on E:
Exception do
Writeln( E.ClassName, '
: ', E.
Message );
end;
end.
In der Anwendung selber würde ich immer mit
TSettings
arbeiten, weil es dann egal ist, wie und woher die Einstellungen denn nun wirklich kommen.