1

I was just wondering if there is some better way how to handle system "static" configuration data. Let say you have a system which offers several operation which are in code translated to operation code but you need to keep other related information to that operation like description, priority etc. Nasty way I have seen is public static final constants. Better way I was using before was create a class eg:

public abstract Codebook{
private int id;
private String description;
... getters setters
}

Then for given cathegory - in this case OperationalCode:

public class OperationalCode extends Codebook{}

Instance of this class were created with the data from BD. Now I cannot use DB so I thought I will create factories which will populate classes with given set of parameters. BUT all is hardcoded to factory class which I don't like.

Is there a better solution how to tackle this case as I believe I am not the first one solving that. Some handy framework or ...

I wasn't probably clear enough. I am fully aware of Properties capability in java but that doesn't match the criteria. Let me explain more: When I say configuration I mean business configuration. You never know how many possible items you will get. For example in banking system you can cancel contract and you are forced to provide a reason for termination - predefined list which includes text, code in your system and translation to codes of third party systems where your system need to perform cancelation operation as well. Those possibilities need to be externalized of your system as they will probably change offten. Property files doesn't seems as a right choice and the opposite site - using Buisiness Rule Systems (e.g. Drools ) seems to me as overkill. Using enums with specified properties wouldn't fit quit well because time to time you need to be able to recognize that it is configuration and not just normal enum. That the reason for class inheritance - instanceof operator solve this.

7
  • 1
    a property file?
    – nachokk
    Sep 11, 2013 at 16:07
  • a CSV or XML file?
    – Gamb
    Sep 11, 2013 at 16:10
  • 1
    Extending a class just to get some "constants" is terrible practice. It's an abuse of inheritance and makes it harder to, say, use different values in a test environment.
    – millimoose
    Sep 11, 2013 at 16:16
  • 1
    Would you mix a "configuration" for two production systems? I would say that is horrible practice as well. But that is not the case here. Every class defines a distinct kind of "system business configuration" data. Given class has many instances - defined by business owner of the application. You don't know how many in advance and more over that is the flexibility you are trying to get in opposite to hard code it either in code or ...
    – jaksky
    Sep 11, 2013 at 20:03
  • 1
    A more concrete example would be appreciated.
    – Thufir
    Sep 16, 2013 at 13:35

2 Answers 2

4

Store the constant values within a properties file called application.properties (for example)...

property1.value=Hello
property2.value=World
property3.value=Another property

The content should match the key=value pattern and also, parameters are supported.

property.with.parameter=My name is {0}.

If the file is stored within the root folder of the project, you can read each of them like this:

Properties properties = new Properties();

try {
    properties.load(new FileInputStream("application.properties"));
    System.out.println(properties.getProperty("property1.value"));
    System.out.println(properties.getProperty("property2.value"));
    System.out.println(properties.getProperty("property3.value"));
 } catch (IOException ex) {
    ex.printStackTrace();
 }

You can read more about Properties in the Official Oracle Tutorials.

0

Some languages have a degree of metaprogramming that allow you to construct arbitrary classes that inherit from a base class on the fly. Something along the lines in Ruby (just an example) of (and I don't claim I'm writing valid ruby code though if one wanted to it would give an idea of which way to look):

# get lines of file, or hardcode... whatever
lines.each do |line|
    process line
    cls = Class.new(Object) do
        self.instance_variable_set(name,value)
    end
end

You've got a config file sitting somewhere (in a database?) and load it in, and make all the classes on the fly. Glance at enums in ruby if you want another thought of how to do it with it there.

Java doesn't have as rich a meta programming set available to it. You can make anonymous classes, but they aren't exactly arbitrary anonymous classes... and not what you're really after either.

Lets start off with a class. Lets call it terminationReason. Its abstract, and it has all of the associated business logic in it if it needs it. It has a constructor and you've got your Factory. Yes, this is the approach you didn't like - the Factory would indeed become rather monolithic with all of its various values.

Instead, lets make terminationReason abstract. Then you've got the classes that implement it. You've got latePayment extends terminationReason. If there is nothing special in latePayment, it consists of a constructor that has the values set and thats it. I don't see any glaring problems with this code structure. It isn't that flexible, but if you don't need flexibility it has nice bits of the logic for a particular reason can be adjusted and you can have type safety (you must pass a latePayment to some other method). I want to stress that this really isn't significantly better than using an enum. You've hard coded configuration in lots of small discrete classes instead of an enum. It makes doing things like "show a list of drop down options" much more difficult.

What might be better though, is a combination of structured data files (json, xml or the like) and the factory. Have the factory read the associated data and construct the objects as necessary. This adds a degree of flexibility in the code - you can change what objects and parameters that are created without recompiling the application (note the 'Those possibilities need to be externalized of your system as they will probably change often' in the question).

There is a strong case of the use of instanceof to separate code functionality is a code smell. See avoiding instanceof in Java or Switch Statement code smell and Polymorphism or Instanceof In Conditionals. And while you are right that inheritance is a good thing, using instanceof and associated conditionals to determine functionality is a bad thing.

If you are considering drools or similar systems, you might want to take a long look at it and consider it again. Few applications reduce in scope as time goes on. It is also fairly safe to say that few maintain the same scope. If you find yourself writing custom code that should have been done in drools, or reimplementing logic that off the shelf would have done much more easily... I don't know if drools is the right thing for you. I do know that I've seen many projects where just one rule turns into something that balloons to huge sizes later on and a business rule management system early on could have saved hundreds of hours of custom code and debugging.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.