具有多种可选方法的接口模式

时间:2019-08-07 07:35:18

标签: c# design-patterns interface

对于带有可选方法的接口,例如在问题中 C# Interfaces with optional methods,答案是:使用两个界面

在使用多种(5种或10种以上)可选方法的情况下,常见的设计模式是什么?

示例

假设我们有一个没有方法的接口:

public interface IAnimal {}

动物可能会或可能不会做很多事情,例如:JumpFlyDigSwim等。

通过为每种方法IJumpableIFlyableIDigableISwimable等定义单个方法接口(具有唯一签名),我们可以检查动物是否在调用它之前有一个特定的方法:

IAnimal animal; // + initialize variable
if (animal is ISwimable swimmer)
{
    swimmer.Swim();
}

这可能导致带有大量已实现接口的类定义:

class Bear: IWalkable, IHuntable, IHibernatable, IClimbable, IRunable

这是常见的解决方案,还是有更好的方法来处理多个可选方法,以便可以判断一个方法是否已实现?

2 个答案:

答案 0 :(得分:1)

  • 我想鼓励您使用类似public void Call<Book>(ICallRequest<Book> request)这样的泛型,而不要重复request.ParseParams<Book>()
  • 您应将每个处理程序保留为单独的类,例如BookListHandlerNewBookHandler等,以获取正确的SRP,并以class-per-requesthandler为例检查MediatR

答案 1 :(得分:0)

您如何看待这种方法?

public interface IWalkable
{
    string Walk();
}

public interface IHuntable
{
    string Hunt();
}

public interface IHibernatable
{
    string Hibernate();
}


public interface IAnimal: IWalkable, IHuntable, IHibernatable
{       
    string SomeCommonAnimalFunction();
}

public class Animal: IAnimal
{
    private IWalkable walkableProvider = null;
    private IHuntable huntableProvider = null;
    private IHibernatable hibernatableProvider = null;

    Animal(IWalkable walkableProvider = null, IHuntable huntableProvider = null, IHibernatable hibernatableProvider = null) {
        this.walkableProvider = walkableProvider;
        this.hibernatableProvider = hibernatableProvider;
        this.huntableProvider = huntableProvider;
    }

    public string SomeCommonAnimalFunction() {
        return "SomeCommonAnimalFunctionResult";
    }

    public string Walk() {
        return walkableProvider == null ? "default walk" : walkableProvider.Walk();
    }

    public string Hunt() {
        return huntableProvider == null ? "default hunt" : huntableProvider.Hunt();
    }

    public string Hibernate() {
        return hibernatableProvider == null ? "default hibernate" : hibernatableProvider.Hibernate();
    }
}