Re[2]: Контракт интерфейса
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 04.05.12 20:07
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Это особенности языка. например из такого интерфейса

А>
А>public interface Locker {
А>  void Lock();
А>  void Unlock();
А>}
А>

А>совершенно не очевидно можно ли lock-ать вложено или нет.
А>в таких случаях можно использовать комментарии
А>Если мало комментарием то кидай исключения и используй тесты.

В принципе, в тех же дот-нетах, контракты можно определить и более формально:

[ContractClass(typeof(LockerContracts))] // указываем контракт
public interface Locker {
// Без дополнительного публичного свойства никак,
// вызывающий код должен понимать, какие контракты налагаются каждым
// методом и должен иметь возможность проверить выполнимость предусловия
bool Locked {get;}
void Lock();
void Unlock();
}

// В .net-е контракты указываются не с помощью атрибутов (они слишком слабовыразительны для этого)
// а с помощью отдельных классов, реализующих требуемый интерфейс
internal abstract class LockerContracts : Locker
{
  public bool Locked {get {throw new NotImplementedException;}}
  public void Lock() {
    // Все, теперь клиенты будут знать, что дважды локать нельзя
    // в противном случае - это баг со всеми вытекающими (ассертом или
    // исключением в рантайме)
    Contract.Requires(!Locked, "We can't acquire lock twice");
  }

  public void Unlock() {
     // Здесь картина аналогична, попытка заанлокать незалоченное приведет к беде
     Contract.Requires(Locked, "We can't release free lock!");
  }
}


Теперь можно на это дело натравить статический анализатор, который еще и во время компиляции (точнее посткомпиляции) сможет отловить проблемы.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.