如何将DRY应用于涉及Form组件的接口实现?

时间:2015-08-28 13:22:43

标签: delphi interface delphi-xe2 dry

我有一个界面IComm声明例程SetMonitorLogLevel()

unit IFaceComm;
interface
type
  TMonitorLogLevel = (mllOnlyImportant, mllAll);

  IComm = Interface(IInterface)
    procedure SetMonitorLogLevel(LogLevel: TMonitorLogLevel);
  end;

end.

界面由2个表单实现,它们彼此相似,frmBarCommfrmFooComm,如下所示:

TfrmBarComm = class(TForm, IFaceComm.IComm)
  cboDebugLevel: TComboBox;
private
  procedure SetMonitorLogLevel(LogLevel: IFaceComm.TMonitorLogLevel);
end;

请注意,2个表单有许多共同的组件,例如cboDebugLevel,但也可以包含其他组件没有的组件。

两个表单都以完全相同的方式实现IComm.SetMonitorLogLevel()

procedure TfrmBarComm.SetMonitorLogLevel(LogLevel: IFaceComm.TMonitorLogLevel);
begin
  case LogLevel of
    IFaceComm.TMonitorLogLevel.mllOnlyImportant:
      Self.cboDebugLevel.ItemIndex := 0;
    IFaceComm.TMonitorLogLevel.mllAll:
      Self.cboDebugLevel.ItemIndex := 1;
  end;
end;

如何避免违反“不重复自己”(DRY)原则?我经常遇到这个问题,当复制粘贴的例程比我上面显示的简单例子大得多时,它特别难看。

2 个答案:

答案 0 :(得分:4)

处理此问题的常用方法是创建另一个实现接口的类。它可能看起来像这样:

type
  TComboBoxCommImplementor = class(TInterfacedObject, IFaceComm.IComm)
  private
    FDebugLevel: TComboBox;
  public
    constructor Create(DebugLevel: TComboBox);
    procedure SetMonitorLogLevel(LogLevel: TMonitorLogLevel);
  end;

constructor TComboBoxCommImplementor.Create(DebugLevel: TComboBox);
begin
  inherited Create;
  FDebugLevel := DebugLevel;
end;

procedure TComboBoxCommImplementor.SetMonitorLogLevel(
  LogLevel: IFaceComm.TMonitorLogLevel);
begin
  case LogLevel of
    IFaceComm.TMonitorLogLevel.mllOnlyImportant:
      FDebugLevel.ItemIndex := 0;
    IFaceComm.TMonitorLogLevel.mllAll:
      FDebugLevel.ItemIndex := 1;
  end;
end;

然后在表单中使用委托实现接口:

type
  TfrmBarComm = class(TForm, IFaceComm.IComm)
    cboDebugLevel: TComboBox;
  private
    FComm: IFaceComm.IComm;
    property Comm: IFaceComm.IComm read FComm implements IFaceComm.IComm
  public
    constructor Create(AOwner: TComponent); override;
  end;

constructor TfrmBarComm.Create(AOwner: TComponent);
begin
  inherited;
  FComm := TComboBoxCommImplementor.Create(cboDebugLevel);
end;

答案 1 :(得分:2)

创建一个拥有两个表单上使用的组件的框架。 框架实现IComm。使用框架和两种形式的两种形式都实现type TfrmBarComm = class(TForm) FFrameComm: TFrameComm; public property FrameComm: TFrameComm read FFrameComm implements IComm; end; 。 该框架可作为委托接口实现的属性进行访问。

看起来像这样:

"1.1"