views:

163

answers:

6

I am making a program which makes use of a couple of constants. At first, each time I needed to use a constant, I'd define it as

//C#
private static readonly int MyConstant = xxx;

//Java
private static final int MyConstant = xxx;

in the class where I'd need it. After some time, I started to realise that some constants would be needed in more than one class.

At this time, I had 3 choises:

  1. To define them in the different classes that needed it. This leads to repetition. If by some reason later I need to change one of them, I'd have to check in all classes to replace them everywhere.
  2. To define a static class/singleton with all the constants as public.
  3. If I needed a constant X in ClassA, ClassB and ClassC, I could just define it in ClassA as public, and then have ClassB and ClassC refer to them. This solution doesn't seem that good to me as it introduces even more dependencies as the classes already have between them.

I ended up implementing my code with the second option. Is that the best alternative? I feel I am probably missing some other better alternative.

What worries me about using the singleton here is that it is nowhere clear to a user of the class that this class is using the singleton. Maybe I could create a ConstantsClass that held all the constants needed and then I'd pass it in the constructor to the classes that'd need it?

Thanks

edit: I'm using this mostly for complex types, not ints and strings. At least in the C# case that makes a difference as it means I can't use the const keyword.

+1  A: 

I'd define it in one place, in one of the classes that needed it. I'd make it static and final and public so it was true constant, accessible by any other client that needed it.

duffymo
+3  A: 

Use a properties file and put the constants in there.

Romain Hippeau
Why did I get dinged ?
Romain Hippeau
A: 

One approach to this would be to use Spring, available in both Java and .NET.

www.springsource.org
www.springframework.net - .net

Otherwise I'd use a config file.

McAden
When you mean a config file, in the end you mean using something like a Singleton?
devoured elysium
By config I mean constant placed in a single location in a separate file where it can easily be found if it needs to be updated - belonging to the application rather than a specific class. If you felt you needed a singleton Spring would be ideal for that.
McAden
Yes but from a design point of view what you are doing is relying in something that ends up looking like a static class. You have all your classes relying on an object that has a "global" state.
devoured elysium
+3  A: 

No wording about C#, but in Java there are several ways to solve this problem.

  1. Change the access modifier to default (package-only) or public. The most straightforward solution.

  2. Group them in a package-private or public enum. Most straightforward if those values are related to each other. E.g. Role.ADMIN, Role.USER, Role.GUEST, etc.

  3. Declare them in a package-private or public interface and let the classes implement it. Only do this if those constants belong to some contract the classes have to adhere as well.

  4. Put them in properties files and load as private static final Properties and add a public static String getProperty(String key). Wrap this in some package-private or public Configuration class. More useful if those constants might be sensitive to changes which you could then control externally.

Constants doesn't require to be accessed by an instance, so the whole singleton idea makes no sense.

BalusC
If it was in a singleton, they wouldn't be declared as static, of course. They'd just be declared static if in a static class or put inside each class that'd need it.
devoured elysium
Then those values are actually not **constants** anymore. No, forget the singleton idea.
BalusC
+1  A: 

ConfigurationManager.AppSettings Property in .Net exists for just this reason. You put the settings into config files assuming that these are elements that you want to be set in one place,e.g. for a website using ASP.Net the web.config is one location where settings can be placed so that development, test and production environments can each have different settings in how they run.

JB King
Yes but that ends up being as a static class, right?
devoured elysium
Probably, but my point is that there are built-in classes to do what you need, so why not use them?
JB King
+1  A: 

As far as int is concerned I usually use an enum in C#

public enum MyMagicNumbers
{
    TheFirst = 1,
    TheSecond = 2,
    TheLast = 10,
}

For other types - like BalusC already mentioned - a sealed class is all you need

public sealed class MyMagicStuff
{
    private MyMagicStuff() {}

    public const string TheFirst = "One";
    public const string TheSceond = "Two";
    public const string TheLast = "Ten";
}
Filburt
How would one even use the data if you can't instantiate the class and the fields are not static?
devoured elysium
@devoured It's sufficent to make them `const` - at least in C#.
Filburt
Didn't know that fact. Anyway, my types are complex, thus I can't use the "const" modifier on them.
devoured elysium
@devoured You may want to update your question concerning the complex type requirement - most answers assume you're dealing with simple types.
Filburt