Constants.h considered harmful

It's common to use a centralised "Constants" class where you gather together lots of constants for your app. For example, in Objective-C you'll often have a big file Constants.h full of lines like this.

  1.  
  2. #define DEBUG_MODE NO
  3. #define APP_URL @"http://itunes.com/apps/mycoolapp"
  4. #define CHARACTER_ANIMATION_TIME 2.0f
  5. #define FOOTER_IMAGE @"mycoolapp-footer.png"
  6. #define FONT @"Helvetica-Bold"
  7.  

Don't do this.

Why?

1. It increases compile times significantly. Because lots of other classes depend on Constants.h (it's common to include it in the .pch header file so all files have access to it), any small change to Constants.h means that every class in your application will need to be recompiled. And ironically, during development at least, constants are often variable 🙂

2. It makes unit testing more complex, adds additional dependencies and discourages re-use. Because many classes depend on Constants.h, its harder to test them in isolation. Moreover, you can't easily transfer classes between projects, without manually checking which parts of Constants.h needs to be copied too.

Instead, it's much better to place constants in the class which they are used in. If you have a true need for a global constant, but it is for a value which you might want to frequently change during development (such as the DEBUG_MODE boolean above), consider using a macro to load the value from a config file, for example you could define a key in the Info.plist:

  1.  
  2. #define DEBUG_MODE ([[[[NSBundle mainBundle] infoDictionary] objectForKey:@"APP_MODE"] isEqualToString:@"DEBUG"])
  3.  
Matt Mayer

Matt Mayer is a founder at ReignDesign. Matt is from the UK and was based in Shanghai for ten years. He is now living in Bangkok, Thailand.

Leave a Reply

Your email address will not be published. Required fields are marked *