В чем разница между провайдером и провайдером?

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

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

2 ответа

Programming to interfaces скажите нам, что наш код должен зависеть от интерфейсов, в то время как ISP направляет нас не создавать божественные интерфейсы, которые имеют большое количество методов. Большие интерфейсы вызывают две основные проблемы:

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

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

public interface ITask
{
    void Execute();
} 

Затем вы создаете SendToEmailTask класс, который реализует ITask интерфейс. Предположим, что через некоторое время появляется новое требование, что вам нужно добавить запись в SendToEmailTask, И согласно OCP Вы не должны изменять существующий код, а добавлять новый LoggingTask это также реализует ITask интерфейс (используя Decorator шаблон):

public class LoggingTask : ITask
{
    private readonly ITask task;

    public LoggingTask(ITask task)
    {
         //guard clause
         this.task = task;
    }

    public void Execute() 
    { 
        Logger.Log("task...");
        this.task.Execute();
    }
} 

Благодаря этому вы также добились Single Responsibility принцип.

Давайте посмотрим на принципы с точки зрения разработки модульных тестов.

Если вы пишете много модульных тестов для одного интерфейса / класса, это как если бы вы нарушали принцип ISP. Интерфейс слишком большой.

Если вы хотите переопределить какой-либо метод при тестировании интерфейса / класса, но вы не можете это сделать, потому что этот метод не является виртуальным, это как если бы вы нарушали принцип OCP, и ваш класс не допускает расширения.

Другие вопросы по тегам