【问题标题】:Avoiding code duplication in Delphi在 Delphi 中避免代码重复
【发布时间】:2011-09-03 14:07:20
【问题描述】:

我有两个组件 A 和 B。组件 B 派生自组件 A,并与它共享大多数属性和过程。现在我有一个像这样的冗长程序:

procedure DoSomething;
begin
  Form1.Caption := Component_A.Caption;
  // hundreds of additional lines of code calling component A
end;

根据组件 B 是否处于活动状态,我想重用上述过程,并将 Component_A 部分替换为组件 B 的名称。那么它应该如下所示:

procedure DoSomething;
var
  C: TheComponentThatIsActive;
begin
  if Component_A.Active then
    C := Component_A;
  if Component_B.Active then
    C := Component_B;
  Form1.Caption := C.Caption;
end;

如何在 Delphi2007 中做到这一点?

谢谢!

【问题讨论】:

    标签: delphi components dry code-duplication


    【解决方案1】:

    TheComponentThatIsActive 应该与 ComponentA 的类型相同 (TComponentA)。

    现在,如果您遇到了一些属性/方法仅属于 ComponentB 的绊脚石,请检查并进行类型转换。

    procedure DoSomething;
    var
        C: TComponentA;
    
    begin
        if Component_A.Active then
            C := Component_A
        else if Component_B.Active then
            C := Component_B
        else
            raise EShouldNotReachHere.Create();
    
        Form1.Caption := C.Caption;
    
        if C=Component_B then
            Component_B.B_Only_Method;
    end;
    

    【讨论】:

    • 您需要处理这两种情况都不是活动的或跳跃断言它不会发生的情况。另外,当您可以测试=Component_B 时,为什么还要使用is
    • @David:很好地确保 C 被分配。至于类型转换与直接调用,这取决于有多少不同的组件和类型。如果我们添加一个Component_D,它也是TComponentB 类型,或者添加一个TComponentX 作为TComponentB 的后代,那么改变我的方式的代码就更少了,而且它很简单,可以解释前进。
    • 在这个例子中,C=Component_B 等价于 is 测试,不是吗?如果可能的话,我通常会回避使用is
    • @David:在这个简化的测试中,是的。在实际程序中,只有 OP 知道,这将是决定哪种解决方案更好的一个因素。可能需要对 OP 进行一些重构,具体取决于他或她需要对代码执行的操作。
    • 请随意改回来。但显然留下raise。 :-)
    【解决方案2】:

    您可以将 ComponentA 或 ComponentB 作为参数传递给 DoSomething。

    ComponentA = class
    public 
     procedure Fuu();
     procedure Aqq();
    end;
    
    ComponentB = class(ComponentA)
    public 
     procedure Blee();
    end;
    
    implementation
    
    procedure DoSomething(context:ComponentA);
    begin
      context.Fuu();
      context.Aqq();
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var cA:ComponentA;
        cB:ComponentB;
    begin
      cA:= ComponentA.Create();
      cB:= ComponentB.Create();
    
      DoSomething(cA);
      DoSomething(cB);
    
      cA.Free;
      cB.Free;
    end;
    

    【讨论】:

      猜你喜欢
      • 2014-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多