【问题标题】:How to handle a real world multiple inheritance scenario in .Net? [duplicate]如何在 .Net 中处理现实世界的多重继承场景? [复制]
【发布时间】:2014-01-24 09:59:58
【问题描述】:

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

话虽如此,请考虑一个简单的示例,例如“游戏公司”。游戏公司可以是:

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

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

在理想情况下,这应该是尽可能安全的类型,并且易于过滤和导航到每个类(如各种类型的完全连接的实体框架映射)。

我想到了同样的事情,我可能知道“正确”的答案。

如果我将FatPersonTallPerson 作为基类并想“解决”多重继承限制怎么办?因为很有可能同时拥有一个又胖又高的人。在这种情况下,如果单个Person 有两个属性WeightHeight,那么它可能会更简洁,完全消除基类。只需重写我之前基于对象类型进行的任何过滤以考虑这些新属性。

对于每个多重继承情况,是否存在与此等价的东西?对于我提出的这个特殊情况呢?

更新:

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

【问题讨论】:

  • 也许我不明白。您的解决方案是:如果您不继承,那么您将不会拥有多重继承?无论如何......有什么问题?
  • 您概述的特定情况没有定义任何需要多重继承的东西。例如,暴雪,你可以只有两个对象,BlizzardDeveloper 和 BlizzardPublisher。拥有一个对象同时继承 Developer 和 Publisher 有什么好处?
  • 如果您使用属性,即使使用提供它的语言,您也可以避开 MI,所以是的。真正的问题是您是否需要诸如 Publish 之类的方法,在这种情况下,如果实体实现了接口 IPublish,您会眯着眼睛说实体是发布者
  • 大公司创建部门以保持公司的可管理性。在软件中称为“封装”。
  • Titles.Where(x => x.Publisher_ID = this.ID),已连接。您的部分问题是您正在研究如何通过继承来实现它,而不是我需要什么来实现它。要使用继承锤所以这必须是一个钉子......

标签: .net inheritance data-modeling multiple-inheritance


【解决方案1】:

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

接口是设计类型关系的好方法。如果你做例如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。有了这个,您可以动态注册角色并动态地将方法调用重新路由到适当的对象。因此,开发公司最终可以成为发行商,而不必失去其身份。这种方法也存在对象精神分裂症问题。

【讨论】:

  • 非常好,我以前见过这种混合方法。你有什么建议让它对测试更友好吗?我一直认为这些扩展方法适用于没有副作用的小型纯方法。那里的Publish 方法可能有复杂的代码,并且在测试期间不可能从主类中模拟出行为。
  • 您可以添加一个模拟类,其方法与 mixin 相同。编译器会在扩展方法之前选择类方法。
猜你喜欢
  • 2013-10-24
  • 2018-09-11
  • 2020-08-09
  • 2018-02-01
  • 1970-01-01
  • 2022-10-17
  • 1970-01-01
  • 1970-01-01
  • 2016-04-19
相关资源
最近更新 更多