2015-08-28 42 views
1

我有一個接口IComm聲明一個例程SetMonitorLogLevel()如何將DRY應用於涉及表單組件的接口實現?

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)的原則?我經常遇到這個問題,當複製粘貼的例程比我上面顯示的簡單例子大得多時,它特別難看。

+0

實現一類接口,並創建表單從該類繼承 – fantaghirocco

+1

@fantaghirocco當你有兩個這樣的接口,A和B.然後,你必須Form1中會發生什麼事是想要實現A,想要實現B和Form3的Form2比想要實現A和B? –

+0

@大衛Heffernan這就是爲什麼我upvoted你的答案 – fantaghirocco

回答

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; 
+0

upvote代表 – fantaghirocco

+0

謝謝你這樣一個完整的答案(並感謝你對我在先前的評論請求表示感謝) – DBedrenko

2

創建擁有它們在這兩種形式中使用的組件的框架。 框架實現IComm。這兩種形式使用框架和兩種形式實現IComm。 該框架可以作爲委託接口實現的屬性訪問。

它看起來像這樣:

type TfrmBarComm = class(TForm) 
    FFrameComm: TFrameComm; 
public 
    property FrameComm: TFrameComm read FFrameComm implements IComm; 
end;