Как расширить / определить интерфейс, используя тот же открытый интерфейс? - PullRequest
3 голосов
/ 05 июня 2019

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

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

Я хотел бы знать, что это лучшая идея, чем создание нового интерфейса и обновление всех ссылок

Допустим,Я начну с этого:

public interface iMyWaiter : iMyWorker
{
    void takeOrder();
}

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

public class MyWaiter : MyWorker, iMyWaiter
{
}

теперь давайте предположим, что я хочу обновить iMyWaiter до версии 2, «нормальный» способ сделать это - создать новый интерфейс:

public interface iMyWaiter2 : iMyWaiter
{
    void getBill();
}

и извлечь класс изновый интерфейс:

public class MyWaiter : MyWorker, iMyWaiter2
{
}

Это повлечет за собой затраты на поиск ссылок iMyWaiter и замену его на iMyWaiter2

iMyWaiter waiter = new MyWaiter();
waiter.takeOrder();

, теперь становится:

iMyWaiter2 waiter = new MyWaiter();
waiter.takeOrder();

Чтоямы думаем о том, чтобы сделать общий интерфейс «iWaiter», который наследуется от версионного, и универсальный класс, который наследуется от версионного:

public interface iMyWaiter_1 : iMyWorker
{
    void takeOrder();
}
public class MyWaiter_1 : MyWorker, iMyWaiter_1
{
}


public interface iWaiter : iMyWaiter_1
{
}
public class MyWaiter : MyWaiter_1, iMyWaiter
{
}

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

public interface iMyWaiter_1 : iMyWorker
{
    void takeOrder();
}
public class MyWaiter_1 : MyWorker, iMyWaiter_1
{
}


public interface iMyWaiter_2 : iMyWaiter_1
{
    void getBill();
}
public class MyWaiter_2 : MyWaiter_1, iMyWaiter_2
{
}

, поэтому этот интерфейс и класс всегда доступны для создания, и мой код никогда не меняется, за исключением использования новых функций, предоставляемых новым интерфейсом

public interface iWaiter : iMyWaiter_2
{
}
public class MyWaiter : MyWaiter_2, iMyWaiter
{
}

теперь я могу просто добавить функцию «getBill» в мой код и не беспокоиться об интерфейсах:

iMyWaiter waiter = new MyWaiter();
waiter.takeOrder();
waiter.getBill();

Мои вопросы:

Это хорошая практика проектирования?

Какие минусы?

Что я не рассматриваю?

1 Ответ

3 голосов
/ 05 июня 2019

Предположим, у вас есть классы, которые зависят от IWaiter:

public class FoodOrder
{
    private readonly IWaiter _waiter;

    public SmallRestaurant(IWaiter waiter)
    {
        _waiter = waiter;
    }

    // other methods, one of them needs the waiter.
}

... и множества других классов, подобных им.И это ваше IWaiter:

public interface IWaiter
{
    Bill GetBill();
}

Не должно быть сценария, в котором вы добавляете новый метод в IWaiter, а затем вам нужно найти классы, которые в нем нуждаются, и обновить их доиспользуйте новый метод.Для этого есть две причины:

  • Это не серьезное изменение.Если одному из них не нужен новый метод, он может его игнорировать.
  • Процесс должен идти другим путем.Вы бы добавили метод к IWaiter, потому что классы нуждаются в своих официантах, чтобы сделать эту новую вещь.Потребность начинается с классов, которые зависят от IWaiter.Они являются причиной изменений, поэтому вам не нужно их искать.Не имеет смысла делать обратное, добавляя метод в интерфейс, который не нужен другим классам.

Тот факт, что добавление метода не является критическим изменением, должен устранить необходимостьСоздайте новый «версионный» интерфейс только потому, что добавлен новый метод.

Если вам действительно нужно было создать версионный интерфейс, также применимо вышеизложенное.Вы будете создавать новый интерфейс, потому что это нужно некоторым классам.Вам не нужно обновлять все классы, которые используют V1, чтобы теперь они использовали V2.Если бы вы это сделали, не было бы необходимости вообще поддерживать V1.

Управление версиями - это хорошо, чтобы предотвратить критические изменения, если мы опубликовали какую-то библиотеку, от которой зависит другой код, и мы не хотимсломать их, изменив интерфейс.Если все это находится в нашем собственном коде, и по какой-то причине мы должны внести серьезные изменения в интерфейс, тогда найти использование этого интерфейса будет очень легко.Когда мы меняем интерфейс, мы получаем ошибку компилятора везде, где используется интерфейс.

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