C конфигурация API

В моем .bash_profile у меня есть:

# No Proxy
function noproxy
{
    /usr/local/sbin/noproxy  #turn off proxy server
    unset http_proxy HTTP_PROXY https_proxy HTTPs_PROXY
}


# Proxy
function setproxy
{
    sh /usr/local/sbin/proxyon  #turn on proxy server 
    http_proxy=http://127.0.0.1:8118/
    HTTP_PROXY=$http_proxy
    https_proxy=$http_proxy
    HTTPS_PROXY=$https_proxy
    export http_proxy https_proxy HTTP_PROXY HTTPS_PROXY
}

Поэтому, когда я хочу отключить прокси-сервер, функции запускаются в оболочке входа в систему и устанавливают переменные в соответствии с ожиданиями и желаниями.

6
задан Will 3 July 2009 в 05:27
поделиться

6 ответов

Структура лучше длинного списка. Длинный список трудно поддерживать, поскольку никто не помнит точный порядок.

Вы можете создать конструктор, который заполняет эту структуру безопасными (по умолчанию и / или недопустимыми) записями. Всегда (вероятно, в функции доступа) проверка на недопустимые значения упростит обнаружение ошибок при инициализации.

Вы можете скрыть магическое число в этой структуре. Первое поле - это CONFIG_MAGIC, которое должно быть равно определенной вами константе. Вы устанавливаете это поле в конструкторе и ожидаете, что оно будет установлено всегда. Таким образом вы избегаете того, чтобы кто-то просто malloc () использовал структуру и инициализировал ее вручную. Такому программисту необходимо будет узнать об этой константе CONFIG_MAGIC, и он, скорее всего, найдет и использует правильный конструктор.

11
ответ дан 8 December 2019 в 13:48
поделиться

Каким образом обновлять вызов функции во всех местах - это хорошо ? Конечно, вам следует перестроить все с новыми обновленными заголовками, но в идеале вам нужно будет вносить как можно меньше изменений в код при каждом изменении конфигурации.

0
ответ дан 8 December 2019 в 13:48
поделиться

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


    set_diagnostic_email_config("bla@foo.com", 0, 1, 0, 1, 0, 1, 0, 0, 0);

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

Если у вас есть только логические значения, я бы использовал флаги, которые вы можете комбинировать с оператором ИЛИ. Вот возможный пример:


   typedef enum {
       FLAG_DEFAULT = 0,
       FLAG_INCLUDE_TIMESTAMP = 0x1,
       FLAG_SEND_FOR_CRASHES = 0x2,
       FLAG_SEND_DAILY_STATUS = 0x4,
       FLAG_SEND_ON_EVENT1 = 0x8
    } Email_Flags;

    int set_diagnostic_email_config(const char *address, unsigned int flags);

Теперь вы можете вызывать функцию следующим образом:

  set_diagnostic_email_config (" bla@foo.com ", FLAG_SEND_DAILY_STATUS | FLAG_SEND_ON_EVENT1);

Этот код легко читать, вам не нужно знать все варианты, чтобы понять его. И этот код легко написать, потому что порядок «параметров» (на самом деле порядок флагов) не важен. И эту функцию легко расширить, вы можете просто добавить больше флагов, скажем FLAG_SEND_ON_EVENT2 , и вам не нужно изменять вызов функции, если вы хотите изменить ее поведение.

3
ответ дан 8 December 2019 в 13:48
поделиться

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

struct INFO
{
    char *to_address;
    bool include_timestamp;
    bool send_for_crashes;
    bool send_daily_status;
    bool send_on_event1;
    bool send_on_event2;
};

struct INFO *createINFO()
{
    // initialize to defaults.

    // return a pointer to the new created struct.
}

void include_timestamp(struct INFO *info, bool vInclude_timestamp)
{
    // set the field.
}

// add the required setters...

void destroyINFO(struct INFO *info)
{
    // destroy the struct.
}

Таким образом, вы можете добавлять сеттеры по запросу, когда вы добавляете новое поле. Не позволяя пользователю вмешиваться в саму структуру.

3
ответ дан 8 December 2019 в 13:48
поделиться

Подход «многочисленные параметры» имеет большой недостаток, заключающийся в том, что вам нужно изменять много кода каждый раз, когда вводится новый параметр, просто ради передачи этого параметра вниз по стеку вызовов. Со структурой вам нужно только изменить места, которые фактически используют параметры. Необходимость часто изменять тонны кода сама по себе может вызвать установку ошибок, что перевесит преимущества проверки всех присутствующих параметров во время компиляции.

0
ответ дан 8 December 2019 в 13:48
поделиться

Я бы использовал

int set_diagnostic_email_config( char *to_address,
                                 bool include_timestamp,
                                 int event_type ) {
    switch (event_type) {
        case 1:
        ...
    }
}

или

int set_diagnostic_email_config( char *to_address,
                                 bool include_timestamp,
                                 int event_type, void *details )

. Наличие event_type в качестве целого числа означает, что вы можете добавить новое событие без изменения подписи. Дополнительный void * дает дополнительную структуру для каждого типа события.

Если вы используете struct , изменения в ней не всегда могут быть двоично совместимы.

0
ответ дан 8 December 2019 в 13:48
поделиться
Другие вопросы по тегам:

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