2011-03-24 80 views
1

我想這應該是一個容易的因爲我必須做錯了什麼。德爾福IS操作符 - 操作符不適用於此操作數類型

這是我的代碼,我想在Delphi做一個策略模式:

unit Pattern; 

interface 

type 

    TContext = class; 

    IStrategy = interface 
    function Move(c: TContext): integer; 
    end; 

    TStrategy1 = class(TInterfacedObject, IStrategy) 
    public 
    function Move(c: TContext): integer; 
    end; 

    TStrategy2 = class(TInterfacedObject, IStrategy) 
    public 
    function Move(c: TContext): integer; 
    end; 

    TContext = class 
    const 
    START = 5; 
    private 
    FStrategy: IStrategy; 
    public 
    FCounter: integer; 
    constructor Create; 
    function Algorithm(): integer; 
    procedure SwitchStrategy(); 
    end; 

implementation 

{ TStrategy1 } 

function TStrategy1.Move(c: TContext): integer; 
begin 
    c.FCounter := c.FCounter + 1; 
    Result := c.FCounter; 
end; 

{ TStrategy2 } 

function TStrategy2.Move(c: TContext): integer; 
begin 
    c.FCounter := c.FCounter - 1; 
    Result := c.FCounter; 
end; 

{ TContext } 

function TContext.Algorithm: integer; 
begin 
    Result := FStrategy.Move(Self) 
end; 

constructor TContext.Create; 
begin 
    FCounter := 5; 
    FStrategy := TStrategy1.Create(); 
end; 

procedure TContext.SwitchStrategy; 
begin 
    if FStrategy is TStrategy1 then 
    FStrategy := TStrategy2.Create() 
    else 
    FStrategy := TStrategy1.Create(); 
end; 

end. 

而且如果FStrategy是TStrategy1則是給我:運營商並不適用於這一運算對象類型。 我在這裏做錯了什麼導致這應該工作,因爲我從很多Delphi語言參考瞭解?

回答

9

您已經從您的界面中省略了GUID。沒有它,is就無法正常工作。

編輯:乍一看,它仍然無法正常工作。您不能使用is來測試在Delphi中實現對象類型的接口引用(好吧,不是直接的)。你應該改變你的設計。例如,您可以更改接口或添加其他接口以返回實現的描述。

+4

詳細說明,QueryInterface是一個符號快捷方式,它通過其IID標識接口,Craig將其稱爲GUID。通過將光標置於'IStrategy = interface'下的空白行並按下CTRL + SHIFT + G來生成一個。 – 2011-03-24 16:17:21

+0

@David,這都是正確的,但即使這樣也不會使他的代碼工作,因爲IID/GUID不匹配類型引用。 – 2011-03-24 16:18:34

+2

@Craig從D2010開始,您可以從Delphi界面中恢復實現對象。 – 2011-03-24 17:19:16

4

你可以通過添加IID/GUID克雷格狀態,然後改變SwitchStrategy,使這項工作:

procedure TContext.SwitchStrategy; 
begin 
    if (FStrategy as TObject) is TStrategy1 then 
    FStrategy := TStrategy2.Create() 
    else 
    FStrategy := TStrategy1.Create(); 
end; 

德爾福的更現代的版本里,才能工作。我認爲德爾福2010是添加了將接口轉換爲實現對象的能力的地方。


不過,我傾向於避免這種情況的解決方案,去這樣的事情:

type 
    IStrategy = interface 
    function Move(c: TContext): integer; 
    function Switch: IStrategy; 
    end; 

    TStrategy1 = class(TInterfacedObject, IStrategy) 
    public 
    function Move(c: TContext): integer; 
    function Switch: IStrategy; 
    end; 

    TStrategy2 = class(TInterfacedObject, IStrategy) 
    public 
    function Move(c: TContext): integer; 
    function Switch: IStrategy; 
    end; 

function TStrategy1.Switch: IStrategy; 
begin 
    Result := TStrategy2.Create; 
end; 

function TStrategy2.Switch: IStrategy; 
begin 
    Result := TStrategy1.Create; 
end; 

procedure TContext.SwitchStrategy; 
begin 
    FStrategy := FStrategy.Switch; 
end; 

當你發現自己問的對象是什麼類型的,這通常表示設計弱點。

+7

「當你發現自己問一個對象是什麼類型的時候,這通常表明了設計的弱點。」生活的話。 – 2011-03-24 19:55:15

+0

感謝您提供這個寶貴的建議! – elector 2011-03-25 06:35:21

相關問題