我目前重写自由教育数字电路模拟器inertiality添加到它的功能。我的问题是如何调度事件,以便原班增加预阐述他们。我有这样的事情:

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如祝,专业超过300个组件继承形式TC1的行为。

但现在我必须添加一些特殊的操作(等于所有组件后代 从TC1每FUNC1时间被调用,期间操作艇员选拔如果我有 调用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,谁在叫? 它叫TC2.Func1而不是TH.Func1我希望? 有没有一种方法来覆盖descenants方法FUNC1 而无需编写一个辅助类的任何单独一个(他们将尽一切 相同的操作,意思正好等于代码)? 所以能够从TH调用300个后裔功能FUNC1 TC2-N

在换句话说,我试图找到一种方式来获得这样的Tcontainer呼叫c1.Func1呼叫;

NewFunc1(等于所有TC1后代)谁呼叫TC2.Func1(为TC1的任何后裔不同)。

任何人都可以提出一个方法来做到这一点?

有帮助吗?

解决方案

您有一些任务,每当有人呼叫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;

您将需要在所有的300子孙类重命名当前Func1功能。 IDE的重构工具或许能够提供帮助的。

其他提示

类助手是用于修改你不能在源获得的类是有用的。如果你是TC1类的作者,你将能够使通过引入TC1一类的辅助必要的更改,那么为什么不直接修改TC1.Func1,然后你做了什么?应工作。

您可以做以下的装饰模式来描述,当你的程序在模拟模式下运行出现需要特殊任务的包装类。它可以容纳您的数字组件的一个实例,并调用执行自己的任务后,该组件的方法。

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直接在数码类的地方会首先绕道到模拟类的方法。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top