Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a magic number, and why is it bad? [closed]

What is a magic number?

Why should it be avoided?

Are there cases where it's appropriate?

like image 630
Adam Davis Avatar asked Sep 06 '08 22:09

Adam Davis


People also ask

What is a magic number and why is it bad?

A magic number is a number in the code that seems arbitrary and has no context or meaning. This is considered an anti-pattern because it makes code difficult to understand and maintain. One of the most important aspects of code quality is how it conveys intention. Magic numbers hide intention so they should be avoided.

Are magic numbers bad?

Magic numbers are an anti-pattern and should generally be avoided. What do I mean when I say magic number? I'm referring to using numbers directly in code as opposed to using a named constant. This can also apply to other data types and literals, especially strings.

What is the magic number mean?

A team's magic number represents the combination of wins needed by that team and losses by its closest competitor to clinch a given goal. Every time a team wins, its magic number decreases by one.

What is the magic number rule?

Strict Magic Number rule: Literals (including strings and characters) should only appear on the right hand side of a constant declaration statement. Practical Magic Number rule: A literal is a not a magic number if the most meaningful variable name for it is the same as the spoken name of the literal.


2 Answers

A magic number is a direct usage of a number in the code.

For example, if you have (in Java):

public class Foo {     public void setPassword(String password) {          // don't do this          if (password.length() > 7) {               throw new InvalidArgumentException("password");          }     } } 

This should be refactored to:

public class Foo {     public static final int MAX_PASSWORD_SIZE = 7;      public void setPassword(String password) {          if (password.length() > MAX_PASSWORD_SIZE) {               throw new InvalidArgumentException("password");          }     } } 

It improves readability of the code and it's easier to maintain. Imagine the case where I set the size of the password field in the GUI. If I use a magic number, whenever the max size changes, I have to change in two code locations. If I forget one, this will lead to inconsistencies.

The JDK is full of examples like in Integer, Character and Math classes.

PS: Static analysis tools like FindBugs and PMD detects the use of magic numbers in your code and suggests the refactoring.

like image 109
Marcio Aguiar Avatar answered Oct 02 '22 02:10

Marcio Aguiar


A Magic Number is a hard-coded value that may change at a later stage, but that can be therefore hard to update.

For example, let's say you have a Page that displays the last 50 Orders in a "Your Orders" Overview Page. 50 is the Magic Number here, because it's not set through standard or convention, it's a number that you made up for reasons outlined in the spec.

Now, what you do is you have the 50 in different places - your SQL script (SELECT TOP 50 * FROM orders), your Website (Your Last 50 Orders), your order login (for (i = 0; i < 50; i++)) and possibly many other places.

Now, what happens when someone decides to change 50 to 25? or 75? or 153? You now have to replace the 50 in all the places, and you are very likely to miss it. Find/Replace may not work, because 50 may be used for other things, and blindly replacing 50 with 25 can have some other bad side effects (i.e. your Session.Timeout = 50 call, which is also set to 25 and users start reporting too frequent timeouts).

Also, the code can be hard to understand, i.e. "if a < 50 then bla" - if you encounter that in the middle of a complicated function, other developers who are not familiar with the code may ask themselves "WTF is 50???"

That's why it's best to have such ambiguous and arbitrary numbers in exactly 1 place - "const int NumOrdersToDisplay = 50", because that makes the code more readable ("if a < NumOrdersToDisplay", it also means you only need to change it in 1 well defined place.

Places where Magic Numbers are appropriate is everything that is defined through a standard, i.e. SmtpClient.DefaultPort = 25 or TCPPacketSize = whatever (not sure if that is standardized). Also, everything only defined within 1 function might be acceptable, but that depends on Context.

like image 42
Michael Stum Avatar answered Oct 02 '22 02:10

Michael Stum