2009-08-30 82 views
3

我有一个变量,我像一个常量(它永远不会改变)。我无法将其声明为常量,因为该值会在运行时添加。像常量一样工作的变量的命名约定

你会利用变量名来帮助你理解数据的含义吗?

或者你会不是因为这违反了约定,使事情更混乱?

较大的问题:
即使场景不是典型的场景,但您是否遵守了约定,但足够接近以至于它本身可以帮助您理解事物?

回答

1

封装它。

#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被称为不止一次例外。

0

是否可以将其标记为只读?那么公约并不重要。

10

如果它能帮助您(和其他人)在六个月的时间内理解您的代码,请执行此操作。如果不行,不要。这真的很简单。

就我个人而言,我会利用它。这是Java中的惯例,由于其面向对象的性质,常量总是在运行时分配。我知道如果我不小心分配给它,我肯定会注意到下一次扫描这段代码。

+3

在Java中,他可以声明它是最终的并且可以完成它。 – 2009-08-30 09:30:09

1

我会将它命名为变量,我更愿意保持我的命名非常一致。 正如Rob已经提出的那样,readonly(至少在C#中可用)。 或者一个没有setter的房产。

9

我不认为我的个人需要在这里至高无上 - 如果我已经编写了代码,那么在未来如果需要的话,我已经比其他任何人更适合回溯;所以我首先要说的是“任何人” - 一个现在或未来的队友,他们需要像我一样彻底地理解代码(理想情况下)。除了强制性的代码评审作为向代码库提交任何东西的先决条件(一种极好的做法,以及我目前雇主的无条件的规则)之外,如果我曾经让我的注意力集中起来,我很可能会被调用它(这确实发生了 - 这就是为什么我喜欢这些强制性代码评论,适用于我自己以及其他人!)。

“在启动时只设置一次变量”是一个足够特殊的情况,可能值得添加到您的团队的指导方针中 - 将其视为“比变量更接近常数”可能会很有意义,但只有在整个代码库中统一使用相同的规则/准则时才有所帮助。如果规则不存在,我会检查是否存在关于添加它的共识;否则,为了我个人的口味,我不会违背准则......这就是“自我编程”和“代码库团队所有权”的根源,这是我用燃烧热情服务的两个原则。顺便说一下,在编码准则方面,我是一个单人团队(虽然这不是一个最佳的情况,但我觉得我可以毫无争议地获得一致的一致意见,即“一旦启动“变量作为常量,就命名惯例而言! - )。但是对于一个更大的团队来说,这是更多的工作,而且可以采用任何方式。

+1

如果我可以投票多次,我会这样做。这正是正确的答案。好的命名是一致的沟通的一部分,这意味着正确的答案不是我们任何人的感受,而是关于团队和组织。 – CPerkins 2009-08-30 16:33:21

+0

@CPerkins,谢谢!我们完全同意。 – 2009-08-30 18:30:44

0

你遵循惯例,即使 情况是不典型的 公约,但足够接近,这 可以帮助你,身体力行, 了解的东西?

遵循一个约定,当情景是非典型的时候可能会混淆或减慢其他人(或者甚至在一段时间后)。我会避免给变量赋予它不是的东西的幌子。

而且,事实上,你有这种非典型的情况可能是,也许一些其他的,比较典型的模式可以遵循的指示。虽然,我没有任何立即建议替代方案。

0

我想使它成为资本(因为它是不是从设计的角度可变更恒定),并添加周围,说明其独特的应用程序的注释。

0

FWIW我自己的习惯是使用所有盖帽为#define S和对枚举。对于const变量我要么使用没有特别的约定,或者当我做它与一个“k”的前缀名称(“konstant” - 不是“c”这已经是在使用的东西像“数”或“字符”) 。

我发现我喜欢'k'约定,并且可能会更频繁地使用它,甚至可能将它用于枚举,为可怕的预处理器宏保留尖叫的全帽标识符。

0

首先,按照您项目的编码标准。你应该为其他人阅读代码编码,而不是你自己。您的个人喜好不应该优先于项目级的规则和惯例等

在没有项目编码标准,你应该遵循你正在处理的语言“最佳做法”。

在Java中,最佳实践是您应该使用camel case标识符声明伪常量。这就是Sun Java编码标准所说的,这也是绝大多数专业Java开发人员所使用的。

在C和C++中,(经典)约定是全部大写字母用于定义为预处理符号的常量。因此,由于这不是预处理符号,因此您应该使用您的编码标准认为适用于某个变量的任何符号。

伪常数不应该改变的事实不会阻止某人修改代码,使其实际发生意外或故意更改。如果使用/滥用是一种编码规范,使标识像一个真正的constaint,你将成为问题的一部分:

  1. 有人试图读/调试你的代码将首先假设标识符是一个真正的不变,不调查的可能性不是。
  2. 然后,当他们看到声明时,会有很多呼喊和威胁的开锁。

实际上,处理伪常量的一种更好的方法是封装它。在Java中,您将声明它为私有成员并提供getter和setter。 setter应该做些什么来防止伪常量在第一次被设置后被改变。任何体面的Java JIT编译器都会内联一个简单的getter,所以这不会影响运行时性能。

0

约定就是这样,约定。他们在那里帮助代码可以理解。如果他们选择得不是太差,并且他们一贯使用,他们通常会这样做。最后一点大概是他们最重要的事情:就应该始终如一地应用。

其中有一点是防止一些公约,使代码更易读,即使他们一贯性原则 - 至少对于新来者和人民的代码库之间进行切换 - 是当他们与其他公约发生冲突。在C和C++中,我知道两个有关在ALL_CAPS中使用名称的常见约定:

  • 为预处理器保留它们;作为预处理器标识符,我认为它是特殊的:它们不遵守通常的作用域规则并且防止与它们发生冲突很重要

  • 将它们用于常量(宏和枚举器)。

两个问题来,除了不熟悉,如果你使用他们的逻辑不变的东西这些都是事实变量:

  • 他们不在的地方(如数组大小)可用,其中语言想到常量表达式

  • 我的经验教我,维修往往会令他们更不恒定的,他们现在的样子。

0

使用单个私有静态字段创建包装类。创建一个initField(..)和一个getField(..)静态方法。如果静态字段不为空,initField将抛出/断言/否则错误。 (原语,你可能需要使用一个原始和一个布尔跟踪初始化。)

在java中,我更喜欢通过这些不同类型的变量为系统属性。然后用静态类可以做这样的事情:而不是使用-D指定它

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

你也可以使用一个属性文件(参见java.util.Properties)。然后你得到:

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 
} 
... 
} 
1

我的直接印象是什么,你“在运行时设置,则永远不会改变”是一个常数,但必须以业务规则是不变的。另外,你应该使用mutators/accessors,因为使用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点之前退出工作!),但仍然没有保证。但是代码审查应该指出类似的东西。

所以我的建议是把foo当作普通的成员变量 - 对于几乎是const的东西,不需要特别的命名约定。

但是,即使在私有变量上也要使用增变器/存取器。这些通常非常快,您可以在其中执行业务规则。这应该是你的惯例。

(如果您正在为嵌入式医疗设备编写代码,请假装您从未看过此贴子)。

0

提供错误信息通常不是最佳实践。

隐含声称的东西是一个常数,当它只是目前没有改变,是发出错误的信息。

0

一个问题是:什么样的变量?

在静态变量的情况下,在我称之为缺少更好的术语的“启动时”之后不会改变,我使用ALL_CAPS ...对于全局变量也是如此(如果语言支持他们的话)......

通信语义实际上是命名约定,并看到一个ALL_CAPS明确规定的点,即A)我不会写它二)我可以缓存它(到一个局部变量例如,或者在AS3中,即使是一个实例变量也是有意义的,因为静态访问非常缓慢)...

它是否是“真正的常量”并不重要......这更多的是实现细节,应该隐藏起来(可靠!信息信息隐藏是好的,也是重要的,但至关重要的是,共享的信息是值得信赖的)......它可以真正交换......例如,我经常开始构建应用程序与一些硬编码配置,包含一些静态常量...后来,我决定我不希望这是硬编码的,而是来自某个配置文件,所以我加载它,并在启动过程中,我启动所有的伪常量...实际的应用程序仍然把它们视为常量,因为在启动后,这就是这些值...这对我来说似乎是完全有效的......

在实例级别,我不是100%确定,如果我曾经跑过变成一个案例,在那里我可以很肯定地说,一些领域永远不会改变...通常,这使得这个班不灵活...

其他的临时工ñ,你可以通常声明只读属性,有编译时错误,这也是一件好事...

0

我不确定这是否是您的选择语言是合法的,但在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

就像其他任何东西 - 范围和上下文都需要知道什么东西是恒定的。所以 - 没有办法满足每个人。

按照您选择的语言使用的样式 - 80%的时间,这将是足够清晰。另一种选择是高度超越命名系统,为了达到理想的技术正确性而牺牲生产力(如果你能达到这个目标,很少有人甚至会真正意识到这一点。)