2013-07-17 144 views
3

如何實現模板方法模式的變體,使具體類不會從基類繼承,但模式的整體特徵得到維護。它無法繼承的原因是它被迫從另一個類繼承,並且多重繼承不可用。無繼承的模板方法模式

例如,假設下面的Tempate Method模式:

public abstract class BaseClass { 
    public void Alpha() { 
     Beta(); 
    } 

    public abstract void Beta(); 

    public void Gamma() { 
     Delta(); 
    } 

    public abstract void Delta(); 

} 

public ConcreteClass : BaseClass { 
    public override void Beta() { 
     Gamma(); 
    } 

    public override void Delta() { 
     Console.WriteLine("Delta"); 
    } 
} 

... 
var object = new ConcreteClass(); 
object.Alpha(); // will outout "Delta" 

我怎麼能實現無具體類繼承BaseClass的同樣的結果?

+0

如果這是C#,那麼你不能做'BaseClass的對象=新的具體類()'沒有具體類繼承的BaseClass。你現在究竟有什麼和你想要達到的目標? –

+0

更改爲'var'。 –

+0

仍然不清楚你有什麼課 –

回答

2

您的基類可能依賴於通過構造函數注入的接口(或其他類型)。您的模板方法(一個或多個),然後可以使用這個接口/類型的方法來實現模式的期望的結果:

public class BaseClass 
{ 
    IDependent _dependent; 

    public BaseClass(IDependent dependent) 
    { 
     _dependent = dependent; 
    } 

    public void Alpha() { 
     _depdendent.Beta(); 
    } 

    public void Gamma() { 
     _depdendent.Delta(); 
    } 

} 

有效使用組成,而不是繼承。

+0

這解決了一半的問題。另一半是我需要從IDependent對象調用BaseClass方法。可以使用其他界面,但有更好的解決方案嗎? –

+1

你可以給依賴者一個對基類的引用。雖然開始有點臭。 OOD不安的水平正在上升,這表明這不是正確的解決方案... –

+0

我複製了MVP模式(減去'Model'),並使'View'類具有觸發的事件。 –

0

如果我理解正確的(你的代碼是不是對我來說很清楚),你有一個ConcreteClass目前從SomeOtherClass繼承,到模板方法添加到ConcreteClass,你可以擴展你的ConcreteClassabstract類:

public abstract class TplConcreteClass : ConcreteClass{ 

    public void Alpha() { 
     Beta(); 
    } 

    public abstract void Beta(); 

    public void Gamma() { 
     Delta(); 
    } 

    public abstract void Delta(); 

} 

比你創建新的具體類來實現的模板方法:

public NewConcreteClass : TplConcreteClass { 
    public override void Beta() { 
     Gamma(); 
    } 

    public override void Delta() { 
     Console.WriteLine("Delta"); 
    } 
} 

這樣你的客戶端代碼應該工作...

+0

這沒有解決這個問題。該問題詢問如何實現Template Method模式的變體,從而ConcreteClass不會從BaseClass繼承。 –

+0

@HermanSchoenfeld在你原來的問題中說你對你的限制是多重繼承......試着更清楚你是否問了一些問題 – davioooh

+0

這是不正確的,我沒有改變關於多重繼承的措辭。 –

0

可以通過提供在方法調用一個參照基類實現這一點:

public ConcreteClass { 
    public void Beta(BaseClass baseClass) { 
     baseClass.Gamma(); 
    } 

    public void Delta() { 
     Console.WriteLine("Delta"); 
     } 
}