unit Tier;
interface
uses
System.Generics.Collections;
type
TValueObject =
class abstract
public
function SameValueAs( Other : TValueObject ) : Boolean;
virtual;
abstract;
function Equals( Obj : TObject ) : Boolean;
override;
end;
TTier =
class( TValueObject )
{$REGION 'values'}
private type
TValue =
record
Id : Integer;
Name :
string;
end;
const
_Values :
array [0 .. 2]
of TValue = ( ( Id : 0;
name : '
Hund' ), ( Id : 12;
name : '
Katze' ), ( Id : 5;
name : '
Maus' ) );
class procedure BuildItems;
{$ENDREGION}
{$REGION 'class'}
private
class var _Items : TList<TTier>;
class var _ItemsDict : TDictionary<Integer, TTier>;
class var _Shutdown : Boolean;
class function GetTier(
const Index : Integer ) : TTier;
static;
class function GetAll : TArray<TTier>;
static;
protected
class constructor Create;
class destructor Destroy;
public
class property _All : TArray<TTier>
read GetAll;
class property Hund : TTier
index 0
read GetTier;
class property Katze : TTier
index 12
read GetTier;
class property Maus : TTier
index 5
read GetTier;
{$ENDREGION}
{$REGION 'instance'}
private
FId : Integer;
FName :
string;
function SameTierAs( Other : TTier ) : Boolean;
constructor CreateItem( );
{$ENDREGION}
public
constructor Create( TierId : Integer );
destructor Destroy;
override;
function SameValueAs( Other : TValueObject ) : Boolean;
override;
function GetHashCode : Integer;
override;
function ToString :
string;
override;
procedure FreeInstance;
override;
property Id : Integer
read FId;
property name :
string read FName;
end;
implementation
uses
System.SysUtils;
{ TValueObject }
function TValueObject.Equals( Obj : TObject ) : Boolean;
begin
Result := ( Self = Obj )
or Assigned( Obj )
and ( Self.ClassType = Obj.ClassType )
and
SameValueAs( Obj
as TValueObject );
end;
{ TTier }
class procedure TTier.BuildItems;
var
LValue : TValue;
LItem : TTier;
begin
if Assigned( _ItemsDict )
then
Exit;
_Items := TObjectList<TTier>.Create( True );
_ItemsDict := TDictionary<Integer, TTier>.Create( );
for LValue
in _Values
do
begin
LItem := Self.CreateItem;
LItem.FId := LValue.Id;
LItem.FName := LValue.
Name;
_Items.Add( LItem );
_ItemsDict.Add( LValue.Id, LItem );
end;
end;
constructor TTier.Create( TierId : Integer );
begin
inherited Create;
if not _ItemsDict.ContainsKey( TierId )
then
raise EArgumentOutOfRangeException.Create( '
Ungültige TierId' );
FId := TierId;
FName := _ItemsDict[TierId].
Name;
end;
constructor TTier.CreateItem;
begin
inherited;
end;
class constructor TTier.Create;
begin
BuildItems;
end;
destructor TTier.Destroy;
begin
if _Items.
Contains( Self )
and not _Shutdown
then
Exit;
inherited;
end;
procedure TTier.FreeInstance;
begin
if _Items.
Contains( Self )
and not _Shutdown
then
Exit;
inherited;
end;
class function TTier.GetAll : TArray<TTier>;
begin
Result := TTier._Items.ToArray;
end;
function TTier.GetHashCode : Integer;
begin
Result := FId;
end;
class function TTier.GetTier(
const Index : Integer ) : TTier;
begin
Result := TTier._ItemsDict[
index]
end;
class destructor TTier.Destroy;
begin
TTier._Shutdown := True;
TTier._ItemsDict.Free;
TTier._Items.Free;
end;
function TTier.SameTierAs( Other : TTier ) : Boolean;
begin
Result := Assigned( Other )
and ( Self.FId = Other.FId );
end;
function TTier.SameValueAs( Other : TValueObject ) : Boolean;
begin
Result := ( Self = Other )
or Assigned( Other )
and ( Self.ClassType = Other.ClassType )
and
SameTierAs( Other
as TTier );
end;
function TTier.ToString :
string;
begin
Result := FName;
end;
end.