6

次の問題についていくつかの提案をしたいと思います: VCL コントロール用のアダプターを書きたいとしましょう。すべてのアダプタは同じ基本クラスを持つ必要がありますが、特別なコントロールのラッピングが異なります (たとえば、TEdit から値を取得することは、TSpinEdit から値を取得することとは異なります)。したがって、最初のアイデアは、次のようなクラス階層を作成することです

TAdapter = class
end;

TEditAdapter = class (TAdapter)
end;

TSpinEditAdapter = class (TAdapter)
end;

次に、vcl コントロールへの参照を保持するフィールドを導入します。私の特別なアダプターでは、もちろん、具体的なサブクラスで動作します。ただし、基本クラスには参照も含まれている必要があります (たとえば、アダプターを使用してコントロールを表示する場合)。

可能性 1 (プロパティ アクセサーでのダウンキャスト):

TAdapter = class
protected
  FCtrl : TControl;
end;

TEditAdapter = class (TAdapter)
  public
    property Control : TEdit read GetControl write Setcontrol;
end;
{...}
function TEditAdapter.GetControl : TEdit;
begin
  Result := FCtrl as TEdit;
end;

したがって、特定のメソッドを実装する場合は Control プロパティを使用し、基本クラスで何かを行う場合は protected フィールドを使用します。

可能性 2 (ジェネリック基本クラスを使用):

TAdapter = class
end;

TAdapter <T : TControl> = class (TAdapter)
protected
  FCtrl : T;
end;

TEditAdapter = class (TAdapter <TEdit>)
end;

どちらのソリューションをご希望ですか? それとも、さらに優れた 3 番目の解決策がありますか?

敬具、

キリスト教徒

4

2 に答える 2

4

次の 2 つの状況のいずれかになるため、ジェネリックを使用してこの問題を解決することはできません。

  • 「適応」させたいプロパティまたはメソッド (Textプロパティなど) は、祖先クラスで定義されています。その場合、祖先に 1 つのアダプターを使用してすべての子孫の問題を解決できるため、ジェネリックは必要ありません。
  • プロパティまたはメソッドは、適応させたいクラスによって導入されます。その場合、プロパティまたはメソッドにアクセスするには、その指定された typeのジェネリック型制約が必要になるため、ジェネリックを使用できません。例。Textのプロパティのアダプターが必要だとしましょうTMyClass。プロパティをTMyClass導入するのは 1 つであると仮定しましょう。Textそれにアクセスするには、ジェネリック型を宣言する必要がありますが、それTGeneric<T:TMyClass>は実際にはジェネリックではありません。

私の意見では、最初のオプションのように、クラスごとに特定のアダプターを作成するのが最善の策です。RTTI トリックを使用して、最初のオプションを実装しやすくすることができるかもしれませんが、それだけの価値があるかどうかはわかりません。

于 2011-06-17T10:13:58.810 に答える
0

ジェネリック バージョンでは、少なくとも TAdapter クラスで、コードの重複を避けることができます。型を使用Tすることで、多くの共有コードが可能になります。

一方、VCL 階層により、使用されるほとんどのプロパティとメソッドは既にTControl. したがって、非ジェネリック実装で重複するコードが非常に多くなるかどうかはわかりません。

現在のジェネリック実装はソースを複製せず、exe サイズを大きくする傾向があるため、非ジェネリック バージョンでは生成されるコードと RTTI が少なくなると思います。

IMHOジェネリックベースの設計は実装に抽象化を追加しますが、非ジェネリックはおそらくそれが適応するVCL階層により近いでしょう。

特定のケース (VCL のマッピング) では、非ジェネリック クラスをマップしようとしているため、非ジェネリック ソリューションを調査したいと思います。

別の (非 VCL ベースの) アダプター アーキテクチャの場合、私はおそらく純粋な汎用実装をボトムアップでアドバイスしたでしょう。

于 2011-06-17T09:56:37.213 に答える