Encapsulating the properties file in a class is a good practice?

3

In other languages like Python it is possible to perform programming logic in the configuration files and in Java this is not allowed because it is a compiled language.

I decided to encapsulate the settings of the .properties file in a Java object, so I have the advantage of being able to validate the file information, generate programming logic and even use Eclipse autocomplete, but I have the disadvantage of not being able to create properties dynamically, so I have the doubt whether this is a good practice or just something to complicate further development.

Ex:

Config.properties file

email.user=user
email.host=smtp.email.com
email.auth=true  

Class:

public class Config {

    private String emailUser;
    private String emailHost;
    private Boolean emailAuth;

    public Config() {
        Properties properties = new Properties();
        try {
            properties.load(Config.class.getResourceAsStream("/config.properties"));
            emailUser = properties.getProperty("email.user");
            emailHost = properties.getProperty("email.host");
            emailAuth = Boolean.valueOf(properties.getProperty("email.auth"));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //Somente Gets

}
    
asked by anonymous 27.02.2014 / 13:25

3 answers

1

In general it seems like a good practice for settings , excluding other types of values such as internationalization texts or lists of values.

The main reason for this is because sooner or later you may decide to change the configuration to another source, such as a database, a file on a specific disk path, a parameter in web.xml and so on. In this case, you would only need to replace the implementation in one place, without impacting the entire system.

Another reason is centralize and standardize access to settings . You get to have a certain level of control of where and what settings you are using. If each class was responsible for accessing its own configuration, it is possible that some time later it would be difficult to trace which configuration is used where.

The last comment takes us to the principle of single responsibility . Each class must have a well-defined and unique responsibility. Code to get reading properties in the middle of business rules is something that pollutes the code.

However, as Vitor has pointed out, the code can be lengthy if there are many getters . Another approach is to map (more or less what Rodrigo just mentioned in the PHP approach.) But, although more flexible, this approach reduces traceability.

Finally, the decision is up to each project. Particularly, I've never worked on projects with many parameters where it would be impractical to create getters .

Update on the implementation

In the original response, I did not go into much of the implementation details, however, looking more carefully at the question code, I noticed the public constructor.

This can lead to unnecessary instantiation of the class in several places. You need to adopt the Singleton pattern and this can be achieved in two ways:

  • Static method. See an example implementation at Wikipedia .
  • Injection dependencies through a container, such as Spring, CDI, HK2 EJB.
  • 27.02.2014 / 14:14
    3

    If the file is large this approach will give you some work.

    You can use a singleton or (if you are using CDI) something with application scope to open the file and keep the instance of Properties.

    att

    Vitor.

        
    27.02.2014 / 13:49
    0

    I'm going to say the impression I have when working with Symfony which, despite being a PHP framework, is well known for forcing its developers to adopt good practices (encapsulation, dependency injection, service-oriented architecture, etc.) / p>

    Symfony application settings generally come from YAML files, although they may also come from XML files. The symfony configuration component initially validates the syntax of the files and throws an exception if something is wrong.

    Here's one of the most interesting aspects of it: when you take application settings and matters for a bundle, you can set a default for that bundle setting - for example:

    >
    • The value can not be null;
    • The value can be null, but if it is set it has to be one of the predefined values;
    • The value can be an array, an integer, a string, or even having a variable type;

    If any of these values do not fit the defined configuration pattern, an exception is thrown.

    Then, when the entered settings are validated, Symfony compiles that bundle into a single PHP file, already containing the settings (validated, inclusive) inside. This causes the application to load much faster and the configuration files do not have to be read again every time a request is started.

    (Note that the bundle will only be compiled if the settings there are valid, depending on the restrictions you have defined yourself.)

    After all, at any point in the application I can fetch the configuration with a line of code of the type:

    $this->getContainer()->getParameter('endpoint');
    

    Finally, as I said, the idea here is not to panfile a framework (ok, just a little bit), but to expose a configuration concept that I find very interesting and that is suddenly worth replicating to other frameworks . So here's a hint of how you can implement such features in your project:)

        
    27.02.2014 / 14:04