Принцип разделения интерфейса и удобство / вспомогательные методы

Как принцип сегрегации интерфейса применяется к вспомогательным / вспомогательным методам? Например:

Я хочу создать интерфейс, который представляет деловых партнеров. Минимум, который мне понадобится, - это метод установки и метод получения, который установит или получит полный список партнеров:

Interface Partners {
  method getList();
  method setList();
}

Я также хочу, чтобы у меня был метод contains(), чтобы сообщить мне, был ли определенный человек включен в список партнеров. Я считаю это вспомогательным или вспомогательным методом, потому что все, что он делает, это вызывает getPartners(), а затем проверяет, находится ли данный человек в этом списке.

Мое понимание принципа разделения интерфейса заключается в том, что я должен разделить свой метод contains() на отдельный интерфейс, поскольку кто-то может захотеть реализовать мой интерфейс Partners, не предоставляя реализацию для этого ненужного вспомогательного метода. В моем примере это не имеет большого значения, но список вспомогательных методов может быстро увеличиваться в размере (addPartner, addPartnerByID, addPartnerByUserid и т. Д.), Так что это практическая проблема.

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

Как применить принцип разделения интерфейса к таким методам?

2 ответа

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

акцент мой

Пожалуйста, обязательно есть contains() метод, если вы считаете, что важно иметь в своем API. Особенно, если весь ваш клиентский код в настоящее время использует один.

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

Если у вас были другие виды методов, которые не имели ничего общего с получением или настройкой Партнеров, то следует применить ISP, чтобы создать для этого другой интерфейс.

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

Следующий ответ основан на языке C#. Это может быть недействительным на другом языке.

Я хочу создать интерфейс, который представляет деловых партнеров

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

Абстрактные классы представляют иерархии, где каждый потомок этой иерархии является специализацией, поэтому вы можете добавить больше членов для обогащения семейства. В этом случае отношение описывает "Это X - Y"

Интерфейсы представляют собой набор характеристик и поведения, не связанных с какой-либо иерархией. Следовательно, основное намерение - связать классы разных типов, которые будут иметь одинаковые функции или поведение. Отношение описывает "Этот Х может сделать Y"

Итак, предполагая, что в вашем описании лучше подходит абстрактный класс, я предлагаю следующее:

Одним из вариантов может быть установка методов "getList()" и "setList()" в качестве неабстрактных методов и предоставление в абстрактный класс поля для хранения списка

public abstract Partner
{
      List<Partner> list;

      public void SetList(List<Partner> list)
      {
          list = list;
      }
      public List<Partner> GetList(Partner partner)
      {
          return list;
      }
}

Таким образом, метод "Contains" также может быть неабстрактным, поэтому вы не заставляете классы-потомки предоставлять реализацию.

public bool Contains(Partner partner)
{
    return list.Contains(partner);
}

И давайте предположим, что в будущем вы захотите добавить новые методы помощников. Эти методы могут быть новыми неабстрактными методами в базовом классе, поэтому вы не будете влиять на своих текущих потомков "Партнера".

Если вам нужно изменить реализацию методов helpers, вы можете установить ее как "виртуальную", чтобы классы-потомки могли переопределять базовую реализацию.

public virtual void AddPartner(Partner partner)
{
    list.Add(partner);
}
Другие вопросы по тегам