也说魔数与魔字符串

博客受.net中魔字符串相关内容启发,分析了代码中使用魔数和魔字符串的弊病。魔字符串增加出错概率、忽略语义环境,魔数影响代码可读性且修改不便。指出在项目里应避免使用,通过常量访问特定内容是开发标准,但数字语义未延伸时可不定义为常量,强调策略使用要把握度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

         看了叙远兄写的.net中的魔字符串,还有birdsome的评论,颇有启发。
         所谓魔数和魔字符串就是在代码中直接使用某一个数字或者字符串,而不是常量。譬如一个很简单的根据职位计算薪水的方法:

ExpandedBlockStart.gifContractedBlock.gifpublic int getSalary(String title, int grade) dot.gif{
InBlock.gif    
if ("Programmer".equals(title)) 
InBlock.gif        
return grade * 500 + 700;
InBlock.gif    
else if ("Tester".equals(title))
InBlock.gif        
return grade * 500 + 800;
InBlock.gif    
else if ("Analyst".equals(title))
InBlock.gif        
return grade * 800 + 1000;
ExpandedBlockEnd.gif}

        在这个方法里面,"Programmer","Tester"和"Analyst"是所谓的魔字符串(Magic String),而500, 700,800和1000就是所谓的魔数(Magic Number)了。 咋一看,代码这样写也没有什么问题,但是,仔细思考一下就会发现,如果这种随手捻来的字符串和数字散布于程序当中,随处可见的话,是会有很多弊病的。我们先来分析三个魔字符串。虽然三个Magic String的意义很明显,并不影响到代码的可读性,但是这样却增加了出错的概率,并且忽略了具体的语义环境。我们很容易就会想到,像"Programmer"这个单词散布在多个方法中,一个大小写的笔误就会产生bug。同时,"Programmer"在计算薪水的方法中代表着职位,但是在统计公司订阅的杂志的方法中,也许就要代表一本杂志的名称了。然而这种语义环境是无法通过一个单纯的"Programmer"就能体现出来的。
        而Magic Number的问题就更大了,首先是影响了代码的可读性,谁会知道500和800是薪水基数,700是补贴呢?而且更糟糕的是,如果薪水基数发生改变的时候,那么就得找人把这些500,700,800的数字找出来一个一个地update,那可是一件够郁闷的事情了。
        如果我们拥有一个常量定义的interface,代码就会变漂亮起来了:

ExpandedBlockStart.gifContractedBlock.gifpublic int getSalary(String title, int grade) dot.gif{
InBlock.gif    
if (Constants.TITLE_PROGRAMMER.equals(title)) 
InBlock.gif        
return grade * Constants.BASE_SALARY_LOW + Constants.ALLOWANCE_LOW;
InBlock.gif    
else if (Constants.TITLE_TESTER.equals(title))
InBlock.gif        
return grade * Constants.BASE_SALARY_LOW + Constants.ALLOWANCE_MEDIUM;
InBlock.gif    
else if (Constants.TITLE_ANALYST.equals(title))
InBlock.gif        
return grade * Constants.BASE_SALARY_HIGH + Constants.ALLOWANCE_HIGH;
ExpandedBlockEnd.gif}

        从以上的分析,在一个Project里面,避免使用魔数(Magic Number)和魔字符串(Magic String)是相当必要的。通过定义的常量去access特定的字符串和数字也已经是软件开发的standard。那么是不是所有的数字和字符串都应该定义成常量呢?或许有朋友会认为所有的数字和字符串都应该定义成常量,但是我觉得,每个字符串确实是应该定义成常量的,但是对于数字而言,如果数字本身的语义没有得到延伸,那么就不应该定义成常量。譬如数组的index就不应该定义成变量。 像这样的代码:

None.gifString building = address[Constants.ONE]; 
            // 在Constants这个interface中,ONE的定义为 final int ONE = 1;None.gif
None.gif

        你一定会觉得这样的代码就是画蛇添足, 因为ONE就是1,它没有其他特别的含义,不像上面代码中的500和700。而且如果真的要这样定义的话,出现了有上百个元素的数组的时候,那么你就得定义上百个没有任何意义的常量了。是不是很FT呢?
        总之,任何策略的使用,还是一个度最重要。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值