oop - 如何使不是其抽象类的子类的接口实现者表现得像该接口的抽象类?
问题描述
我想用一个例子来解释我的问题。可以说我有一个界面:
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
实现者都有一个IActionPerformer
或ActionPerformerBase
(感觉更好)对象来处理真正的控制,例如:
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
. 但是当我研究装饰器模式时,我发现它就像从外壳到核心,我的意思是每个对象都执行它的方法和包装对象的方法。在我的例子中有点不同,我的意思是问题。这就是我们所说的“封装”吗?还是我在理解这些概念时遇到了大问题?
我希望我清楚地解释了自己。感谢大家阅读,试图提供帮助。
有一个美好的白天/夜晚。
解决方案
正如设计模式在第一章中所说:
优先使用对象组合而不是类继承
那是在 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
具有所需的功能,因此可以有效地重用该功能。
一旦你弄清楚了如何使用组合而不是继承来重用,请帮自己一个忙,从你的代码库中消除继承。相信我,你不需要它。十多年来,我一直在设计和编写生产代码,但没有继承。