Skip to main content
 首页 » 编程设计

language-agnostic之使用设计模式代替多重继承

2025年01月19日45qq78292959

来自 C++ 背景,我习惯于多重继承。我喜欢霰弹枪直接对准我的脚的感觉。现在,我更多地使用 C# 和 Java,你只能继承一个基类但实现任意数量的接口(interface)(我理解的术语正确吗?)。

例如,让我们考虑两个实现公共(public)接口(interface)但不同(但需要)基类的类:

public class TypeA : CustomButtonUserControl, IMagician 
{ 
    public void DoMagic() 
    { 
        // ... 
    } 
} 
 
public class TypeB : CustomTextUserControl, IMagician 
{ 
    public void DoMagic() 
    { 
        // ... 
    } 
} 

两个类(class)都是 UserControl s 所以我不能替换基类。两者都需要实现 DoMagic功能。我现在的问题是该函数的两个实现是相同的。我讨厌复制粘贴代码。

(可能的)解决方案:
  • 我自然要TypeATypeB共享一个公共(public)基类,我可以在其中编写相同的函数定义一次。但是,由于只有一个基类的限制,我无法在层次结构中找到适合的位置。
  • 也可以尝试实现一种 composite pattern .把 DoMagic函数在一个单独的辅助类中,但这里的函数需要(并修改)相当多的内部变量/字段。将它们全部作为(引用)参数发送看起来很糟糕。
  • 我的直觉告诉我 adapter pattern可以在这里占有一席之地,一些类在必要时在两者之间进行转换。但它也感觉很hacky。

  • 我将其标记为与语言无关,因为它适用于所有使用这种单一基类多接口(interface)方法的语言。

    另外,如果我似乎误解了我命名的任何模式,请指出。

    在 C++ 中,我只需创建一个带有私有(private)字段的类,即函数实现并将其放入继承列表中。 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 
        } 
    } 
    

    还有其他方法可以实例化您的私有(private) IMagician 成员(例如通过构造函数将它们作为参数传递),但以上内容应该可以帮助您入门。