Соглашение об именовании для переменной, которая работает как константа - PullRequest
3 голосов
/ 30 августа 2009

У меня есть переменная, которую я использую как константа (она никогда не изменится). Я не могу объявить его как константу, потому что значение добавляется во время выполнения.

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

Или вы бы не , потому что это противоречит соглашению и делает вещи более запутанными?

Большой вопрос:
Соблюдаете ли вы соглашения, даже если сценарий не типичен для соглашения, но достаточно близок, чтобы он мог лично помочь вам понять вещи?

Ответы [ 16 ]

10 голосов
/ 30 августа 2009

Если это поможет вам (и всем остальным) понять ваш код через шесть месяцев, сделайте это. Если это не так, не надо. Это действительно так просто.

Лично я бы это использовал. Это соглашение в Java, где константы всегда выделяются во время выполнения из-за своей объектно-ориентированной природы. Мне было бы гораздо удобнее, если бы я случайно назначил его, я определенно заметил бы, когда в следующий раз просмотрю этот кусок кода.

9 голосов
/ 30 августа 2009

Я не считаю, что мои личные данные должны быть здесь первостепенными - если я написал код, я уже лучше подготовлен для его повторного отслеживания в будущем, если и когда это потребуется, чем кто-либо другой; таким образом, это «кто-то еще», которого я поставил в первую очередь - настоящего или будущего партнера по команде, который должен будет понимать код (в идеале) так же тщательно, как и я.

Кроме того, с обязательными проверками кода в качестве предварительного условия для передачи НИЧЕГО в кодовую базу (отличная практика и неизменное правило моего нынешнего работодателя) меня, скорее всего, призовут к этому, если я когда-нибудь упущу свое внимание (это случается - именно поэтому я ЛЮБЛЮ эти обязательные обзоры кода, применительно ко мне и ко всем остальным! -).

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

Кстати, если бы я был в команде из одного человека с точки зрения руководящих принципов кодирования (это случается, хотя это не оптимальная ситуация;), я думаю, у меня не было бы проблем с достижением единодушного единого мнения о том, что я лечу "один раз при запуске "переменные как константы с точки зрения соглашений об именах! -). Но с большой командой это больше работы, и она может пойти в любую сторону.

1 голос
/ 30 августа 2009

Мое непосредственное впечатление таково, что то, что вы «устанавливаете во время выполнения, затем никогда не меняете», является константой, только если бизнес-правила постоянны. Кроме того, вы должны использовать мутаторы / аксессоры, так как использование ALL CAPS вряд ли может гарантировать «константность».

public class BadClass
{ 
    public static final double PI = 3.1;     
      // PI is very constant.  Not according to the business roles modeled by my 
      // application, but by nature.  I don't have a problem making this publicly
      // accessible--except that [Math] already does, with much better precision)

    public static /*final*/ int FOO = null;
      // FOO is constant only by convention.  I cannot even enforce its "constness".
      // Making it public means that my enemies (overtime, for example) can change 
      // the value (late night programming), without telling me.
}

Вместо

public class BetterClass
{
    public static final double PI = 3.1;
    private /*final*/ Integer foo = null; 

    public int getFoo() {
        return this.foo.intValue();
    }
    public void setFoo(int value) {
        // The business rules say that foo can be set only once.
        // If the business rules change, we can remove this condition 
        // without breaking old code.
        if ( null == this.foo ) {
           this.foo = value;
        } else {
           throw new IllegalStateException("Foo can be set only once.");
        }
    }
}

Если вы всегда используете мутатор для установки значения, даже внутри самого [BetterClass], вы знаете, что «константность» foo не будет нарушена. Конечно, если кто-то собирается установить значение foo напрямую (мне нужно прекратить работу до 2:00!), Гарантии все равно нет. Но что-то подобное должно быть указано при проверке кода.

Так что я рекомендую трактовать foo как обычную переменную-член - нет необходимости в специальном соглашении по именованию для чего-то, что почти константно.

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

(Если вы пишете код для встроенных медицинских устройств, сделайте вид, что вы никогда не видели эту публикацию).

1 голос
/ 30 августа 2009

Инкапсулируйте это.

#include <iostream>

class ParamFoo
{
    public:
        static void initializeAtStartup(double x);
        static double getFoo();
    private:
        static double foo_;
};

double ParamFoo::foo_;

void ParamFoo::initializeAtStartup(double x)
{
    foo_ = x;
}

double ParamFoo::getFoo()
{
    return foo_;
}

int main(void)
{
    ParamFoo::initializeAtStartup(0.4);
    std::cout << ParamFoo::getFoo() << std::endl;
}

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

1 голос
/ 30 августа 2009

Я бы назвал это как переменную, я предпочитаю, чтобы мои имена были очень согласованными. Как уже предположил Роб, насчёт только для чтения (доступно по крайней мере в C #). Или свойство без установщика.

0 голосов
/ 31 августа 2009

Так же, как и все остальное - объем и контекст должны знать, как что-то является постоянным. Так что - нет способа удовлетворить всех.

Следуйте стилю, используемому на выбранном вами языке - в 80% случаев это будет достаточно ясно. Альтернативой является система имен с чрезмерным переизбытком, которая жертвует производительностью ради идеальной технической корректности (которую мало кто даже по-настоящему оценит, если удастся ее достичь).

0 голосов
/ 31 августа 2009

Я не уверен, допустимо ли это на вашем языке, но в C ++ это подойдет для вашей цели:

#include <iostream>

int main()
{
    int i = 0;
    std::cin >> i;

    const int CONST = i; 
    std::cout << CONST; //displays i

    system("PAUSE"); 
    return 0;
}

Я не уверен, что это морально, но это решит вашу проблему (если вам действительно не нужна ваша память).

0 голосов
/ 31 августа 2009

один вопрос будет: что за переменная?

в случае статических переменных, которые не меняются после того, что я бы назвал «время загрузки» из-за отсутствия лучшего термина, я использую ALL_CAPS ... то же самое для глобальных переменных (если язык поддерживает их вообще) ...

Обмен семантикой - это точка соглашения об именах, и, видя, что ALL_CAPS ясно заявляет, что: а) я не буду писать в него; б) я могу кешировать его (например, в локальную переменную или в AS3 даже переменную экземпляра). имеет смысл, так как статический доступ очень медленный) ...

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

на уровне экземпляра, я не уверен на 100%, если бы я столкнулся с делом, где я мог быть уверен, что какое-то поле никогда не изменится ... обычно, это делает класс негибким ...

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

0 голосов
/ 31 августа 2009

Предоставление неверной информации, как правило, не лучшая практика.

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

0 голосов
/ 30 августа 2009

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

В Java я предпочитаю передавать эти типы переменных в качестве системных свойств. Статический класс может затем сделать что-то вроде:

public final int MY_INT = Integer.getInteger("a.property.name");

Вы также можете использовать файл свойств (см. Java.util.Properties) вместо использования -D для его указания. Тогда вы получите:

public class Foo {

public static final int MY_INT;

static {
Properties p = new Properties();
try{
p.load( new FileInputStream("app.props"):
} catch(IOException e) {
//SWALLOW or RETHROW AS ERROR
}
MY_INT=Integer.parseInt( p.getProperty("my.int","17") ); //17 is default if you swallo IOException
}
...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...