1

いくつかのクラスとコンポーネントで開発したフレームワークがあります。すべての開発者が 1 つの場所からメソッドにアクセスできるように、フレームワーク全体にアクセスできるメイン オブジェクトを作成したいと考えています。

例:

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;

それは友達ですか、可能であればあなたからのアイデアが欲しいです。私の意図は、単一の広大な構造を作成することです。

4

2 に答える 2

2

コメントで既に書いたように、この場合、他のサービスへのアクセスを提供できる 1 つのメインサービス(メイン クラス、シングルトン) を使用することをお勧めします。すべてのモジュールには一意の 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;

here class constructor&単純にDictionarydestructorを作成して解放し ます。メソッドは、一意の ID で Service を返します。FServicesQueryService

class function TAppServices.QueryService(ServiceID: TGUID): TCustomAppService;
begin
    result := nil;
    if FServices.ContainsKey(ServiceID) then
        result := FServices[ServiceID];
end;

メソッドは、パラメーターのクラス名から属性 ( ) をRegisterService抽出し、このペア (id-service) を辞書に追加します。RTTIServciceIDAttribute

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;

summary:
TAppServicesアプリ内の任意のサービスへのアクセスを提供するメイン オブジェクトです。エンドサービスについて何も知らないため、依存関係はありません。必要に応じて実装を変更できます。必要な数の TCustomAppService クラスの子孫を持つことができます。アプリケーションに新しいサービスを追加する場合、TAppServicesクラス インターフェイスや実装を変更しないでください。

于 2012-11-21T20:09:12.640 に答える
2

このためのクラスを作成する必要はありません。

という名前のユニットを作成するだけMyApp.Framework.DataBaseです。Delphi は、「名前空間」の作成を可能にするユニット単位のドットをサポートしています。

Myapp.Delphiでは、uses リストに入力を開始すると、オートコンプリートも行われます。

さらに、共通のスコープで単純な関数/手順を編成するためにTDataBase呼び出すことができる静的メソッドを持つクラスを作成できます。TDataBase.Method

于 2012-11-21T14:43:30.283 に答える