C# 有抽象类和接口(interface),它也应该有 "mixins"吗?

标签 c# visual-studio design-patterns oop

每隔一段时间,我就会遇到一种情况,我希望所有类都具有相似的逻辑。例如,也许我想要一个 Bird和一个 Airplane能够Fly() .如果您正在考虑“策略模式”,我会同意,但即使使用策略,有时也无法避免重复代码。

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

  • 两者 BirdAirplane需要持有一个实现 IFlyBehavior 的对象的实例.
  • 两者 BirdAirplane需要问的IFlyBehavior实例到 Fly()OnReadyToFly()叫做。
  • 两者 BirdAirplane需要问的IFlyBehavior实例到 Land()OnReadyToLand()叫做。
  • OnReadyToFly()OnReadyToLand()是私有(private)的。
  • Bird继承AnimalAirplane继承PeopleMover .

  • 现在,假设我们稍后添加 Moth , HotAirBalloon和其他 16 个对象,假设它们都遵循相同的模式。

    我们现在需要以下代码的 20 个副本:
    private IFlyBehavior _flyBehavior;
    
    private void OnReadyToFly()
    {
        _flyBehavior.Fly();
    }
    
    private void OnReadyToLand()
    {
        _flyBehavior.Land();
    }
    

    我不喜欢这个的两件事:
  • 它不是很 DRY(同样的九行代码一遍又一遍地重复)。如果我们发现了错误或添加了 BankRight()IFlyBehavior ,我们需要将更改传播到所有 20 个类。
  • 没有任何方法可以强制所有 20 个类一致地实现这种重复的内部逻辑。我们不能使用接口(interface),因为接口(interface)只允许公共(public)成员。我们不能使用抽象基类,因为对象已经继承了基类,而 C# 不允许多重继承(即使类没有继承类,我们以后可能希望添加一个新的行为来实现,比如说, ICrashable ,所以抽象基类并不总是一个可行的解决方案)。

  • 如果...?

    如果 C# 有一个新的结构会怎样,比如 patterntemplate或者[在这里填写你的想法],它像一个接口(interface)一样工作,但允许你在成员上放置私有(private)或 protected 访问修饰符?您仍然需要为每个类提供一个实现,但是如果您的类实现了 PFlyable模式,你至少有办法强制每个类都有必要的样板代码来调用 Fly()Land() .而且,借助像 Visual Studio 这样的现代 IDE,您将能够使用“实现模式”命令自动生成代码。

    就我个人而言,我认为扩展接口(interface)的含义以涵盖任何契约(Contract)更有意义,无论是内部(私有(private)/ protected )还是外部(公共(public)),但我建议首先添加一个全新的结构,因为人们似乎非常固执关于“接口(interface)”这个词的含义,我不希望语​​义成为人们回答的焦点。

    问题:

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

    更新

    根据 AakashM 的评论,我相信我请求的功能已经有了一个名称:Mixin。所以,我想我的问题可以缩短为:“C# 应该允许 Mixins 吗?”

    最佳答案

    您描述的问题可以使用访问者模式解决(一切都可以使用访问者模式解决,所以要小心!)

    访问者模式允许您将实现逻辑移至新类。这样你就不需要基类,访问者在不同的继承树上工作得非常好。

    总结:

  • 新功能不需要添加到所有不同的类型
  • 对访问者的调用可以上拉到每个类层次结构的根

  • 如需引用,请参阅 Visitor pattern

    关于C# 有抽象类和接口(interface),它也应该有 "mixins"吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2310388/

    相关文章:

    design-patterns - 用于监控多个对象的设计模式

    c# - 获取 Enumerable.First() 的 MethodInfo 与 Enumerable.OfType() 的 MethodInfo?

    c# - RX Observable.TakeWhile 在每个元素之前检查条件,但我需要在之后执行检查

    c# - 在 asp.net 中打印 html

    c# - 如何调试此 Web 服务 http 处理程序?

    entity-framework - 在 Entity Framework 中保存一个,保存全部

    c# - 异常堆栈跟踪

    c++ - 可在 CUDA 中使用的数组大小是否有限制?

    entity-framework - Visual Studio 2015 EDMX 模型浏览器和图表丢失

    design-patterns - MVVM是哪种类型的设计模式?