如何使不是其抽象 class 的子 class 的接口实现者表现得像该接口的抽象 class?
How to make interface implementors that are not sub classes of its abstract class behave like abstract class of that interface?
我想用一个例子来解释我的问题。假设我有一个接口:
interface IActionPerformer
{
bool IsReadyToExecuteAction();
void Action();
IActionImplementor GetImplementor();
}
以及 Action()
方法的实现者。我不知道这样做是对还是错,但无论如何,请继续阅读,我会解释我的目的。实施者:
interface IActionImplementor
{
void Action();
}
以及实现 IActionPerformer
:
的抽象 class
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;
}
}
现在从这个抽象class继承的子classes,只有当它准备好执行时才执行实际的动作。
但是假设我的软件中有一个对象,它继承自不同的超级 class。但与此同时,该对象的行为必须像 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
我可能不太清楚地解释我的问题。我对抽象、设计模式之类的概念很陌生。并试图找出它们。这个看起来像一个装饰器,它是一个 IActionPerformer
并且它有一个 IActionPerformer
。但是当我研究装饰器模式时,我看到它就像从 shell 到核心,我的意思是每个对象都执行它的方法和包装对象的方法。在我的例子中有点不同,我的意思是问题。这就是我们所说的“封装”吗?还是我在理解这些概念时遇到了很大的问题?
我希望我解释清楚了。感谢大家阅读,努力提供帮助。
玩得开心day/night.
正如第一章中的设计模式所述:
Favor object composition over class inheritance
那是在 1994 年。继承让事情变得复杂。 OP 是另一个例子。
在下文中,我将保持 IActionPerformer
和 ActionPerformerBase
不变。自 inheritance is isomorphic to composition 以来,您可以用继承做任何事情,您也可以用组合做 - 甚至更多,例如模拟多重继承。
以下是如何从另一个子类实现 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
与任何 ActionPerformerBase
组合,并且由于 ActionPerformerBase
具有所需的功能,因此可以有效地重用该功能。
一旦您弄清楚了如何使用组合而不是继承来进行重用,帮自己一个忙,从您的代码库中消除继承。相信我,你不需要它。我在没有继承的情况下设计和编写生产代码已有十多年了。
我想用一个例子来解释我的问题。假设我有一个接口:
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;
}
}
现在从这个抽象class继承的子classes,只有当它准备好执行时才执行实际的动作。
但是假设我的软件中有一个对象,它继承自不同的超级 class。但与此同时,该对象的行为必须像 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
我可能不太清楚地解释我的问题。我对抽象、设计模式之类的概念很陌生。并试图找出它们。这个看起来像一个装饰器,它是一个 IActionPerformer
并且它有一个 IActionPerformer
。但是当我研究装饰器模式时,我看到它就像从 shell 到核心,我的意思是每个对象都执行它的方法和包装对象的方法。在我的例子中有点不同,我的意思是问题。这就是我们所说的“封装”吗?还是我在理解这些概念时遇到了很大的问题?
我希望我解释清楚了。感谢大家阅读,努力提供帮助。
玩得开心day/night.
正如第一章中的设计模式所述:
Favor object composition over class inheritance
那是在 1994 年。继承让事情变得复杂。 OP 是另一个例子。
在下文中,我将保持 IActionPerformer
和 ActionPerformerBase
不变。自 inheritance is isomorphic to composition 以来,您可以用继承做任何事情,您也可以用组合做 - 甚至更多,例如模拟多重继承。
以下是如何从另一个子类实现 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
与任何 ActionPerformerBase
组合,并且由于 ActionPerformerBase
具有所需的功能,因此可以有效地重用该功能。
一旦您弄清楚了如何使用组合而不是继承来进行重用,帮自己一个忙,从您的代码库中消除继承。相信我,你不需要它。我在没有继承的情况下设计和编写生产代码已有十多年了。