Эти интерфейсы должны быть унаследованы на уровне интерфейса или реализованы на уровне класса?

Я создаю консольное приложение с целью изучения шаблонов состояния и наблюдателя. Программа основана на базовой системе ордеров, в которой каждый ордер может иметь состояние (ожидающий, готовый, представленный i.e state pattern) и подписчики, заинтересованные в получении уведомлений от заказа при его обновлении, уведомляются (шаблон наблюдателя).

класс Order реализует три интерфейса;IOrder, IOrderState и IObservable но я понял, что вместо этого я возможно, интерфейсы наследуются друг от друга. Какой подход был бы лучше? Когда бы вы сделали реализацию класса из каждого из интерфейсов отдельно, вместо того, чтобы говорить,IOrder наследовать от двух других?

например:

public class Order : IOrder, IOrderState, IObservable

или

public interface IOrder : IOrderState, IObservable

редактировать Возможно, я только что ответил на свой вопрос - прав ли я, думая, что вы сделаете интерфейс IOrder наследуемым от двух других интерфейсов, если вы уверены, что объект что будет реализовывать его (класс Order) всегда нужно будет использовать эти методы? И если вы не уверены, нужны ли методы интерфейсов или другие классы i.e возможно, порядок, который не должен соблюдаться подписчиками, тогда вы включили бы интерфейсы отдельно на уровне класса?

4 ответов


по данным ISP (Interface Segregation Principle) правило, должно быть, что IOrder интерфейс реализует IOrderState, IObservable интерфейсы. Итак, какой класс реализует IOrder, Он также будет реализовывать другие 2 интерфейса.

таким образом, 2-й случай более уместен. т. е.

public interface IOrder : IOrderState, IObservable

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

однако, если вы можете придумать случай, когда классу нужен только IOrder, а не эти два других, вы можете разделить их.

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

например. кто-то, использующий вашу библиотеку, должен знать только то, что предоставляется IOrder, а не IOrderstate.


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

когда каждый класс В вашей библиотеке выглядит так:

interface IMyClass {}
class MyClass : IMyClass {}

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

если бы вы могли представить себе любой другой IOrder impelmentation, затем сделать IOrder интерфейс. В противном случае выбросьте его (например, я не могу представить два или более разных IOrderState реализации).

если каждый IOrder должно быть IObservable, тогда унаследовать IOrder С IObservable. Это полностью зависит от ваших целей использования.


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

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

возможно, вы можете задать себе следующие вопросы:

  • у всех IOrder потребители требуют, чтобы наблюдать порядок? Если это так, IOrder должны реализовать IObservable.

  • у всех IOrder потребители требуют отслеживать состояние заказов? Если это так, IOrder должны реализовать IOrderState.

на самом деле я бы задал такие вопросы, чтобы определить, что делать.

С другой стороны, вы можете подумать о более гибкой архитектуре, где что Order должны реализовать можно определить по generic ограничения:

public void Add<TOrder>(TOrder order) where TOrder : IOrder
{
}

но когда вам нужно, чтобы отслеживать состояние заказа, вы можете сделать это:

public void SaveState<TOrder>(TOrder order) where TOrder : IOrder, IOrderState
{
}