抽象方法,可能为空

Abstract method, which may be empty

我有一个抽象class,其中包含一个抽象方法,只是有时需要。简单地说,原因是 class 执行了一些代码,只是有时会产生输出(然后需要处理)。所以抽象 class 的实现,确实有输出,需要实现这个方法,而没有输出的实现实际上可以不用。摘要 class 看起来像这样:

abstract class AbstractWorker
{
    public virtual Execute()
    {
        OutputModel output = await PerformActions();
        await HandleOutput(output);
    }        

    protected abstract Task<OutputModel> PerformActions();
    protected abstract Task HandleOutput(OutputModel);
}

我无法实现 PerformActions()HandleOutput() 方法,因为它们对于 AbstractWorker 的具体实现非常独特。而且,正如我所说,并不总是需要处理输出,但我需要强制执行该方法,以防它确实有输出。所以实现 wood 看起来像这样:

public class ConcreteWorker : AbstractWorker
{
    protected override async Task<OutputModel> PerformActions() 
    {
        // ...do stuff here, which produces no output
        return null;
    }

    protected override async Task HandleOutput(OutputModel output) 
    {
        // Do nothing, since there is no output
        return;
    }
}

虽然以上确实有效,但似乎有些愚蠢。但对于生成输出的情况,这是必需的。有什么更聪明的方法吗?

您可以使用基础中的默认逻辑将它们设为虚拟 class。

protected virtual async Task<OutputModel> PerformActions(){
    // ...do stuff here, which produces no output
   return null;
}

protected virtual async Task HandleOutput(OutputModel output) 
{ 
    // Do nothing, since there is no output
    return;
}

你不应该实现你没有使用的方法。 SOLID原则,接口隔离:

https://en.wikipedia.org/wiki/Interface_segregation_principle

我会在使用方法和不使用方法的 类 之间放置另一个抽象层。

解决这个问题的面向对象的方法是添加另一个抽象层。

AbstractWorker class 实现一个只有 Execute() 方法的接口 (IAbstractWorker)。 (好吧,因为它是一个异步方法,所以让我们把它 return 一个 Task 并称它为 ExecuteAsync 以遵循最佳实践)

让不需要处理输出的工作人员直接实现该接口,
需要处理输出的工作人员使用当前摘要 class.

基本上是这样的:

interface IAbstractWorker
{
    Task ExecuteAsync();
}

abstract class AbstractSepcializedWorker : IAbstractWorker
{
    public async Task ExecuteAsync()
    {
        OutputModel output = await PerformActions();
        await HandleOutput(output);
    }        

    protected abstract Task<OutputModel> PerformActionsAsync();
    protected abstract Task HandleOutputAsync(OutputModel);
}


class Worker : IAbstractWorker
{
    public async Task ExecuteAsync()
    {
        // implementation
    }
}

class SepcializedWorker : AbstractSepcializedWorker
{

    protected override Task<OutputModel> PerformActionsAsync()
    {
        // implementation
    }
    protected override Task HandleOutputAsync(OutputModel)
    {
        // implementation
    }
}

然后你让所有的worker classes 实现IAbstractWorker 接口,你可以很容易地创建新的具体worker classes 直接实现接口或继承抽象class(因此通过继承实现)。