2011-04-25 47 views
3

我有一個base class它有一個嵌套類型,裏面。在外部(基本)類型中有一個函數,稍後它會被孩子覆蓋。實際上這個函數屬於OO的的inner type,但我仍然需要它,被base classsubtypes覆蓋。覆蓋嵌套類函數或使用代表?**

我應該使用該功能作爲callbackinner type或只是將它的inner type裏面,讓我們的subtypes從那裏覆蓋它?

編輯:示例代碼加入

class A 
{ 
    protected void func() { /* do something */ } 
    class B { /**/ } 
} 

// OR 

class A 
{ 
    class B 
    { 
     protected void func() { /* do something */ } 
    } 
} 

// Then 

class C : A 
{ 
    override func() { /**/ } 
} 
+0

你能提供一些代碼來說明它更好嗎? – ChrisWue 2011-04-25 01:10:19

回答

2

我的建議是板條箱用於由所述基類的構造發起內型功能委託:

internal class BaseClass 
{ 
    public BaseClass(Action myAction) 
    { 
     this.innerType = new InnerType(myAction); 
    } 

    public BaseClass() 
    { 
     // When no function delegate is supplied, InnerType should default to 
     // using its own implementation of the specific function 
     this.innerType = new InnerType(); 
    } 
} 

如您所見,派生類型可以調用基礎構造函數:base (overridenAction),他們可以在其中提供它們自己的im對最內層類型的功能的理解。當然,您沒有義務使用Action,但是您需要任何代表。

1

IMO所描述的內容看起來像The Strategy design pattern。考慮使用這種模式。你的代碼會更易於維護,因爲它包含了可識別的模式。你也可以看看state design pattern,通常你必須在這兩者之間進行選擇,它們是緊密相連的。

1

在這種情況下:

class A 
{ 
    class B 
    { 
     protected void func() { // do something } 
    } 
} 

不能從A類派生和B類中重寫func()

從您的描述看來,A派生類應該能夠覆蓋內部類B中的一些函數(或功能),這表明您可能應該重新考慮您的設計。無論是提取B和不讓它的內部類或通過這樣的接口讓你想覆蓋的顯式依賴的功能:

class A 
{ 
    private B _MyB; 
    public A(ISomeBehaviour behaviour) 
    { 
     _MyB = new B(behaviour); 
    } 
} 

,無論如何,如果你要堅持你的設計,然後我就不會推薦委託方法,而選擇覆蓋,因爲使用代表時,如果這是您的子類中所需的全部內容,則更難以添加修飾。

1

這就是外部類如何作爲內部服務類的策略。

請注意,不建議使用模式名稱(如TemplateMethodStrategy)作爲真實類名,請使用域中有意義的任何內容。同樣適用於OuterInner

public class Consumer 
{ 
    public void Foo() 
    { 
     IOuterFoo fooService = new Derived(); 
     fooService.OuterFoo(); 
    } 
} 

// ... 

public interface IOuterFoo 
{ 
    void OuterFoo(); 
} 

abstract class Base : Base.IStrategy, IOuterFoo 
{ 
    public void OuterFoo() { _service.Foo(); } 

    private readonly InnerService _service; 

    protected Base() { _service = new InnerService(this); } 

    private interface IStrategy { void Foo(); } 

    private class InnerService 
    { 
     private readonly IStrategy _strategy; 
     public InnerService(IStrategy strategy) { _strategy = strategy; } 
     public void Foo() { _strategy.Foo(); } 
    } 

    void IStrategy.Foo() { TemplateMethodFoo(); } 

    protected abstract void TemplateMethodFoo(); 
} 

class Derived : Base 
{ 
    protected override void TemplateMethodFoo() 
    { 
     throw new NotImplementedException(); 
    } 
} 
+3

當我看到大於10個LoC代碼樣本,例如'Foo','Bar'或者更糟,'OuterFoo'以及像'IStrategy'這樣的模式名時,它總是會讓我感到迷惑。我知道你是這樣做的,只是爲了舉例說明這個模式,但是對我來說,如果它能夠解決一些真實世界的問題,無論多麼牽強或簡化,它的可讀性都要高出十倍。 – 2011-04-25 10:30:25