4

I've noticed some projects like to store constants in their own file, i.e constants used globally and in the main program loop might clutter the main file so perhaps they look to place them elsewhere and then reference/import file/class.

I understand that when writing an OOP class that you'd want to keep all constants at the header of the class file so they can be referenced statically as such:

myCar.setColour(Colour.RED);

Where RED is a colour constant in the Colour class.

What is good practice for having a large amount of constants, should they just be at the top of your main file or is it in any way wise to have maybe a ProgramConstants class that is purely static, public and available to read?

insidesin
  • 198
  • 1
  • 1
  • 9
  • 4
    I don't see how that's a duplicate... – insidesin Jul 17 '15 at 10:21
  • ["Your peer tells you after reviewing the code..."](http://programmers.stackexchange.com/a/141010/31260) – gnat Jul 17 '15 at 10:22
  • What's your point? How does this relative to storing information in seperate classes? – insidesin Jul 17 '15 at 10:23
  • 2
    Well, that's what your question boils down to in the end. "Is that more readable and maintainable?" – Deduplicator Jul 17 '15 at 10:23
  • @Deduplicator Not really. It boils down to the explanation of why one would put them into another class or why one would not. I am looking for answers based on advantage and disadvantages, not a way I might find out in the future or 'what I like to do'. – insidesin Jul 17 '15 at 10:25
  • recommended reading: [What is the problem with “Pros and Cons”?](http://meta.programmers.stackexchange.com/q/6758/31260) – gnat Jul 17 '15 at 10:26
  • @gnat So knowledge is worse than no knowledge? Okay that makes great sense... – insidesin Jul 17 '15 at 10:27
  • ["We already tried supporting those questions, we even gave them their own site. Sadly, it didn't work out..."](http://meta.stackexchange.com/a/200144/165773) – gnat Jul 17 '15 at 10:29
  • Thanks for linking me to an article of someone flailing their failed project around, quite irrelevant though unfortunately. :( – insidesin Jul 17 '15 at 10:31
  • 1
    that "someone" as you call them, is a moderator over here. And that "failed project" is what this very site attempted at it's beginning. And that "article" explains in details how it went and how it was discovered that such questions are poor fit over here. "Irrelevant", yeah sure – gnat Jul 17 '15 at 10:35
  • Good for them :) Obviously you can attempt the same thing in two situations with different implementations and of course different outcomes. That's not news to me. So you're saying asking theory questions on the internet is a poor method of getting information? O-K. – insidesin Jul 17 '15 at 10:37

1 Answers1

10

The idea behind encapsulation in object-oriented programming is moving data and the code that uses it together.

There is no "but the data are constants, treat them specially." If you have colors, keep them in a Color class. Java's Calendar class has calendar field constants in it. BigDecimal and BigInteger each contain constants of their own type.

The idea is that referencing constants involves their scope: BigDecimal.ZERO for example. I know that is a decimal zero because I typed BigDecimal.ZERO and not BigInteger.ZERO.

One of the worst anti-patterns in this regard is having a "constant interface" which is honestly lazy and unclear. Sometimes you come across an interface containing a bunch of random constants thrown together, and classes will implement the interface just to make it easy to refer to the constants. That generally ends up violating LSP and makes it difficult to determine what those constants do.

Constants should be:

  • An enum if appropriate, such as java.math.RoundingMode. The Java Calendar fields which were created before enum existed should be an enum. This necessarily scopes them properly and ensures other constants are not in the same namespace (class static final field).

  • Located on the class that defines their type, if appropriate. This covers the reusable numbers on BigDecimal for example.

  • Located somewhere else where like constants are together and not intermingled with other, unlike constants.

One could argue this is a matter of opinion. I feel that if you asked any group of experts to compare e.g. BigDecimal and some random AWT constants class, we would come to a consensus that there are some really bad practices in reality and some that make code clearer and easier to understand.

  • What about things that aren't directly tied to an Object but are instead more logically linked to the main program itself (or something better worded). – insidesin Jul 17 '15 at 11:14
  • @insidesin without much information to go on I cannot say for sure, but maybe it should not be a constant, then. Just make it a local variable and pass it into objects that need it. For example, the "application name" can be a variable like this instead of a constant. –  Jul 17 '15 at 11:15
  • To add a bit and perhaps answer @insidesin 's question, I would argue topics like this from the angle of [cohesion](https://en.wikipedia.org/wiki/Cohesion_(computer_science)). The driving questions are: what is the underlying motivation for we grouping things together? Does it simplify things or complicate them? Could we have come up with a better grouping? In my opinion, grouping things together only because they share in a relatively unimportant implementation detail falls under coincidental cohesion, and there are likely much better groupings to use. – Daniel B Jul 17 '15 at 11:29
  • @DanielB that is the core idea behind [encapsulation](https://en.wikipedia.org/wiki/Encapsulation_%28computer_programming%29) which I mentioned in my answer. Sometimes constants are highly cohesive with the classes that contain them, sometimes not so much. That is the crux of what I iterated in the bullet points. –  Jul 17 '15 at 11:46
  • @Snowman I agree (with both your answer and your comment); I just feel that the "types of cohesion" list has some value to add to the discussion, in that it actively lists and ranks different reasons for keeping things together. Representing it as a gradient helps with the justification, or at least it has helped me. – Daniel B Jul 17 '15 at 12:49
  • I was always taught high cohension, low coupling. It's like a motto. – insidesin Jul 17 '15 at 14:27
  • Yeah, good point. Cohesion is important, I guess I consider that implicitly with encapsulation. Items that are encapsulated together should have high cohesion. –  Jul 17 '15 at 14:46