Wednesday, August 24, 2005

Value Type Framework

Newsgroups: borland.public.delphi.oodesign
From: "Joanna Carter \(TeamB\)"
Date: Wed, 25 Aug 2004 17:17:33 +0100
Local: Thurs, Aug 26 2004 12:17 am
Subject: Re: Attribute Framework

I now call it a Value Type framework as it avoids conflicts with the .NET idea of Attributes.

Essentially it is a sophisticated version of RTTI that allows you to implement metadata accessible without having to make all properties published.

First, you need a simple metadata type...

IMetadata = interface
[GUID]
function GetName: string;
function GetType: TValueTypeType;
end;

...then you can add type specific additional data...

IStringMetadata = interface(IMetadata)
[GUID]
function GetLength: Integer;
function GetCase: TStringCase;
end;

IFloatMetadata = interface(IMetadata)
[GUID]
function GetSize: Integer;
function GetPrecision: Integer;
end;

Then comes the main Value Type types from which all business objects are built...

IValueType = interface
[GUID]
procedure Assign(const Other: IValueType);
function Clone: IValueType;
function GetAsString: string;
function GetFormatString: string;
function GetMetadata: IMetadata;
function GetName: string;
function GetRequired: Boolean;
function IsNull: Boolean;
procedure SetAsString(const Value: string);
procedure SetFormatString(const Value: string);
procedure SetNull;
procedure SetRequired(Value: Boolean);
property AsString: string
read GetAsString
write SetAsString;
property FormatString: string
read GetFormatString
write SetFormatString;
property Required: Boolean
read GetRequired
write SetRequired;
end;

Once again, we can add type specific information to the generic case.

e.g.

IIntegerValueType = interface(IValueType)
[GUID]
function GetValue: Integer;
procedure SetValue(Value: Integer);
property Value: Integer
read GetValue
write SetValue;
end;

IStringValueType = interface(IValueType)
[GUID]
function GetValue: string;
procedure SetValue(const Value: string);
property Value: string
read GetValue
write SetValue;
end;

All Business Objects that contain properties/attributes are derived from IObjectValueType, which is designed to contain a list of Value Types, one for each property about which you wish to obtain metadata...

IObjectValueType = interface(IValueType)
[GUID]
function GetValueType(const Name: string): IValueType;
function GetValueTypes: IValueTypeList;
function GetType: TGUID;
function GetValue: IInterface;
property Value: IInterface
read GetValue;
end;

Finally, you can build something like a Customer interface and class...

ICustomer = interface
[GUID]
function GetCode: string;
function GetName: string;
function GetTotalOnOrder: Double;
function GetTotalShipped: Double;
procedure SetCode(const Value: string);
procedure SetName(const Value: string);
procedure SetTotalOnOrder(Value: Double);
procedure SetTotalShipped(Value: Double);
property Code: string
read GetCode
write SetCode;
property Name: string
read GetName
write SetName;
property TotalOnOrder: Double
read GetTotalOnOrder
write SetTotalOnOrder;
property TotalShipped: Double
read GetTotalShipped
write SetTotalShipped;
end;

TCustomer = class(TObjectValueType, ICustomer)
private
// ICustomer
function GetCode: string;
function GetName: string;
function GetTotalOnOrder: Double;
function GetTotalShipped: Double;
procedure SetCode(const Value: string);
procedure SetName(const Value: string);
procedure SetTotalOnOrder(Value: Double);
procedure SetTotalShipped(Value: Double);
end;

Property accessors usually look like this...

function TCustomer.GetName: string;
begin
Result := (GetValueTypes['Name'] as IStringValueType).Value;
end;

procedure TCustomer.SetName(const Value: string);
begin
(GetValueTypes['Name'] as IStringValueType).Value := Value;
end;

This structure allows you to address the properties of an ICustomer as simple properties, but also as the sub value types of an object value type complete with all their metadata.

Normal code uses the ICustomer interface, whilst OPFs and MVP frameworks can make use of the Value Type information for persistence and display purposes - much more sophisticated than 'data-aware'. :-))

Comments: Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?