[英]Design pattern to use instead of multiple inheritance
來自C ++背景,我習慣了多重繼承。 我喜歡瞄准我腳的霰彈槍的感覺。 如今,我在C#和Java中工作得更多,在那里你只能繼承一個基類但實現任意數量的接口(我的術語是否合適?)。
例如,讓我們考慮兩個實現公共接口但不同(但需要)基類的類:
public class TypeA : CustomButtonUserControl, IMagician
{
public void DoMagic()
{
// ...
}
}
public class TypeB : CustomTextUserControl, IMagician
{
public void DoMagic()
{
// ...
}
}
這兩個類都是UserControl
所以我不能替換基類。 兩者都需要實現DoMagic
功能。 我現在的問題是該函數的兩個實現都是相同的。 我討厭復制粘貼代碼。
(可能的)解決方案:
TypeA
和TypeB
共享一個公共基類,在那里我只能編寫一次相同的函數定義。 但是,由於只有一個基類的限制,我無法在層次結構中找到適合的位置。 DoMagic
函數放在一個單獨的幫助器類中,但這里的函數需要(並修改)相當多的內部變量/字段。 將它們全部作為(參考)參數發送只會看起來很糟糕。 我用語言無關來標記它,因為它適用於使用這種one-baseclass-many-interfaces方法的所有語言。
另外,請指出我是否誤解了我提到的任何模式。
在C ++中,我只使用私有字段創建一個類,該函數實現並將其放在繼承列表中。 什么是C#/ Java之類的正確方法?
您可以使用策略模式或類似的東西使用具有 (組成),而不是一個 (繼承):
public class TypeA : CustomButtonUserControl, IMagician {
IMagician magicObj = new Magical();
public void DoMagic() {
magicObj.DoMagic();
}
}
public class TypeB : CustomButtonUserControl, IMagician {
IMagician magicObj = new Magical();
public void DoMagic() {
magicObj.DoMagic();
}
}
public class Magical : IMagician {
public void DoMagic() {
// shared magic
}
}
還有其他方法來實例化您的私有IMagician成員(例如通過構造函數將它們作為參數傳遞),但上面的內容應該讓您開始。
DoMagic
與很多私人成員合作。 你可以在internal
打包這些私有變量嗎? 這樣,擴展方法可以訪問它們。 如果沒有顯得特別好,選擇什么樣的感覺最好, 用它幾次,並重新安排明天。 :)
用組合替換繼承。
將'common'函數移動到單獨的類,創建該類的實例,並將其插入TypeA對象和TypeB對象。
復合圖案適用於復雜對象,這意味着焦點在於一個對象由其他對象組成。 策略模式可以被視為一種特殊情況,但策略不一定是一個對象。 我認為這將更適用於您的情況。 然后,這在很大程度上取決於DoMagic()
的性質。
public interface IMagician{ /* declare here all the getter/setter methods that you need; they will be implemented both in TypeA and TypeB, right? */ }
public static class MyExtensions {
public static void doMagic(this IMagician obj)
{
// do your magic here
}
}
現在,問題是如果你真的需要使用私有屬性/方法(而不是“內部”屬性),這種方法將無法工作。 嗯,實際上,如果你能通過反射閱讀這些屬性,你可能能夠發揮你的魔力,但即使它有效,它也是一個相當丑陋的解決方案:)
[請注意,“doMagic”將自動顯示為TypeA和TypeB的一部分,只是因為您實現了IMagician - 沒有必要在那里實現任何實現]
您可以使用合成將魔術師作為typeA和typeB的屬性
class Magician : IMagician
{
public void DoMagic()
{}
}
Class TypeA : CustomButtonUserControl
{
//property
Magician magicianInTypeA
}
Class TypeB : CustomTextUserControl
{
//property
Magician magicianInTypeB
}
abstract class Magical: CustomButtonUserControl
{
public void DoMagic()
{
// ...
}
}
public class TypeA : Magical
{
}
public class TypeB : Magical
{
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.