如何在.Net中处理现实世界中的多重继承场景



我以前听说过多重继承的陷阱,我知道.Net开发人员反对将其包含在内。

话虽如此,举一个简单的例子,比如"游戏公司"。游戏公司可以是:

  • 软件开发人员,如PlatinumGames
  • 出版商,例如Agetec
  • 同时是开发商和发行商,如暴雪娱乐
  • 仅限游戏硬件制造商(手头没有完全是制造商的公司的例子)
  • 以上所有,即任天堂

如果我必须在.Net中对此进行建模,我该如何处理"是"关系存在的事实,并且一家公司可以同时是其中的多个?想象一下,我已经建模了一个:

  1. Game类,具有List<Developer>Publisher作为属性
  2. 具有Manufacturer属性的Console

在理想的场景中,这应该是尽可能类型安全的,并且易于过滤和导航到每个类和从每个类导航(就像某种完全连接的实体框架映射)。

我也以同样的方式思考了一些事情,对此我可能知道"正确"的答案。

如果我将FatPersonTallPerson作为基类,并希望"绕过"多重继承限制,该怎么办?因为很有可能同时拥有一个又胖又高的人。在这种情况下,如果有一个Person有两个属性,WeightHeight,完全消除基类,可能会更干净。这只是一个重写我以前基于对象类型的任何过滤的问题,以考虑这些新的属性。

对于每一个多重继承案例,是否都有本质上等效的东西?对于我提出的这个特殊案例,该怎么办?

更新:

我读过这个答案,它被标记为我的副本(在发布这个之前),但我在这里有点不同意。我认为这与将SQL优化问题标记为其他所有SQL优化问题的重复相同。最后,每个案例都是不同的案例,需要不同的方法/答案。我认为这适用于这里,因为我问了一个非常固定的案例,就像另一个答案一样。

此场景是基于角色的软件工程的一个很好的例子,是当前研究的主题。这是因为这个问题没有唯一的解决方案。有几种方法,但都有缺点。

接口是设计类型关系的好方法。如果您制作例如DeveloperPublisher接口,则可能存在同时使用这两种接口的公司。然而,您不能从接口继承代码,并且通常会得到大量重复的代码。

更进一步,您提出了mixin继承。这基本上是用扩展方法增强的接口实现。看看这个例子:

class Company { }
interface Publisher { }
public static class PublisherMixin
{
public static void Publish(this Publisher p) 
{
//do something
}
}
class CompanyThatIsAPublisher : Company, Publisher { }

然后你可以做

var c = new CompanyThatIsAPublisher():
c.Publish();

您可以对多个mixin执行此操作。您甚至可以在弱引用字典的帮助下为mixin提供状态。

避免代码重复的另一种方法是委派。您仍然有接口层次结构,但为开发人员角色、发布者角色等创建对象。然后,公司只将方法调用转发给这些子对象。然而,这会导致客体精神分裂症。子对象并不真正属于可能造成问题的主对象。但是,您可以轻松地交换它们。

在C#中,您还可以使用DynamicObject。这样,您就可以动态地注册角色,并将方法调用动态地重新路由到适当的对象。因此,一家开发公司最终可以成为一家出版商,而不必失去自己的身份。这种方法也有对象精神分裂症的问题。