如何解决这个设计问题:从抽象为接口的 class 继承?

How to solve this design problem: Inheriting from class that is abstracted to a interface?

我很难掌握以下问题的解决方案。

我正在将 classes 与其对应的接口解耦,但我需要扩展 class 以进行新的更改,而不是更改原始实现以符合开闭原则。

这是基础 class HttpRequest 实现 IHttpRequest

public class HttpRequest : IHttpRequest
{
    public string RawUrl { get; protected set; }

    public HttpRequest(string rawUrl)
    {
        RawUrl = rawUrl;
    }

    public string GetJsonFromUrl(string url)
    {
        //
    }
}

public interface IHttpRequest
{
    string GetJsonFromUrl(string url);
}

扩展后的class是UrlMetadataResolver:

public class UrlMetadataResolver : HttpRequest
{
    public UrlMetadataResolver(string rawUrl) : base(rawUrl)
    {
        //
    }
}

我该怎么办?我应该为 UrlMetadataResolver (IUrlMetadataResolver) 创建一个接口吗?

如果是这样的话,那就更乱了。

谢谢

我建议创建一个实现 classes 共有的所有方法的基础 class:

public abstract class HttpBaseRequest : IHttpRequest
{
    protected HttpBaseRequest(string rawUrl)
    {
        RawUrl = rawUrl;
    }


    public string RawUrl{ get; protected set; }


    public string GetJsonFromUrl(string url)
    {
        return "";
    }
}



public class HttpDataRequest : HttpBaseRequest
{
    public HttpDataRequest(string rawUrl) : base(rawUrl) { }
}



public class UrlMetadataResolver : HttpBaseRequest
{
    public UrlMetadataResolver(string rawUrl) : base(rawUrl) { }
}

如果需要,您仍然可以创建接口 IUrlMetadataResolver

确实,由于您没有提供任何关于您想要完成的内容的描述,所以不可能有任何完整或具体的答案。

但这里有一两个提示:

如果您已经在使用 HttpRequest class 那么最好的办法就是不要更改它;如您所说,为了符合开闭原则。所以是的,创建一个新的 class.

如果 UrlMetadataResolver class 的新功能确实扩展了 HttpRequest class 的功能;这意味着它使用 HttpRequest 的方法和一些额外的方法,那么是的,你应该继承 HttpRequest,以便能够使用它的方法,并在新的 class 中添加你的新方法.

在这种情况下,是的,您应该创建一个继承自 IHttpRequest 的新接口并对其进行扩展。接口的含义是允许改变事物的实现方式,而不改变事物的完成方式。 IE。您稍后可以使用另一种方法,并通过另一个 class 以另一种方式实现 UrlMetadataResolver 功能。使用接口将允许您在 IUrlMetadataResolver 接口的引用中仅更改它,而不更改业务层中的任何内容。

如建议的那样,组合也是一种很好的做法,但在我们想要从多个 class 继承的情况下更有意义。 C# 和 .NET 显然更倾向于组合而不是继承(它们做得很好),因为它们不允许继承多个 class。

另一方面,如果新功能没有扩展,而是覆盖了 HttpRequest 的功能,那么要走的路就是将 HttpRequest 方法标记为虚拟, 在 UrlMetadataResolver.

中继承和覆盖

你当然可以假设你可以双向选择;覆盖并扩展 HttpRequest class。

您当然可以随时创建一个与 HttpRequest.

无关的新 class UrlMetadataResolver

希望我能帮上忙, 编码愉快!