我有一个界面IComm
声明例程SetMonitorLogLevel()
:
unit IFaceComm;
interface
type
TMonitorLogLevel = (mllOnlyImportant, mllAll);
IComm = Interface(IInterface)
procedure SetMonitorLogLevel(LogLevel: TMonitorLogLevel);
end;
end.
界面由2个表单实现,它们彼此相似,frmBarComm
和frmFooComm
,如下所示:
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)原则?我经常遇到这个问题,当复制粘贴的例程比我上面显示的简单例子大得多时,它特别难看。
答案 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"