Нужно предложение с CodeContracts - PullRequest
1 голос
/ 03 декабря 2010

Привет, ребята Я новичок в СиСи, и мне нужно ваше предложение. Я начал с CC в моем последнем проекте. У меня есть контракт WCF, который должен быть реализован третьими лицами. Я хочу назначить кодовые контракты сервисным контрактам. Допустим, у меня есть класс Car (Service Contract) и это OperationContract ICar. В ICar есть метод GetCar (), который, как я сказал выше, должен быть реализован нашими клиентами. Я создаю кодовый класс Contract для Icar и в методе GetCar проверяю контракт с помощью класса CarContractHelper. Я ввел вспомогательный класс, который проверяет класс Car следующим образом: Contract.Ensure(CarContractHelper.Validate(Contract.Result<Car>())). Это правильный подход к решению проблемы? Или есть способ получше? Я также проверяю каждый элемент свойства класса Car в его установщиках, что вы думаете по этому поводу, нужно ли это или это излишнее? Спасибо И конечно же я отмечу правильный ответ и проголосую :))

UPDATE


@ StriplingWarrior Я представил помощника по проверке автомобиля, чтобы иметь дело с повторяющимся кодом подтверждения договора. например:

Contract.Requires(!string.IsNullOrWhiteSpace(car.Id);
Contract.Requires(car.Mileage > 0);

и т.д.. Вместо того чтобы писать везде код Contract.Requires, у меня есть только один вспомогательный класс для каждого бизнес-объекта, который проверяет контракт бизнес-объекта. И это то, что я хочу знать, если это правильный подход или, может быть, есть лучший способ? спасибо.

P.S. Я проверяю каждое свойство в их собственных установщиках, потому что у меня не работает инвариантный метод (?), Насколько я знаю, инварианты работают, когда вызывается любой метод класса, а в моем случае wcf contract не есть какие-то методы. Поэтому я решил проверить внутри свойства свойства. Это хороший подход?

Ответы [ 2 ]

1 голос
/ 04 декабря 2010

Я не так много сделал с Контрактами на код, но вот некоторые наблюдения:

Одним из преимуществ контрактов на код является возможность взглянуть на контракт для конкретного метода и узнать, что ожидается.Наблюдение CarContractHelper.Validate(Contract.Result<Car>()) на самом деле ничего не говорит мне, поэтому мне пришлось бы детализировать, чтобы узнать, что (например) возвращаемое значение CarId больше нуля.Так что в одном случае я бы предпочел Contract.Ensure(Contract.Result<Car>().CarId > 0) и, возможно, несколько других требований.С другой стороны, я вижу, как это может создать много повторяющегося кода контракта, с которым будет трудно работать, если (например) вы добавите новое свойство в класс Car.

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

var car = _carService.GetCar();
_crashTestUtil.TestCar(car);

Если в контракте TestCar требуется, чтобы car.CarId > 0 и GetCar() не удалось обеспечить это, компилятор может предупредить вас об этом факте.Для того чтобы это работало с вспомогательным классом проверки, я полагаю, что вам нужно убедиться, что ваш вспомогательный класс проверки также использует методы контракта кода для выполнения проверок контракта.

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

0 голосов
/ 07 декабря 2010

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

На мой взгляд, было бы лучше, если бы ваш API обрабатывал недействительный автомобиль или выдал соответствующее исключение. Если вы используете Code Contracts для проверки действительности автомобиля, у вас есть только 2 варианта: 1. Автомобиль действителен 2. Автомобиль недействителен, ContractException (или ваше собственное исключение).

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

...