Configuration settings for all classes

I write a small web server and it accepts a configuration file with all the various parameters: how many threads are started, which class deals with each file extension, which file is displayed by default, etc. etc. forward. To represent this, I parse the configuration file into a Configuration object that contains all of these parameters, and the main class contains this object.
However, configuration data is required at almost every server level - classes inside classes inside classes ...

My question is what is the best to use here? Do I have to specify the configuration as a parameter for many classes and pass it back and forth? Should I make it a single? Is there any other solution that I don't see?

+6
source share
8 answers

Use Guice ! Guice is an injection dependency scheme that effectively replaces your use of a new keyword. You define object bindings in a module as follows:

 bind(Configuration.class).to(MySpecificConfiguration.class); bind(WebServer.class).to(MySpecificWebServerImplementation.class); 

And then, instead of typing up WebServer directly, you just ask Guice to do this for you:

 WebServer ws = Guice.createInjector(yourModule).getInstance(WebServer.class); 

Which will magically create MySpecificWebServerImplementation for you. If MySpecificWebServerImplementation is defined as follows:

 public class MySpecificWebServerImplementation { @Inject public MySpecificWebServerImplementation(Configuration configuration) { } } 

Then MySpecificWebServerImplementation will automatically receive the specified configuration, and you do not have to worry about passing it.

+3
source

Although Singletons no longer loved by many professionals for various reasons - I think there is a good use case for Ssingleton`.

However, ask yourself if the requirements of the web server really require a single, common configuration for all aspects of the server. And if so, how soon will they change soon? For example, let's say 3 websites are hosted on your server. And now you will be asked to set bandwidth limits for one of them - how do you configure this?

I really approve of a good singleton - although you should consider the whole thread safety issue when initializing in a multi-threaded environment (although it looks like you will not have this problem since you will not have multiple threads before initializing it.

Keep in mind that singlets live within ClassLoader , and if you have multiple ClassLoader (for example, for each .war download), you will have multiple copies of this " Singleton ".

Consider all aspects of your server, and if it's really simple - A Singleton save you a lot of headache - and make the code much more convenient and readable. As mentioned in one or two answers - dependency injection is a good alternative to Singleton - they help you simplify your work with JUnits.

One note about JUnit, I understand (have not tried it yet) that Mockit can allow you to replace the actual implementation during a test run, so you can create different JUnit test cases for different scenarios without changing your Singleton to test.

+2
source

Making this a singleton seems like a wise decision. I think it would be a mistake to pass the configuration as a parameter to other constructors of other classes or method calls, as this, as a rule, pollutes the arguments of the method and makes them unnecessarily complicated.

If you decide to make a singleton, I would recommend developing a mechanism that allows you to introduce new instances of the configuration into a singleton class so that the singleton does not make your unit tests very difficult to perform.

+1
source

Passing the Configuration instance around adds a lot of unnecessary clutter to your code. Singleton is a good idea or adds some kind of manager class that provides all of these shared resources, such as configuration data.

If you go for singleton, consider implementing an enumeration template:

 public enum Config{ DATA; private int value1; private int value2; private int value3; public load(File configFile) { // some magic to store the values } public int getValue1() {return value1;} public int getValue2() {return value2;} public int getValue3() {return value3;} } 

You can use it everywhere in your code:

 int property = Config.DATA.getValue1(); 
+1
source

If you do this in Java, I would put the whole configuration in Spring , and then either use the Application Context to find the settings or just enter them into my beans. Spring is superior to such things.

+1
source

We have your properties set as system properties. They are accessed by the SystemProperties class.
This is a final class with a private constructor, accessing properties is carried out only using static methods, so it is technically Singleton. It itself is contained in commons.jar, each other project depends on.

Thus, there is no need to transfer anything around, since the settings are available right where you need them.

+1
source

I will finally make the Singleton configuration holder class! I have a classic use case for a Singleton instance.

0
source

There is no configuration, but it's good to have one singleton ServerManager object. Too many global access issues are a bit confusing. The configuration must belong to the "component":

 ServerManager.getServerManager.getConfigurationComponent(Configuration.class); 

ServerManager must create and read the configuration object at startup. Save and close it before you leave.

If you use it more than once in any class, save it as a private trailing field.

0
source

Source: https://habr.com/ru/post/888312/


All Articles