我有一个用几个类和组件开发的框架。我想创建一个可以访问整个框架的主对象,以便所有开发人员都可以从一个位置访问这些方法。
示例:
MyApp.Framework.DataBase
MyApp.Framework.DateUtils
MyApp.Framework.Users
MyApp.Framework.System
对象MyApp
映射整个框架,所有开发人员都可以随时访问。
主要问题是创建一个健壮且易于扩展的结构。过了一段时间,我将包括我们公司产品的功能和方法结构。
示例:
MyApp.Blog. (functions about Blog product)
MyApp.WebDocs. (functions WebDocs product)
关于课程的更多示例:
TMyAppBase = Class
Private
Function GetDatabase: TDataBaseClass;
Function GetUsers: TSystemUsersClass;
Function GetForms: TFormManager;
Public
Constructor Create; Virtual;
Destructor Destroy; Override;
Property Database: TDataBaseClass Read GetDatabase;
Property Users: TSystemUsersClass Read GetUsuarios;
Property Forms: TFormManager Read GetForms;
End;
使用此课程:
var
LMyApp: TMyAppBase
begin
ShowMessage(LMyApp.Users.ActiveUserName);
end;
那会是朋友吗,我希望你的想法可能。我的意图是创建一个单一而广泛的结构。
答案 0 :(得分:2)
您不必为此创建一个类。
只需创建一个名为MyApp.Framework.DataBase
的单位,依此类推。 Delphi以单位形式支持点,这样就可以创建“命名空间”。
当你开始在使用列表中输入Myapp.
时,Delphi甚至会自动完成。
此外,您可以使用静态方法创建一个类TDataBase
,您可以使用TDataBase.Method
调用这些方法来组织通用范围内的简单函数/过程。
答案 1 :(得分:2)
正如我在评论中已经写过的那样,我认为在这种情况下,最好使用一个主要的服务(主要类,单身),它可以为您提供对其他服务的访问权限。您的所有模块都具有唯一ID(TGUID
)。在程序执行开始时,他们应该在主服务中注册自己
例如。主要服务单位:
unit AppServices;
interface
uses generics.collections, rtti;
type
// Unique ID Attribute for services
ServiceIDAttribute = class(TCustomAttribute)
strict private
FId : TGUID;
public
constructor Create(ServiceID: string);
property ID : TGUID read FId;
end;
//Services Base class
TCustomAppService = class(TObject)
strict protected
public
end;
// Main Service Object
TAppServices = class(TObject)
strict private
class var
FServices : TObjectDictionary<TGUID, TCustomAppService>;
var
public
class constructor Create();
class destructor Destroy();
class procedure RegisterService(aService : TCustomAppService);
class function QueryService(ServiceID : TGUID):TCustomAppService;
end;
class constructor
&amp; destructor
只是创建并释放FServices
词典。 QueryService
方法通过其唯一ID返回Service:
class function TAppServices.QueryService(ServiceID: TGUID): TCustomAppService;
begin
result := nil;
if FServices.ContainsKey(ServiceID) then
result := FServices[ServiceID];
end;
方法RegisterService
从参数的类名中提取RTTI
属性(ServciceIDAttribute
)并将此对(id-service)添加到字典中:
class procedure TAppServices.RegisterService(aService: TCustomAppService);
var ctx : TRttiContext;
st : TRttiType;
a : TCustomAttribute;
id : TGUID;
begin
ctx := TRttiContext.Create();
try
st := ctx.GetType(aService.ClassType);
for a in st.GetAttributes() do begin
if not (a is ServiceIDAttribute) then
continue;
id := ServiceIDAttribute(a).ID;
FServices.AddOrSetValue(id, aService);
break;
end;
finally
ctx.Free();
end;
end;
现在,关于终端服务。例如UserManager单元:
unit UserManager;
interface
uses AppServices;
const
SID_UserManager : TGUID = '{D94C9E3A-E645-4749-AB15-02631F21EC4E}';
type
[ServiceID('{D94C9E3A-E645-4749-AB15-02631F21EC4E}')]
TUserManager = class(TCustomAppService)
strict private
FActiveUserName: string;
public
property ActiveUserName: string read FActiveUserName;
end;
implementation
initialization
TAppServices.RegisterService(TUserManager.Create());
end.
现在我们可以测试我们的代码:
procedure TestApp();
var uMgr :TUserManager;
dbMgr : TDBmanager;
begin
dbMgr := TAppServices.QueryService(SID_DBManager) as TDBManager;
if dbMgr.Connected then
writeln('connected!')
else writeln('not connected');
uMgr := TAppServices.QueryService(SID_UserManager) as TUserManager;
writeln('Active user: ', uMgr.ActiveUserName);
end;
<强>摘要强>
TAppServices
是主要对象,可以访问App中的任何服务。它对终端服务一无所知,因此它没有依赖性。您可以根据需要更改其实施。
您可以根据需要拥有尽可能多的TCustomAppService类后代。向应用程序添加新服务时,不应更改TAppServices
类接口或实现。