既にお気づきのように、既存のクラスを継承によって拡張するプラグインを複数持つことはできません。プログラマーがコードを扱う場合を含め、アプリ全体を混乱させる可能性があります。
必要なのは、すべてのプラグインが特定のプロパティを登録できる、または TCustomer インスタンスが作成 (初期化)、ロード、保存、または削除されたときにいくつかのコールバック関数を提供できる、TCustomer クラスのある種の登録メカニズムです。結局、コアの TCustomer は、プラグインが存在する可能性があるという事実以上に、プラグインについて詳しく知る必要はありません。
データをどのようにロード/保存するかによって、コア TCustomer クラスは拡張子を認識する必要さえありません。永続化メカニズムにプラグインを認識させ、TCustomer / TOrder / TWhatever が初期化 / ロード / 保存 / 削除されるたびに呼び出されるコールバック関数を登録する方法を提供するだけで十分です。
また、GUI にプラグインを認識させ、UI の一部を登録してメイン GUI に各プラグインの特定のコントロール用に追加のタブなどを作成させる手段を提供する必要があります。
コード例がありません。これはまだ自分で実装していませんが、デザインについて考えてみましたが、これは私の遊びのリストに載っています。
とはいえ、基本的なメカニズムは次のようになります。
TBaseObject = class; // forward declaration
// Class that each plug-in's extensions of core classes needs to inherit from.
TExtension = class(TObject)
public
procedure Initialize(aInstance: TBaseObject);
procedure Load(aInstance: TBaseObject);
procedure Store(aInstance: TBaseObject);
procedure Delete(aInstance: TBaseObject);
end;
// Base class for all domain classes
TBaseObject = class(TObject)
private
MyExtensions: TList<TExtension>;
public
procedure RegisterExtension(const aExtension: TExtension);
procedure Store;
end;
procedure TBaseObject.RegisterExtension(const aExtension: TExtension);
begin
MyExtensions.Add(aExtension);
end;
procedure TBaseObject.Store;
var
Extension: TExtension;
begin
// Normal store code for the core properties of a class.
InternalStore;
// Give each extension the opportunity to store their specific properties.
for Extension in MyExtensions do
Extension.Store(Self);
end;