首页 > 解决方案 > 如何使不是其抽象类的子类的接口实现者表现得像该接口的抽象类?

问题描述

我想用一个例子来解释我的问题。可以说我有一个界面:

interface IActionPerformer
{
    bool IsReadyToExecuteAction();
    void Action();
    IActionImplementor GetImplementor();
}

以及方法的实现者Action()。我不知道这样做是对还是错,但无论如何,继续阅读我会解释我的目的。实施者:

interface IActionImplementor
{
   void Action();
}

还有一个实现的抽象类IActionPerformer

abstract class ActionPerformerBase: IActionPerformer
{
   private IActionImplementor _implementor;
   public abstract bool IsReadyToExecuteAction();
   public IActionImplementor GetImplementor()
   {
      return _implementor;
   }
   public void Action()
   {
      if (IsReadyToExecuteAction())
      {
         GetImplementor().Action();
      }
   }

   protected ActionPerformerBase(IActionImplementor implementor)
   {
      this._implementor = implementor;
   }
}

现在从这个抽象类继承的子类只有在准备好执行时才执行实际操作。

但是假设我的软件中有一个对象,它继承自不同的超类。但同时,这个对象必须表现得像一个IActionPerformer. 我的意思是这个对象必须实现IActionPerformer接口,比如:

class SomeOtherSubClass : SomeOtherSuperClass, IActionPerformer

此时,我想执行Action()方法并控制它是否准备好执行。

我认为用另一个对象调用方法可能是一个解决方案。我的意思是,控制器或处理程序对象将接口作为参数并以我想要的方式调用方法。喜欢:

IActionInvoker.Invoke(IActionPerformer performer)
{
   if (performer.IsReadyToExecuteAction())
   {
      performer.Action();
   }
}

或者每个IActionPerformer实现者都有一个IActionPerformerActionPerformerBase(感觉更好)对象来处理真正的控制,例如:

class SomeOtherSubClass : SomeOtherSuperClass, IActionPerformer
{
   ActionPerformerBase _realHandler;
   public bool IsReadyToExecuteAction()
   {
      return _realHandler.IsReadyToExecuteAction();
   }
   public void Action()
   {
      _realHandler.Action();
   }
   .
   .
   .
}

//This is the one get the job done actually.
class RealHandlerOfSomething : ActionPerformerBase

我可能不太清楚试图解释我的问题。我对抽象、设计模式和类似的东西不熟悉。并试图弄清楚它们。这个看起来像一个装饰器,它是 aIActionPerformer并且它有一个IActionPerformer. 但是当我研究装饰器模式时,我发现它就像从外壳到核心,我的意思是每个对象都执行它的方法和包装对象的方法。在我的例子中有点不同,我的意思是问题。这就是我们所说的“封装”吗?还是我在理解这些概念时遇到了大问题?

我希望我清楚地解释了自己。感谢大家阅读,试图提供帮助。

有一个美好的白天/夜晚。

标签: oopdesign-patternsarchitectureconceptual

解决方案


正如设计模式在第一章中所说:

优先使用对象组合而不是类继承

那是在 1994 年。继承使事情变得复杂。OP 是另一个例子。

在下文中,我将保持IActionPerformer原样ActionPerformerBase。由于继承与组合同构,你可以用继承做任何事情,你也可以用组合做 - 甚至更多,比如模拟多重继承。

以下是如何IActionPerformer从另一个子类实现接口并仍然重用ActionPerformerBase

public class SomeOtherSubClass : SomeOtherSuperClass, IActionPerformer
{
    private readonly ActionPerformerBase @base;

    public SomeOtherSubClass(ActionPerformerBase @base)
    {
        this.@base = @base;
    }

    public void Action()
    {
        // Perhaps do something before calling @base...
        @base.Action();
        // Perhaps do something else after calling @base...
    }

    // Other methods of IActionPerformer go here, possibly following the same pattern...
}

SomeOtherSubClass与 any 组合在一起ActionPerformerBase,并且由于ActionPerformerBase具有所需的功能,因此可以有效地重用该功能。

一旦你弄清楚了如何使用组合而不是继承来重用,请帮自己一个忙,从你的代码库中消除继承。相信我,你不需要它。十多年来,我一直在设计和编写生产代码,但没有继承。


推荐阅读