Библиотека для упрощения использования “дизайна контракта” [закрытый] принцип

В Java вот является возможный хвост рекурсивной реализацией функции Fibonacci:

public int tailRecursive(final int n) {
    if (n <= 2)
        return 1;
    return tailRecursiveAux(n, 1, 1);
}

private int tailRecursiveAux(int n, int iter, int acc) {
    if (iter == n)
        return acc;
    return tailRecursiveAux(n, ++iter, acc + iter);
}

Контраст это со стандартной рекурсивной реализацией:

public int recursive(final int n) {
    if (n <= 2)
        return 1;
    return recursive(n - 1) + recursive(n - 2);
}
19
задан nbro 5 August 2017 в 00:16
поделиться

3 ответа

Я следовал принципам следующих статей:

  • Исключение или ошибка? (Миро Samek, C / C ++ Users Journal, 2003)
  • Простая поддержка проектирования по контракту в C ++ (Педро Геррейро, TOOLS, 2001)

В конечном итоге я применил подход Самека. Было очень полезно просто создать макросы для REQUIRE, ENSURE, CHECK и INVARIANT (на основе существующего макроса assert ). Конечно, это не так хорошо, как поддержка родного языка, но в любом случае она позволяет вам получить большую часть практической ценности от этой техники.

Что касается библиотек, я не думаю, что их использование окупается, потому что одно важное значение Механизма утверждений является его простота.

О различиях между отладочным и производственным кодом см. Когда утверждения должны оставаться в рабочем коде? .

9
ответ дан 30 November 2019 в 04:16
поделиться

Самый простой?

Утверждайте операторы в начале вашей функции для проверки ваших требований. Утверждайте утверждения в конце вашей функции для проверки ваших результатов.

Да, это грубая, это небольшая система, но ее простота делает ее универсальной и портативной.

6
ответ дан 30 November 2019 в 04:16
поделиться

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

#include <cassert>

class Car {
    virtual bool engine_running_impl() = 0;
    virtual void stop_impl() = 0;
    virtual void start_impl() = 0;

    public:
    bool engine_running() {
        return engine_running_impl();
    }

    void stop() {
        assert(engine_running());
        stop_impl();
        assert(! engine_running());
    }

    void start()
    {
        assert(! engine_running());
        start_impl();
        assert(engine_running());
    }
}


class CarImpl : public Car {
    bool engine_running_impl() {
        /* ... */
    }

    void stop_impl() {
        /* ... */
    }

    void start_impl() {
        /* ... */
    }
}
6
ответ дан 30 November 2019 в 04:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: