4

私は現在、無料の教育用デジタル回路シミュレーターを書き直して、その機能に慣性を追加しています。私の問題は、イベントを元のクラスにディスパッチして事前精緻化を追加する方法です。私はこのようなものを持っています:

TC1 = class
  ID: integer;
  Connections : array [integer] of Pin;
  function Func1; virtual;
  function FuncN;
end;

TC2-1 = class (TC1)
  function Func1; override;
  function My1Func();
end;

TC2-n = class (TC1)
  function Func1; override;
  function MyNFunc();
end;


TContainer = class
  C1 : TC1;
  function ContFunc;
end;

function Container.ContFunc;
begin
    c1.Func1;
end;

これは、ContFunc が希望どおりに C2.Func1 を呼び出し、フォーム TC1 を継承する 300 を超えるコンポーネントの動作を特殊化することを意味します。

しかし今、いくつかの特別な操作を追加する必要があります (Func1 が呼び出されるたびに TC1 からのすべてのコンポーネントの子孫に等しく、その操作中に TC2-n.Func1 を呼び出す必要があるかどうかを選択します (祖先 TC1 のプロパティを変更した後)。 TC1 のすべての子孫を変更せずに、きれいにそれを行う方法はありますか? 次のようなヘルパー クラス (非推奨?) を使用できますか?

TH = class helper of TC1
  function Func1 virtual; override;
end;

function TH.Func1;
begin
  if x then TC2.Func1 else SaveActionData; 
end

TH を追加すると、TContainer が Func1 を呼び出すと、誰が呼び出されますか? TH.Func1 ではなく、TC2.Func1 を呼び出します。単一のヘルパークラスを作成せずに子孫メソッド Func1 をオーバーライドする方法はありますか? TH から TC2-n の 300 個の子孫関数 Func1 を呼び出すことができます。

つまり、c1.Func1; への Tcontainer 呼び出しによって、次のような呼び出しを取得する方法を見つけようとしています。

TC2.Func1 を呼び出す NewFunc1 (すべての TC1 子孫に等しい) (TC1 の子孫には異なる)。

誰でもそれを行う方法を提案できますか?

4

3 に答える 3

4

Func1オーバーライドされたメソッドで子孫が何を選択したかに関係なく、誰かが を呼び出すたびに実行する必要があるいくつかのタスクがあります。テンプレートメソッドパターンのジョブです。

基本クラスに、Func1必要な操作を実行し、保護された仮想メソッドを呼び出す非仮想パブリック メソッドを指定します。子孫はその仮想メソッドをオーバーライドできますが、クラスを使用するすべてのユーザーはパブリックの非仮想メソッドしか呼び出すことができません。

type
  TC1 = class
  protected
    function InternalFunc1: Integer; virtual; // abstract?
  public
    function Func1: Integer;
  end;

function TC1.Func1;
begin
  if x then
    Result := InternalFunc1
  else
    Result := SaveActionData; 
end;

子孫は をオーバーライドできるようInternalFunc1になり、基本クラスは適切な場合にのみ呼び出されるようにします。

type
  TC2 = class(TC1)
  protected
    function InternalFunc1: Integer; override;
  end;

Func1300 のすべての子孫クラスで、現在の関数の名前を変更する必要があります。IDE のリファクタリング ツールがそれを助けることができるかもしれません。

于 2010-03-02T16:42:24.483 に答える
0

デコレータパターンに従ってラッパー クラスを作成し、プログラムがアナログ モードで動作しているときに発生する必要がある特別なタスクを記述することができます。デジタル コンポーネントのインスタンスを保持し、独自のタスクを実行した後にそのコンポーネントのメソッドを呼び出すことができます。

type
  TAnalogueDecorator = class(TC1)
  private
    FComponent: TC1;
  public
    constructor Create(Wrapped: TC1);
    destructor Destroy; override;

    function Func1: Integer; override;
  end;

constructor TAnalogueDecorator.Create(Wrapped: TC1);
begin
  inherited Create;
  FComponent := Wrapped;
end;

destructor TAnalogueDecorator.Destroy;
begin
  FComponent.Free;
  inherited;
end;

function TAnalogueDecorator.Func1: Integer;
begin
  SaveActionData;
  Result := FComponent.Func1;
end;

x事前に状態を確認する必要がないことに注意してください。メソッドを呼び出すたびにチェックする代わりに、デジタル コンポーネントをアナログ コンポーネントでラップする前に一度チェックすることができます。これで、最初にデジタル クラスで直接呼び出したすべての場所が、Func1最初にアナログ クラスのメソッドに迂回されます。

于 2010-03-02T16:42:12.127 に答える
0

クラス ヘルパーは、ソースで取得できないクラスを変更する場合に役立ちます。あなたがクラス TC1 の作成者であり、TC1 のクラス ヘルパーを導入することで必要な変更を加えることができる場合は、TC1.Func1 を変更するだけで済みます。それはうまくいくはずです。

于 2010-03-02T11:56:14.083 に答える