6

我基本上試圖實現一個策略模式,但我想將不同的參數傳遞給「接口」實現(從同一對象繼承)並且不知道是否這個有可能。也許我選擇了錯誤的花樣,我得到類似於接口(C#)中具有不同參數的策略模式

「StrategyA」的錯誤不會實現繼承的抽象成員「無效DoSomething的(BaseObject)」

與下面的代碼:

abstract class Strategy 
{ 
public abstract void DoSomething(BaseObject object); 
} 

class StrategyA : Strategy 
{ 
public override void DoSomething(ObjectA objectA) 
{ 
    // . . . 
} 
} 

class StrategyB : Strategy 
{ 
public override void DoSomething(ObjectB objectB) 
{ 
    // . . . 
} 
} 

abstract class BaseObject 
{ 
} 

class ObjectA : BaseObject 
{ 
// add to BaseObject 
} 

class ObjectB : BaseObject 
{ 
// add to BaseObject 
} 

class Context 
{ 
    private Strategy _strategy; 

// Constructor 
public Context(Strategy strategy) 
{ 
    this._strategy = strategy; 
} 

    // i may lose addtions to BaseObject doing this "downcasting" anyways? 
public void ContextInterface(BaseObject obj) 
{ 
    _strategy.DoSomething(obj); 
} 

} 
+0

+1這樣一個常見的場景,我已經看到了實現這裏的obj持續增長和不斷增長的... – 2010-12-02 19:56:32

+0

使用的接口,而不是類 如 公共接口 { 無效DoSomething的(BaseObject對象); } 然後讓策略繼承那個接口。 將您的SP基於Interface或從此接口繼承的IStrategy接口。順便說一句,使用DIP注入與IoC像Ninject – GregJF 2017-05-12 01:45:18

回答

13

這聽起來像你實際上試圖重塑Visitor pattern,而不是按照預期的方式使用策略模式。另外,由於您使用C#,我建議您閱讀Judith Bishop的論文On the Efficiency of Design Patterns Implemented in C# 3.0。這涵蓋了訪問者模式的多種方法,並且有一些有趣的相關有用的想法。

+0

我將2種不同的文件格式轉換爲不同的格式,如果有幫助 - 我將格式A和B都轉換爲C – user210757 2009-12-24 18:10:34

+0

一個接口,一個ObjectC ConvertToC()方法,可能是你所需要的,在這種情況下。格式A和格式B(或與這些格式一起工作的類)只需實現該接口,即可完成。 – 2009-12-24 18:17:23

+0

但如果想要 2方法 - ObjectC ConvertToC(ObjectA),ObjectC ConvertToC(ObjectB b),我想我仍然會有同樣的問題 – user210757 2009-12-24 20:04:45

2

strategy pattern是爲了在相同類型的輸入對象上提供不同的行爲。

你實際上想要做的是依賴於上下文,我不確定它可以從已發佈的代碼中看到。

5

在C#方法中,簽名包括它的名字,類型參數列表和形式參數列表。在上面的代碼中,「覆蓋」與虛擬方法有不同的簽名,因此不允許。

策略模式背後的核心思想是定義一組隱藏在裏面的細節的可互換算法。但是,如果你的策略在不同的(按類型)他們可以接受作爲輸入,他們不再可以互換。所以在這種情況下看來這是一種錯誤的模式。

0

您可以創建一個參數類,像這樣:

public class Parameters 
{ 
    public ObjectA {get; set;} 
    public ObjectB {get; set;} 
} 

的改變你的方法接受的參數,如:

class StrategyA : Strategy 
{ 
public override void DoSomething(Parameters parameters) 
{ 
     // Now use ObjectA 
     if(parameters.ObjectA.SomeProperty == true) 
     { ... } 
} 
} 

這樣你就可以額外參數應您的要求在將來改變。另一種方法是使用Dictionary<string, object>在這裏你可以這樣做:

class StrategyA : Strategy 
{ 
    public override void DoSomething(Dictionary<string, object>parameters) 
    { 
      // Now use ObjectA 
      var someProperty = (bool)parameters["SomeProperty"]; 
      if() ... 
    } 
} 
4

你可能要考慮這篇文章: http://hillside.net/plop/2010/papers/sobajic.pdf 的模式被稱爲「參數化戰略格局」,並應與你所需要的。基本上,它建立在策略模式之上,並允許策略(不同算法)具有不同的參數。參數被封裝在特殊的類中,即參數類。每個策略(即算法)需要實現GetParameters()方法,該方法返回特定算法的parmaters實例列表。