Как решить эту проблему проектирования: наследование от класса, который абстрагируется от интерфейса? - PullRequest
0 голосов
/ 20 октября 2018

Мне трудно найти решение для следующей проблемы.

Я разделяю классы с соответствующим интерфейсом, но мне нужно расширить класс для нового изменения вместо того, чтобы менять оригиналреализация для соответствия принципу открытого закрытия.

Это базовый класс 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);
}

, а расширенный класс - UrlMetadataResolver:

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

Чтоя должен делать?я должен создать интерфейс для UrlMetadataResolver (IUrlMetadataResolver)?

Если это так, это становится еще более запутанным.

Спасибо

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Это правда, что, поскольку вы не предоставили никакого описания того, что вы хотите достичь, не может быть никакого полного или конкретного ответа.

Но вот подсказка или два:

Если вы уже используете класс HttpRequest, то, вероятно, лучше всего не менять его;для того, чтобы соответствовать принципу открытого закрытия, как вы сказали.Так что да, создайте новый класс.

Если новая функциональность класса UrlMetadataResolver действительно расширяет функциональность класса HttpRequest;Это означает, что он использует методы HttpRequest и некоторые дополнительные, тогда да, вы должны наследовать от HttpRequest, чтобы иметь возможность использовать его методы и добавлять новые методы в новый класс.

Ив этом случае да, вы должны создать новый интерфейс, который наследуется от IHttpRequest и расширяет его.Смысл интерфейса заключается в том, чтобы разрешить изменение способа реализации вещей без изменения способа выполнения работ.Т.е. позже вы можете использовать другой подход и реализовать функции UrlMetadataResolver другим способом, другим классом.Использование интерфейса позволит вам изменить только то, что на вашем бизнес-уровне ничего не изменит, в ссылках интерфейса IUrlMetadataResolver.

Композиция также является хорошей практикой, как предлагается, но имеет больше смысла в случаях, когда мы хотим наследовать от нескольких классов.C # и .NET явно предпочитают композицию над наследованием (и они хорошо справляются), не допуская наследования более чем одного класса.

Если, с другой стороны, новая функциональность не расширяется, а переопределяет функциональность HttpRequest, тогда нужно пометить методы HttpRequest как виртуальные, наследовать ипереопределить в UrlMetadataResolver.

Можно, конечно, предположить, что вы можете идти обоими путями;переопределить и расширить класс HttpRequest.

Конечно, вы всегда можете создать новый класс UrlMetadataResolver без отношения к HttpRequest.

Надеюсь, я смогу помочь, веселое кодирование!

0 голосов
/ 23 октября 2018

Я рекомендую создать базовый класс, который реализует все методы, общие для классов:

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...