Is encapsulating the properties file in a class a good practice?

Asked

Viewed 1,702 times

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 file settings .properties in a Java object, with this I have the advantage of being able to validate the file information, generate programming logic and even use the Eclipse autocomplete but I have the disadvantage of not being able to create properties dynamically, so I have to wonder if this is good practice or just something to further complicate development.

Ex:

File config.properties

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

}

3 answers

3

If the file is large this approach will give you a certain job.

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

att

Victor.

  • 1

    Welcome to SOPT! I want to praise the fact that your first intervention on the site have been through a reply.

  • +1 Good points.

1


In general it seems to me a good practice to settings, excluding other types of values such as internationalisation texts or lists of values.

The main reason for this statement is because more sooner or later you may decide to change the setting to another source, as a database, file in a specific disk path, a parameter in the web.xml and so on. In that 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 now 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 track which configuration is used in which place.

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

However, as Vitor well recalled, the code can be extended if there are many getters. Another approach is a map (more or less what Rodrigo just mentioned in the PHP approach. However, although more flexible, this approach reduces traceability.

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

Update on the implementation

In the original answer, I ended up not getting into much implementation detail, however, looking more carefully at the code of the question, I noticed the public constructor.

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

  1. Static method. See an example of implementation in Wikipedia.
  2. Injection of dependencies through a container, such as Spring, CDI, HK2 EJB.

0

I’ll say the impression I get when working with Symfony that despite being a PHP framework, it is quite known for forcing its developers to adopt good practices (encapsulation, dependency injection, service-oriented architecture, etc).

The settings of a Symfony application in general come from YAML files, although they can also come from XML files. The Symfony configuration component, at first, validates the syntax of the files and plays an exception if something is wrong.

Hence one of the most interesting aspects of it: when you take the application settings and the matter for a Bundle, it is possible to set a default for the configuration of that Bundle - for example:

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

If any of these values do not fit the set default setting, 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, including) inside. This makes the application load much faster and the configuration files do not have to be read again every time a request is started.

(it is worth remembering that Bundle will only be compiled if the settings there are valid, according to the restrictions you set yourself).

At the end of the day, at any point in the application I can search the configuration with a line of code like:

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

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.