Подтвердить что ты не робот

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

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

Например, у меня есть объект MemberStatus, который наследуется от абстрактного объекта Entity, который, в свою очередь, реализует интерфейс IIdentifiableEntity, что означает, что он имеет свойство Id. MemberStatus также реализует интерфейс INamedEntity, означающий, что у него есть свойство Name, интерфейс IOrderedEntity, означающий, что у него есть свойство DisplayOrder и интерфейс IHasMembers, что означает что у него есть объекты коллекции Collection. Здесь код:

public class MemberStatus : Entity, INamedEntity, IOrderedEntity, IHasMembers
{
  public string Name { get; set; }
  public float DisplayOrder { get; set; }
  public ICollection<Member> Members { get; set; }
}

public abstract class Entity : IIdentifiableEntity
{
  public int Id { get; set; }
}

public interface IIdentifiableEntity
{
  int Id { get; set; }
}

public interface INamedEntity
{
  string Name { get; set; } 
}

public interface IOrderedEntity
{
  float DisplayOrder { get; set; }
}

public interface IHasMembers
{
  ICollection<Member> Members { get; set; }
}

Теперь это работает отлично, как и другие подобные объекты, такие как MemberPosition и MemberTeam, которые все реализуют эти же интерфейсы, и я могу использовать свои методы репозитория и действия контроллера с генериками, которые реализуют эти интерфейсы и имеют много повторного использования кода.

Однако, моя забота заключается в том, следует ли постоянно добавлять простые интерфейсы с одним свойством каждый раз, когда я добавляю новое свойство к своим конкретным объектам. Например, скажем, я хочу добавить свойство bool Enabled... должен ли я продолжить создание IEnabled интерфейса? Причина, по которой я спрашиваю, заключается в том, что некоторые из инициализаторов контроллера, которые используют дженерики, становятся очень длинными, как показано в следующей строке кода. Является ли это нормальной и лучшей практикой?

public abstract class OrderedCrudController<TEntity> : CrudController<TEntity> where TEntity : Entity, INamedEntity, IOrderedEntity, IHasMembers, new()
4b9b3361

Ответ 1

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

Также вы можете рассмотреть контексты, в которых вы будете взаимодействовать с несколькими реализациями этого интерфейса IEnabled?

Если ответ на оба этих вопроса "нет", интерфейс очень мало предназначен.

Сказав это, пожалуйста, не беспокойтесь об этом! это очень мало вреда.

Ответ 2

Не создавайте интерфейсы, которые вы не предвидите неизбежной необходимости. Обратите внимание на YAGNI (вам это не понадобится). В противном случае вы получите ненужный сложный код.

Ответ 3

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

Вместо этого рассмотрите объекты объекта домена, которые имеют поведение, близкое к данным и в его c'tor, дайте ему Action<DomainEvent>. Теперь убедитесь, что вы только ТОЛЬКО передаете данные OUT из объекта домена через это действие.

Теперь ты слушаешь. Всякий раз, когда вы действительно хотите внести изменения в свой домен, вызовите на нем метод. Обновите свой графический интерфейс с помощью Action<DomainEvent>, выполнив эти события и сохраните их в любой интересующей вас модели.

Посмотрите http://www.infoq.com/presentations/ddd-eric-evans и рассмотрите его пункты о событиях домена.

Теперь вам больше не нужно добавлять странные интерфейсы, связанные с техническим доменом в ваш бизнес-домен. И запомни; если вы делаете CRUD, как показано на примерах, то вы НЕ выполняете дизайн, управляемый доменом. У вас анемичный домен.

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

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