C#有抽象类和接口,它是否也有"mixins"?

dev*_*xer 31 c# oop design-patterns visual-studio

我经常遇到一个案例,我希望所有类的集合都拥有类似的逻辑.例如,也许我想要a Bird和a Airplane都能够Fly().如果您正在考虑"战略模式",我会同意,但即使采用策略,有时也无法避免重复代码.

例如,让我们说以下适用(这与我最近遇到的真实情况非常相似):

  1. 双方BirdAirplane需持实现一个对象的实例IFlyBehavior.
  2. 双方BirdAirplane需要问的IFlyBehavior实例Fly()OnReadyToFly()被调用.
  3. 双方BirdAirplane需要问的IFlyBehavior实例Land()OnReadyToLand()被调用.
  4. OnReadyToFly()并且OnReadyToLand()是私人的.
  5. Bird继承AnimalAirplane继承PeopleMover.

现在,让我们说我们稍后添加Moth,HotAirBalloon和其他16个对象,让我们说它们都遵循相同的模式.

我们现在需要20份以下代码:

private IFlyBehavior _flyBehavior;

private void OnReadyToFly()
{
    _flyBehavior.Fly();
}

private void OnReadyToLand()
{
    _flyBehavior.Land();
}
Run Code Online (Sandbox Code Playgroud)

我不喜欢这两件事:

  1. 它不是很干(相同的九行代码一遍又一遍地重复).如果我们发现一个bug或添加一个BankRight()IFlyBehavior,我们需要传播完成的更改应用到所有20个班.

  2. 没有任何方法可以强制所有20个类一致地实现这种重复的内部逻辑.我们不能使用接口,因为接口只允许公共成员.我们不能使用抽象基类,因为对象已经继承了基类,并且C#不允许多重继承(即使这些类还没有继承类,我们以后可能希望添加一个实现的新行为,比如说,ICrashable抽象基类并不总是一个可行的解决方案.

如果...?

如果C#有一个新的构造,比如说pattern或者template或者[在这里填写你的想法],它就像一个接口,但允许你在成员上放置私有或受保护的访问修饰符怎么办?您仍然需要为每个类提供一个实现,但是如果您的类实现了该PFlyable模式,您至少可以强制执行每个类都有必要的样板代码来调用Fly()Land().而且,使用像Visual Studio这样的现代IDE,您将能够使用"实现模式"命令自动生成代码.

就个人而言,我认为只是扩展界面的含义以涵盖任何合同,无论是内部(私人/受保护)还是外部(公共)更有意义,但我建议首先添加一个全新的结构,因为人们似乎非常坚定关于"界面"一词的含义,我不希望语​​义成为人们答案的焦点.

问题:

无论你怎么称呼它,我想知道我在这里建议的功能是否有意义.我们是否需要某种方法来处理我们无法抽象出我们想要的代码的情况,因为需要限制性访问修饰符或者程序员无法控制的原因?

更新

根据AakashM的评论,我相信我要求的功能已有一个名称:一个Mixin.所以,我想我的问题可以简化为:"C#应该允许Mixins吗?"

Ben*_*zun 1

您刚刚描述了面向方面的编程

C# 的一种流行的 AOP 实现似乎是PostSharp(主站点似乎已关闭/不适合我,是直接的“关于”页面)。


跟进评论:我不确定PostSharp是否支持它,但我认为你正在谈论AOP的这一部分:

类型间声明提供了一种表达影响模块结构的横切关注点的方法。也称为开放类,这使程序员能够在一个地方声明另一个类的成员或父类,通常是为了组合与某一方面的关注点相关的所有代码。