2011-03-24 76 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

相关问题