I have a java program that uses a handful of .properties files. It chooses what properties file to use based on a parameter (mode) passed at runtime.
for example when the program is running in mode:a it uses a.properties file and when mode:b it'll uses b.properties file, etc.
I want to combine all these properties files into one common.properties and instead have different namespaces. For example in common.properties I'll have:
a.url = aaa
a.ip = aaa.aaa.aaa.aaa
b.url = bbb
b.ip = bbb.bbb.bbb.bbb
Right now, I instantiate the properties object in the main method and pass it to the other objects/methods that need to read something from the properties.But now that I've combined the properties I have to pass the mode: a or b as well so that they know what set of properties they should extract.
Is there a better way of creating a filtered instance of the properties file in the main method and then passing that to other object in a way that these objects are not aware of the mode: a or b, and just query the properties object for url and ip (not a.url or a.ip)
Don't pass the Properties object to other methods/objects. It's too low-level, especially now that you have to deal with this namespace thing. Encapsulate the Properties inside a dedicated object (let's call it "Configuration"), and pass this Configuration object.
public class Configuration {
private String mode;
private Properties properties;
public Configuration(String mode, Properties properties) {
this.mode = mode;
this.properties = properties;
}
public String get(String key) {
return properties.getString(mode + "." + key);
}
}
You could even extract the contract of this Configuration object into an interface, and make all objects depend on this interface rather than the concrete Configuration class, which would help in
changing the configuration strategy later if you want to (if you has done this from the start, you wouldn't have to change anything in all the objects now)
mocking the configuration in unit tests to make it return what you want.
You can extend the Properties class, add a getter and setter for the active namespace, and override the get() method to prepend the active namespace and call the super.get() method.
Related
I want to set up some global variables that are accessible by multiple classes. Examples of these global variables would be things like some key(Strings)
I am fetching these variable from database and variables would probably not change except when the program is re-compiled
The easiest way is to define a #Component class with field of typeMap for these properties. Then populate it at the start of your application with information retrieved from database.
Then, whenever you want to use these properties inject these using Spring Boot's DI mechanism.
You did not provide much details so the answer will be generic too.
There basically are two approaches:
You could use the Java Properties class.
public static final Properties defaultProperties = new Properties();
Initialize your defaultProperties from database at program start with defaultProperties.put("name", value).
Access your properties by defaultProperties.get("name").
Write your own configuration class.
class MyConfig
{
public final String SomeStringProperty;
public final int SomeIntProperty;
// Singleton
public final static MyConfig instance = new MyConfig();
private MyConfig()
{ // Init properties from database here.
}
}
You might need some dependency injection pattern to initialize MyConfig, e.g. to establish the database connection.
Both methods are similar. The second one provides more type safety and prevents you from accidentally accessing a non existent property because of a typo in the property name. The first one in contrast can be made generic in a way that no code changes to the configuration code are required when new properties are added. Of course, you still have to write code that accesses the new property.
You can set this properties on application.properties file.You can use this properties all over on your project.
For example:I am using key for hit third-party .So I am taking key on my properties file.
My question is the same as this one except it is for Java, specifically applied to properties. Ideally I would like to create one instance of Properties, and call the methods from all of the classes without creating new instances. I would also want to read from a single instance of properties so I only have a single source of the truth.
I have read the API for Properties and it doesn't answer my question.
This question indicates I need to include the reference in the class constructor. Is there a better way??
The fisrt link, "this one" is a link to the Oracle documentation...
If you want to load your properties only once, you should use the singleton pattern. But be carefull that this pattern can be an anti-pattern and may make your unit tests more complex.
To avoid those drawbacks it is better to pass the reference to your properties via a constructor.
/* This is your singleton. It takes care of loading the properties only once and can delegate access method to it */
public class Configuration {
private static Configuration instance; // created only once
public static getInstance() {
instance = // Read the Singelton pattern to create it only once
}
private Properties properties; // loaded only once
public String get(String key) {
return properties.getProperty(key);
}
}
public class Component {
private final Configuration cfg;
public Component (Configuration cfg) {
this.cfg = cfg;
}
}
public class StarterOrDiContainer {
// ..
Component component = new Component(cfg.getInstance());
}
Let's take the system properties as example. In this implementation http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/System.java#System.getProperty%28java.lang.String%29, the properties are just stored in a static class attribute. Either make this attribute public or create public accessor methods. Short answer: just make it static.
You can initialize static data with static initializers, if things get a little bit more complex. (https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html)
I need to implement a solution as part of Test framework & I am considering singleton pattern for reasons explained below. However, I am not able to achieve my intended solution & therefore would need some suggestions/inputs on possible implementations.
Problem Statement :
I have a environment (env of the product I am testing) configuration properties file which I want to load & make the value of the parameters accessible globally to the test framework.
I figured using the singleton pattern because these properties are one-time values (should report an exception if tried to initialize more than once), should be available globally & have an one-point access to the methods.
However, the list of properties/parameters is really long & therefore it's wise to break it into modules (classes). For the below explanation, I tried with composition.
For e.g.
public class Configuration {
private static Configuration configObj;
private static Database dbDetails;
private static Machine macDetails;
//...
//... many more modules
public static synchronized void createInstance(Properities envProps){
//Should create only one instance of Configuration
// and should also initialize Database & Machine objects.
}
public static Configuration getConfigObject(){
return configObj;
}
}
public class Database {
private static String dbConnectString;
public Database(String dbcs){
dbConnectString = dbcs;
}
public static String getDbConnectString(){
return dbConnectString;
}
}
public class Machine {
private static String hostname;
private static String loginUsername;
public Machine(String hostname,String loginUsername){
this.hostname = hostname; //It may include some trimming/cleaning
this.loginUsername = loginUsername;
}
public static String getHostName(){
return hostname;
}
}
PS: Just a sample typed-in code for the understanding of my problem statement.
Expectation : The expectation now is that when trying to get the hostname, I should have a single point of access via Configuration static object (assuming that I have initialized all member variables successfully) i.e.
String hostname = Configuration.getHostname();
OR
String hostname = Configuration.getConfigObject().getHostname();
Current Issue :
How to create one static object that will refer to all methods using either composition or inheritance (Conceptually, composition would be the right approach).
Multiple Inheritance would have solved the issue but Java doesn't support so ruled out. Cannot consider Interfaces either because overriding all methods is tedious & lengthy & the parameters/methods will keep changing over-time.
All suggestions are welcome even if it requires to scrap this design pattern & try something different.
You will not be able to "automatically" delegate static calls to modules. And even if the calls were not static, as you stated, Java does not support multiple inheritance.
Option 1:
Have your main Configuration class provide static methods that return instances to your modules. Whenever you want to read a configuration entry, first get the module instance, then query the entry itself:
Configuration.getDatabaseConfiguration().getServerName();
This method has the advantage that it is very clear which part of your configuration you are referring to. If you would just use Configuration.getServerName(), you cannot distingish whether you want to retrieve the database's server name, or the webserver's.
Option 2:
If you are able to use Java 8 and your configuration is large, but very simple (statically known at compile time or extractable from very few instances), you could consider using the new default interface methods (https://blog.idrsolutions.com/2015/01/java-8-default-methods-explained-5-minutes/).
You would then create an interface for each module, where all getters have default implementations. Your main configuration class would implement all the module interfaces without overriding any of the methods. This way all configuration entries can be queried from one object, but you still have to obtain this object by a static method. This is as close to multiple inheritance as you can get. I would definitely recommend option 1 though.
We have some data in properties file. This data is used across many classes. So, we create a Properties class object in each and every class and then read data using getProperty() method. This is leading to duplication of code.
Can someone please suggest some best practices to avoid this?
One thing that came to my mind is:
Create a class
Have a public variable for each property in property file in this class
Have a method that assigns values to each and every property
In the class where property values are required, create an object for this class and access the public variables
But, things i don't like with this approach are public variables and if at all a new property is added to the property file, i need to add code to read that property in the class.
Any help is appreciated.
Thank you!
You can create a Singleton class, that loads the properties the first time it gets invoked.. and a public method that retrieves the property value, for a given property key..
This is assuming you're using a standart Properties file... But you can extrapolate this to any key-value pair, changing Properties type to a Map or something else.
Something like
public class PropertyHandler{
private static PropertyHandler instance = null;
private Properties props = null;
private PropertyHandler(){
// Here you could read the file into props object
this.props = .....
}
public static synchronized PropertyHandler getInstance(){
if (instance == null)
instance = new PropertyHandler();
return instance;
}
public String getValue(String propKey){
return this.props.getProperty(propKey);
}
}
Then you can invoke this as needed.. from any code.. like this.
String myValue = PropertyHandler.getInstance().getValue(propKey);
Hope this helps
for me static inner class is the best possible way to do it. It will do it with lazily, as class loading is synchronized so thread safe, plus performant also. So with this we are achieving three things:
good performance because with synchronizing the liveliness will suffer, but here we are using static inner class.
thread safety because when inner class will be loaded than only map will be initialized as the class loading is thread safe hence all total thread safe.
Inner class will be loaded when we will call Singleton.initialize().get(key) so the map gets initialized lazily.
Below is the code...
public class SingletonFactory
{
private static class Singleton
{
private static final Map<String, String> map = new HashMap<String, String>();
static
{
try
{
//here we can read properties files
map.put("KEY", "VALUE");
}
catch(Exception e)
{
//we can do the exception handling
System.out.println(e);
}
}
private static Map<String, String> initialize()
{
return map;
}
}
public static String getValue(String key)
{
return Singleton.initialize().get(key);
}
}
One out of the box option is to use system properties. You can add your own system properties to your execution environment.
You can do this with a dedicated class having a static Properties object. See here for an example.
I could be misunderstanding your data flow here, but this is what seems "normal" to me:
Create a readPropFile method.
This should read a file and appropriately parse the properties it finds.
These properties can be stored in a Map<String, Object>, hashed by property name.
Read property file once (presumably when the application starts, or whenever it's appropriate to load properties) --> Properties object (say, props).
Pass props around to anything that needs access to those properties.
Or if you don't want to pass it around explicitly, use a static accessor as illustrated here.
Access properties using props.get("PROPERTY_NAME") (which just looks up that property in the internal Map).
If you don't want to use String lookups, you can keep an enum of valid property names somewhere, and do storage/lookups using that, but then you have to update that enum every time you add a new property to the file.
I've had success using an Enum, and in the constructor using the name() method to read a property of the same name. Be sure to handle exceptions in a reasonable way or else the whole class will fail to load and you won't get a helpful error message.
Benefits of this approach are that each enum value automatically corresponds to a property without having to write individual mapping code for each property. You do of course need an enum value for each property (that's unavoidable if you want DRY prop references), but you avoid repetitive per-property initialization code using unchecked Strings.
Drawbacks are that enums don't allow generic types, so if you wanted certain properties to return Integer and others to return String, then you might be better served with a classic singleton class design.
If you want to go crazy with this you could also write a script to generate your Enum or singleton java source code from the properties file, to keep your code extra DRY.
I am designing a complex Configuration class as part of an API design. The Configuration class roughly looks like this.. (I ignored generics/access modifiers etc)
class Configuration {
One obj1;
Two obj2;
}
class One {
List<Double> values;
}
class Two {
double value;
Map<String, Double> data;
}
This is what I want to accomplish:
I want users to be able to create this Configuration class the first time easily and submit to server.
Then they can change any part of this class and send the updated configuration to the server.
What design patterns to use and avoid?
Is it better to make this class Immutable and use builder pattern?
Or just provide all kinds of modification methods On Configuration class so they can modify the same Configuration class (at all levels) in-place without having to create a new Configuration class for every update. I think Builder pattern is good for Immutable classes only.
Questions:
Is there any way to exploit Builder pattern for this type of scenarios?
Or is it better to provide mutator methods on Configuration class like I mentioned above?
Or are there any other better patterns available?
I think you should use prototype pattern:
in your code you can add map that hold all types of configurations
the map will have a key called "currentConfiguration" and the value will be the configuration that should be loaded. the map can also contains other configurations that can be stored in the map and can replace the current configuration if needed.
once you fetch configuration from the map you simply clone the configuration object and the user can do what ever he pleased with that. after the changes he can save the configuration in the map with speicifc name. so the user can get configuration object that is quite close that what he needs and configure it accordingly.
the code should look like this:`public class CloudRepository {
private Map<String, Configuration> rep;
public CloudRepository(Configuration current){
rep = new HashMap<String, Configuration>();
rep.put("current", current);
}
public Configuration getConfiguration(String string){
return (Configuration) rep.get(string).clone();
}
public void addConfiguration(String name, Configuration conf){
rep.put(name, conf);
}
public void replaceCurrentConfiguration(Configuration conf){
rep.put("current", conf);
}
}
you can also write more code to handle history for your configurations.
you can also consider making this class singleton