Как определить предварительные условия для внешнего состояния, используя кодовые контракты? - PullRequest
3 голосов
/ 06 марта 2012

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

interface IDeleteObjectCommand {
   Guid ObjectId { get; }
   void Invoke();
}

Попытка # 1

У меня уже есть команда с именем IObjectExistsCommand, с помощью которой можно определить, существуют ли объекты.Эти команды могут быть созданы с помощью IObjectExistsCommandFactory.Я думал о том, чтобы сделать следующее, но это добавляет нежелательный шум в интерфейс команды (IMO):

interface IDeleteObjectCommand {
   IObjectExistsCommandFactory ObjectExistsCommandFactory { get; }
   Guid ObjectId { get; }

   // Contract.Requires(ObjectExistsCommandFactory.Create(ObjectId).Invoke());
   void Invoke();
}

Попытка # 2

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

interface IDeleteObjectCommand {
   Guid ObjectId { get; }

   // Contract.Requires(ServiceLocator.Get<ObjectExistsCommandFactory>().Create(ObjectId).Invoke());
   void Invoke();
}

РЕДАКТИРОВАТЬ: Аналогично, как бы вы определили постусловия для внешнего состояния?Т.е. говоря, что этот метод приводит к существованию нового файла.

Ответы [ 2 ]

1 голос
/ 09 марта 2012

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

Создает исключение, если удаляемый объект не существует.

0 голосов
/ 09 марта 2012

Я решил создать «Предварительные условия» enum, которые определяют внешние предварительные условия.Затем я определил отдельный метод на интерфейсе, который возвращает enum, что указывает на то, какие биты внешнего состояния недопустимы:

interface IDeleteObjectCommand {
   Guid ObjectId { get; }
   DeleteObjectPreconditions? GetImpediments();

   // Contract.Requires(!this.GetImpediments().HasValue);
   void Invoke();
}

enum DeleteObjectPreconditions { ObjectExists, ObjectUnlocked };

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

РЕДАКТИРОВАТЬ: Я на самом деле предпочитаю метод определения местоположения службы, чем этот.По крайней мере, с таким подходом пользователи могут доказать, что предварительные условия выполняются через контрактный (хотя и расположенный на службе) интерфейс.

РЕДАКТИРОВАТЬ 2: Это поднимает интересный вопрос.. как бы вы определили постусловия на внешнее состояние?

...