dotSITE
Шаблоны проектирования Work in Murano Software. Вопросы/Ответы
новости материалы решения форумы группы настройки/о проекте
Логин/Регистрация
Логин:
Пароль:
Запомнить вас:
Регистрация
Забыли пароль?

Комментарии

"Design By Contract". Краткий обзор.

"Design By Contract". Краткий обзор.

В кратце попробую своими словами изложить суть "Design By Contract", а также приведу примеры как можно использовать DBC с языками где нет прямой поддержки и пару слов о смежных технологиях :)

Предположим, что у нас есть сервер(тот кто предоставляет некоторый сервис) и есть клиент(тот кому необходимо воспользоваться этим сервисом). Суть идеологии в том, что клиент и сервер заключают между собой контракт : клиент должен выполнить условия которые требует сервер для того чтобы он(сервер) мог предоставить требуемый сервис, сервер должен гарантировать что он выполнил именно ту операцию которую заказывал клиент, а также сервер должен гарантировать что все время работы находиться во "вменяемом" состоянии. Таким образом, DBC позволяет задать preconditions - условия которые должен выполнить клиент, postconditions - условия которые должен выполнить сервер и invariant - условия нормальной работы сервера.

Приведу пример кода, который демонстрирует использование DBC в Eiffel. Метод put, помещает в некоторый контейнер элемент x по ключу key.

put (x: ELEMENT; key: STRING) is
                     -- Insert x so that it will be retrievable through key.
             require
                     not key.empty

             deferred

             ensure
                     has (x)
                     item (key) = x
                     count = old count + 1
             end

---
invariant
                     count <= capacity
---

Здесь мы видим, что от клиента требуется чтобы он предоставил не пустой ключ(содержимое require), от сервера требуется чтобы после выполнения операции он действительно содержал элемент x, чтобы этот элемент x можно было найти по ключу key и что размер контейнера увеличился на один элемент(содержимое ensure) и то что в течении всего времени работы сервера count не превышал capacity(invariant). Содержимое выражения require проверяется перед выполнением тела метода put, содержимое выражения ensure выполняется после выполнения тела метода put, invariant проверяется до и после выполнения тела метода put. deffered означает что метод абстрактный(если использовать термин из С++). Таким образом мы можем на стадии создания интерфейсов задавать семантику метода. Причем со стороны языка поддерживается наследование pre\post-conditions и invariants, задание pre\post-conditions и invariants для абстрактных интерфейсов.

При программировании на С++ можно использовать DBC с помощью define и функции assert ( ); К сожалению нужно многое делать руками, и все равно всех преимуществ получить не удается. Для задания pre\post-conditions можно пользоваться функцией assert, для задания invariant нужно написать такой define:

#ifndef NDEBUG
    #define invariant() (this->Invariant ())
#else
    #define invariant()
#endif

в теле класса написать иплементацию :

class class_for_example
    {
     public:

     put   (x: ELEMENT; key: STRING) 
        {
        // Insert x so that it will be retrievable through key.
             assert (  ! key.empty )
             invariant (  );
            int old_count = count;

             /* any code */

             invariant (  );
             assert (  has (x) )
             assert (  item (key) == x )
             assert (  count = old_count + 1 )
        }

    protected :

    void Invariant ( void ) const
        {
        assert ( count <= capacity );
        }
    }

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

Еще хочу отметить отличие DBC и метода который предлагает eXtreme Programming(это, правда, лично мое впечатление, тем более что я не очень углублялся в то что предлагает XP). Остановиться на этом вопросе я решил, для того, чтобы не создавалось впечатление, что эти две методологии примерно одно и то же. В XP предлагается сначала писать тесты для интерфейсов и уже потом писать сами интерфейсы. В случае если эти тесты затем выполняются в течении всего процесса разработки - в некотором смысле - их можно рассматривать как аналог контракта из DBC. Мне не очень было понятно как можно писать тесты для интерфейсов которых еще нет :. Потом, если контракт находится там же где и интерфейс - для того чтобы понять что делает этот интерфейс нужно взглянуть только на интерфейс, в случае с XP нужно смотреть еще и тесты. То есть информация получается разбросана. И в этом смысле, например, неясно как должны поставляться библиотеки - со своим набором тестов ?. Также, с точки зрения трудоемкости, на мой взгляд, тяжело поддерживать в синхронном состоянии вещи которые находятся в разных местах. Еще, тесты как правило содержат гораздо больше проверок, чем это необходимо в DBC, на различные специальные случаи, на ошибки которые уже были ну и т.д. то есть рассматривать их как контракт было бы неверно с этой точки зрения. Таким образом, DBC и тесты - это разные вещи - причем и одно и другое необходимо, но на разных этапах, DBC при проектировании интерфейсов, тесты при тестировании(DBC, к слову, может помочь при составлении тестов).

Ссылки, где можно узнать больше:

  1. Во-первых рекоммендую посмотреть ссылки уже приведенные в форуме : Их предоставил W :
    http://www.eiffel.com/doc/manuals/technology/contract/page.html
    http://www.elj.com/eiffel/dbc/
    http://www.inferdata.com/~richard/extras/dbcextracts/
  2. . "Object-Oriented Software Construction, Second Edition" Bertrand Meyer.
    http://www.eiffel.com/doc/oosc/
  3. http://www.irisa.fr/prive/jezequel/DesignPatterns/#Preface
  4. http://www.objectmentor.com/publications/lsp.pdf
  5. http://www.reliable-systems.com/tools/iContract/iContract.htm
  6. http://www.aw.com/cseng/titles/0-201-89542-0/techniques/designByContract.htm
  7. http://www.eiffel.com/doc/manuals/technology/contract/ariane/page.html


Alexey Lapshin(dotSITE virtual team)


Контакт Реклама на сайте Спонсорам Веб мастерам

Лицензионное соглашение - © 2000-2012 dotSITE
Хостинг .NET предоставлен PARKING.RU
Поддержку сайта осуществляет Murano Software Inc., Offshore software development