2011-11-14 33 views
0

我有一個接口IFoo,我想爲其提供默認實現Foo。 Foo可以用作實現IFoo的其他類所包含的類/組件。用作包含組件的接口的默認實現

IFoo被幾個類使用,主要通過將調用轉發給Foo來實現它,但對於某些方法,它們可能會提供它們自己的實現。

Foo需要訪問調用類的(私有)成員。

將這些成員作爲參數傳遞給方法調用是不可能的,因爲它們不是(也不應該是)IFoo接口的一部分。

僅爲此目的向這些成員提供公共屬性是不必要的,因爲它會使調用類的接口過於複雜。

現在的問題是:讓Foo訪問這些成員的好設計是什麼,或者這通常如何實現?有沒有任何已知的設計模式?

編輯:繼承不是一個選項,因爲實現IFoo的類不能從同一個類繼承。

回答

1

沒有繼承你說?所以基本上你的Foo類不需要實現IFoo,只需要簡化IFoo的實現。爲什麼你不能在方法中添加一些參數呢?就像這樣:

好的,讓我們來看看。讓我做了一些方法,以確保我得到這個權利:

interface IFoo 
{ 
    void DisplayTime(); 
} 

而且你FooImplHelper(只是爲了這個例子的目的做靜態的,我不知道這是否是你的情況是有道理與否)

public static FooImplHelper 
{ 
    public static void DisplayTime(int UTFOffiset) 
    { 
     Console.WriteLine(DateTime.UtcNow + TimeSpan.FromHours(UTFOffset)); 
    } 
} 

和IFoo的實施

public class MyClock: BaseClock, IFoo 
{ 
    public void DisplayTime() 
    { 
     FooImplHelper.DisplayTime(2); 
    } 
} 

這是否有意義?如果沒有,你將不得不提供更多的信息。

Itay,

+0

我想我忘了提到這一點:繼承不是一種選擇,因爲實現IFoo的類不能從同一個類繼承。這是一個多重繼承的情況。 – Peladao

+0

更正。我希望。 – zmbq

+0

這實際上是我正在考慮的其中一種選擇,而且其實很常見。但是,我不覺得它是一個非常優雅的方式,因爲輔助類沒有使用接口,儘管它基本上用作其默認實現。不過謝謝你的描述。 – Peladao

0

另一種可能性,因爲你問了一個。不過,我更喜歡第一個。

定義的第二界面:

interface IFooImplHelper 
{ 
     int UTFOffset { get; } 
} 

,讓您的FooImpl類是這樣的:

class FooImpl: IFoo 
{ 
     private IFooImplHelper _helper; 

     public FooImpl(IFooImplHelper helper) 
     { 
      _helper = helper; 
     } 

     public void DisplayTime() 
     { 
      Console.WriteLine(DateTime.UtcNow + TimeSpan.FromHours(_helper.UTFDifference); 
     } 
} 

您的客戶將需要同時實現的IFoo接口(呼叫轉接至FooImpl)和IFooImplHelper接口。我真的不認爲他們中的任何人都會讚賞額外的工作,儘管...

Itay。

+0

是的,我認爲沿着這些線(以及),但我不喜歡廣告額外的接口給客戶。我想現在只是添加'int UTFOffset'到IFoo接口(儘管我起初不喜歡它),或者可能使用你的第一個解決方案。 (任何人給予pro和con兩種方式的獎勵分數) – Peladao

+0

不,如果對使用該接口的代碼沒有意義,請不要將偏移量添加到接口中。這會讓你的生活更輕鬆,犧牲你的用戶... – zmbq

+0

我想你是對的。 – Peladao

1

沒有理由聲明與接口方法簽名相同的實現方法簽名,所以您應該可以自由地傳遞參數。例如:

interface IFoo { 
    void MyMethod(); 
} 

static class FooImp { 
    public static void MyMethodImp(object private_object) { 
     // ... 
    } 
} 

class MyFoo : IFoo { 
    public void MyMethod() { 
     FooImp.MyMethodImp(m_PrivateObject); 
    } 
    object m_PrivateObject; 
} 

或者,你可以只記住私有對象的實現類和使用組成:

interface IFoo { 
    void MyMethod(); 
} 

static class FooImp { 
    public FooImp(object private_object) { 
     m_PrivateObject = private_object; 
    } 
    public void MyMethodImp() { 
     // Use the m_PrivateObject somehow. 
    } 
    readonly object m_PrivateObject; 
} 

class MyFoo : IFoo { 
    public MyFoo() { 
     m_PrivateObject = ... ; 
     m_FooImp = new FooImp(m_PrivateObject); 
    } 
    public void MyMethod() { 
     m_FooImp.MyMethodImp(); 
    } 
    object m_PrivateObject; 
    readonly FooImp m_FooImp; 
} 

當然,理想的解決方案是,如果C#支持多重繼承類和不只是界面,但可惜情況並非如此。

+0

在第二種情況下,爲什麼FooImp沒有實現IFoo,因爲方法簽名現在是相同的? – Peladao

+0

@Peladao因爲沒有目的 - 「FooImp」永遠不會被「IFoo」訪問,並且不能被「MyFoo」繼承,因爲它是從另一個類繼承的(在我的例子中沒有顯示,但在原始文章中提到)。 –

+0

@Peladao另外,你可能會使用兩種方法的組合,所以FooImp可能不會完全兼容IFoo。 –