Suggestions for implementing a solution using Singleton design pattern - java

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.

Related

Java Application return super class when initialized

Nowadays we are on writing some core application that is all other application will be relying on. Without further due let me explain the logic with some codes,
We used to have a single java file that was 1000+ lines long and each application was having it as class inside, so when there was a change, each application had to edit the java file inside of it or simply fix one and copy to all. This is hard to implement as much as it is hard to maintain. Then we end-up with creating this as a separate application that is divided to smaller part, which is easy to maintain and also a core maybe a dependency to other application so we fix in one place and all other code applications are fixed too.
I've been thinking for a some great structure for this for a while want to use a builder patter for this as below
TheCore theCore = new TheCore().Builder()
.setSomething("params")
.setSomethingElse(true)
.build();
The problem arises now. Like so, I initialized the object but now I'm having access to that objects public class only. This application actually will have many small classes that has public functions that I don't want them to be static methods that can be called everytime. Instead I want those methods to be called only if TheCore class is initilized like;
// doSomething() will be from another class
theCore.doSomething()
There are some ideas I produced like
someOtherClass.doSomething(theCore)
which is injecting the main object as a parameter but still someOtherClass needs to be initialized or even a static method which doesn't make me feel comfortable and right way to that.
Actually I do not care if initializing TheCore would bring me a super object that includes all other classes inside initialized and ready to be accessed after I initialized TheCore. All I want in this structure to have a maintainable separate app and methods avaiable if only the main object which is TheCore is this circumstances is initialized.
What is to right way to achive it? I see that Java does not allow extending multiple classes even it if does, I'm not sure it that is right way...
Thanks.
After spending significant amount of time of thought I ended up that
// doSomething() will be from another class
theCore.doSomething()
is not suitable since many java classes could possibly have identical method names. So...
// doSomething() will be from another class
theCore.someOtherClass.doSomething()
would be a better approach.
To make it easier to understand I'll have to follow a complex path to explain it which is starting from the package classes first.
Think that I have a package named Tools and a class inside SomeFancyTool
main
└─java
└─com
└─<domainName>
├─Tools
| └─SomeFancyTool.java
└─TheCore.java
Now this SomeFancyTool.java must have a default access level which is actually package level access, because I don't want this classes to be accessed directly;
SomeFancyTool.java
package com.<domainName>.Tools
class SomeFancyTool{
public String someStringMethod(){
return "Some string!";
}
public int someIntMethod(){
return 123;
}
public boolean someBooleanMethod(){
return true;
}
}
So now we have the SomeFancyTool.java class but TheCore.java cannot access it since it is accesible through its Tools package only. At this point I think of an Initializer class that is gonna be in the same package, initialize these private classes and return them with a function when called. So initiliazer class would look like this;
ToolsInitializer.java
package com.<domainName>.Tools
public class ToolsInitializer{
private SomeFancyTool someFancyTool = new SomeFancyTool();
public SomeFancyTool getSomeFancyTool(){
return someFancyTool;
}
}
Since ToolsInitializer.java can initialize all functional private classes inside in Tools package and also can return them as objects to outside of the package scope, still we are not able to use these methods as we cannot import com.<domainName>.SomeFancyTool from TheCore.java because it is package wide accessible. I think here we can benefit from implementation of the java interface. A class that is not functional alone, so no problem even if it is accessed since it's methods will be nothing but declarations.
At this point I'll rename SomeFancyTool.java to SomeFancyToolImplementation.java which it will be implementing the interface and call SomeFancyTool.java to the interface itself.
SomeFancyTool.java (now as an interface)
package com.<domainName>.Tools
public interface SomeFancyTool{
public String someStringMethod();
public int someIntMethod();
public boolean someBooleanMethod();
}
and lets rename prior SomeFancyTool.java and implement the interface
SomeFancyToolImplementation.java (renamed)
package com.<domainName>.Tools
class SomeFancyToolImplementation implements SomeFancyTool{
#override
public String someStringMethod(){
return "Some string!";
}
#override
public int someIntMethod(){
return 123;
}
#override
public boolean someBooleanMethod(){
return true;
}
}
Now our structure has become like this with the final edits;
main
└─java
└─com
└─<domainName>
├─Tools
| ├─SomeFancyTool.java
| ├─SomeFancyToolImplementation.java
| └─ToolsInitializer.java
└─TheCore.java
Finally we can use our TheCore.java class to call all initializer classes with their methods to receive all these private classes inside as an object. This will allow external apps to call and initialize TheCore first to be able to access other methods.
TheCore.java
public class TheCore{
private SomeFancyToolImplementation someFancyTool;
public static class Builder{
private SomeFancyToolImplementation someFancyTool;
public Builder(){
ToolsInitializer toolsInitializer = new ToolsInitializer();
someFancyTool = toolsInitializer.getSomeFancyTool();
}
public Builder setSomeValues(){
//some values that is needed.
return this;
}
public Builder setSomeMoreValues(){
//some values that is needed.
return this;
}
public TheCore build(){
TheCore theCore = new TheCore();
theCore.someFancyTool = someFancyTool;
return theCore;
}
}
}
All Done and it is ready to use. Now the functional package classes and its methods that it relying on if TheCore is initialized or not, cannot be accessed with out TheCore. And simple usage of this Library from a 3rd Party app would simply be;
3rd Party App
TheCore theCore = new TheCore.Builder()
.setSomeValues("Some Values")
.setMoreSomeValues("Some More Values")
.build();
theCore.someFancyTool.someStringMethod();
Note: Note that a the ToolsInitializer.java is still accessible and could be used the get private method without first calling TheCore but we can always set a checker inside getSomeFancyTool() method to throw error if some prerequisites are not satisfied.
I do not still know if this is a functional structural pattern to use or its just some hard thoughts of mine. And don't know if some pattern is already exist that I just could not see yet but this is the solution I end up with.

How to use a variable anywhere in the code?

In Java EE how can I use a variable anywhere in code without passing it down as a parameter?
Something similar to a public static variable... but a static variable is always the same for all the requests... What about a "static" variable but for the single request?
Is it possible?
Here is a little example:
I have:
protected void doGet (...)
{
Model m = Model.GetById (...);
}
public class Model
{
private String descrition;
private Market market;
private List<SparePart> spareParts;
public Model GetById ()
{
Model m = new Model ();
// get info from db using the language
this.market = Market.GetById (...);
this.spareParts = SparePart.GetByModel (m);
}
}
public class SparePart
{
private String description;
public List<SparePart> GetByModel (Model mo)
{
// get info from db using the language
}
}
public class Market
{
private String descrition;
public Market GetById (...)
{
// get info from db using the language
}
}
Both make queries to the database and retrieve informations using the language of the client... How can I set the language variable so i don't have to pass it to the methods that use it?
The anguage variable is just an example, it may happen with other variables
There are dozen ways to pass your data through execution flow in JaveEE applications. Let's assume you need to pass data within one application boundary.
Of course you can use public static final constants.
You can use public static variables, but take into account that EE
environment is extremely multithreaded. So use atomic wrappers
(AtomicInteger, etc).
You can use producers
While single request scope (http (rest) -> interseptor(s) -> bean(s)
-> response) you can use ThreadLocal
Of course you can use Stateful or Singleton beans You can use CDI
Events
If you are using Payara Server (for now the only has JCache spec
preview) you can use JCache to share your data among any
application or along the cluster as well
If you need to share your data between servers you can expose your business methods on #Remote interfaces and or share/publish/consume using JMX.
The concrete choice should depend on your App business logic.
You can set and get attributes on your ServletRequest object.
request.setAttribute("someName", someObject);
Object someObject = request.getAttribute("someName");
See the javadoc here.
Alternatively, you could use CDI (or another DI framework) and define one or more #RequestScoped objects that you can then #Inject in the places you need them.
Although not passing parameters is not a good idea in the first place, if you 'MUST' find a solution and if it matches your design, how about using inner classes? That way you declare the class variable as non-static and you can always access it from the inner classes.

Injecting Constants via Custom Annotation

I have a bunch of constants throughout my code for various adjustable properties of my system. I'm moving all of them to a central .properties file. My current solution is to have a single Properties.java which statically loads the .properties file and exposes various getter methods like this:
public class Properties {
private static final String FILE_NAME = "myfile.properties";
private static final java.util.Properties props;
static {
InputStream in = Properties.class.getClassLoader().getResourceAsStream(
FILE_NAME);
props = new java.util.Properties();
try {
props.load(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String getString(Class<?> cls, String key) {
return props.getProperty(cls.getName() + '.' + key);
}
public static int getInteger(Class<?> cls, String key) {
return Integer.parseInt(getString(cls, key));
}
public static double getDouble(Class<?> cls, String key) {
return Double.parseDouble(getString(cls, key));
}
}
The only problem with that is that for every constant that I get from this file, I have some boilerplate:
private final static int MY_CONSTANT = Properties.getInteger(
ThisClass.class, "MY_CONSTANT");
I don't think I want to use Spring or the like as that seems like even more boilerplae. I was hoping to use a custom annotation to solve the issue. I found this tutorial, but I can't really sort out how to get the functionality that I want out of the annotation processing. The Java docs were even less helpful. This should be a thing I should be able to do at compile time, though. I know the names of the class and field.
What I'm thinking is something like this:
#MyAnnotation
private static final int MY_CONSTANT;
Anyone know how I would go about doing this or at least best practices for what I want to do?
First of all, you shouldn't do it. It's practical, but too hacky and if you ever want to write a test using different settings, you'll run into problems. Moreover, nobody's gonna understand how it works.
An annotation processor can probably do nothing for you. A Lombok-style-hacking processor can. You want to make
#MyAnnotation
private static final int MY_CONSTANT;
work like
private final static int MY_CONSTANT =
Properties.getInteger(ThisClass.class, "MY_CONSTANT");
The original expression doesn't compile (due to the uninitialized final variable), but it parses fine and Lombok can do its job. There's already something related there:
#Value changes the modifiers to final private
#UtilityClass makes all fields static
So actually, you could write just
#MyAnnotation
int MY_CONSTANT;
and let your annotation change also the modifiers. I'd look at the eclipse and javac handlers for #UtilityClass, I guess all you need is to generate the initializer (which is quite some work because it's all damn complicated).
I don't think Lombok itself will implement this anytime soon, since
all the static stuff is non-testable and mostly bad style
and not everyone wants this in their code
it's not that much boilerplate
it also magically refers to the class Properties, but this could be solved via configuration
but I guess a contribution might be accepted.
Actually not quite clear why and what do you want to archive.
As I correctly undestand, you want use special kind of annotations to automatically assign values for static final constants from some properties file. Unfortunatelly it is impossible without special hacks. And annotations have nothing to do with this.
The reason is that final fields must be initialized and it is compiler's request. There aren't special annotations in java which will provide such syntactic sugar which you want.
But if you insist on this there are two ways:
Extrim way. Init all properties field with default value. Then using this hack in some static init section initialize this value using reflection mechanism and you code via reading values from properties.
Less extrim way: refuse request of final modifiers for properties fields, and using only reflection fill these fields values.
And additionally, for these ways, yes you can use annotations. But you will have to solve following technical issues:
1) Find all fields in all classes in classpath, which are annotated with you special annotation. Look at:
Get all of the Classes in the Classpath and Get list of fields with annotation, by using reflection
2) Force your Properties class to be initialized in all possible enter points of your application. In static section in this class you will load your properties file, and then using (1) method with reflection and classloader, assign values to all constants.

Initialize a "singleton" by configure file is suitable or not?

Initialize a singleton by configure file is suitable or not?
I notice that the constructor of singleton should not have any parameter, the reason is that if you need use parameters to configure your object, probably that should not be singleton. Seems this sentence very famous, but indeed there are serval cases are special:e.g.
We design a simple distributed system to deal with tons of users' query:
only one central server
n sub servers, each sub server connecting to central server
there is no connections between sub servers
Obviously, we may design the "central server" as singleton, the details like this:
enum ServerType;
abstract class Server;
class CentralServer inherit from Server;(CentralServer is singleton)
class SubServer inherit from Server;
class Query;
... ... ...
But the central server need some configuration, such as:
serverName
description
portNum-ipAddress map
the list of its sub servers
the size of BlockingQueue
... ... ...
How to initialize the central server by these properties?
My current solution:
using the configure file to finish this part job.
I define another class called Configuration.
So the current constructor of central server like this:
class CentralServer extends Server implements Runnable, ....... {
....
....
private static CentralServer _instance;
private CentralServer () {
super();
....
serverName = Configuration.getCentralServerName();
description = Configuration.getCentralServerDescription();
Configuration.initCentralServerPortNumIpMap(portNumIpMap);
Configuration.initCentralServerSubServersList(subServersList);
sizeBlockingQueue = Configuration.initCentralServerBlockingQueueSize();
....
}
public CentralServer getInstance() {
if (_instance == null) {
_instance = new CentralServer();
}
return _instance;
}
....
....
}
The Configuration class, will read and analyze configuration-file, to get out of configuration info.
My Question:
Initialize singleton like this suitable or not, if not, please
give out more suitable approach
I also need configure all sub servers, so seems the Configuration
class is too heavy, should I split the Big Configuration class into
two sub class? class CentralConfiguration, and class
SubConfiguration?
Unfortunately, your implementation for a Singelton is WRONG!! Simply because it is not thread safe.
public CentralServer getInstance() {
if (_instance == null) { // race condition possible here
_instance = new CentralServer();
}
return _instance;
}
Two threads might enter this critical section and evaluate _instance==null to true, and two different instances will be created.
You can simply instantiate your instance statically.
private final static CentralServer INSTANCE = new CentralServer();
public static CentralServer getInstance() {
return INSTANCE;
}
However, the best way to implement singeltons is to use enums
public enum CentralServer { // the best way to implement singletons, due to the author of Effective Java
INSTANCE;
private CentralServer() {
}
}
This gives you serialisation for free.
However, I dont think that you need a singelton at all, singeltons are usually Anti patterns.
Check this out.
In your code, CentralServer has a high dependency on Configuration which I don't think is a good thing, you should see Configuration as a dependency
class CentralServer{
private final Configuration serverConf;
private CentralServer(Configuration serverConf){ // inject configuration
this.serverConf = serverConf;
}
public static CentralServer createCentralServer(Configuration serverConf){ // static factory perhaps
return new CentralServer(serverConf);
}
}
This will give you more flexibility to change or mock configuration. I think Factory pattern would be more appropriate here.
It is perfectly acceptable to make use of external resources during the initialization of your singleton. A common user of the Singleton pattern is loggers and they are almost always configured from external data files.
It does make initialization more complicated but it is not impossible to make a fully tread-safe singleton that accesses external resources such as configuration files. They can even make use of other singletons such as connection pools if their configuration requires database access.
The other answers to this question correctly deal with the actual problems with your singleton initialization.
Initialize singleton like this suitable or not, if not, please give
out more suitable approach:
It is not a suitable approach, because the implementation is not threadsafe yet and it can be broken f.e. via reflection. You should consider reading Effective Java by Joshua Bloch on this topic.
Better would be to create an enum singleton, because this approach is more flexible for later changes, has threadsafe instanciating and is unbreakable.
EDIT: example .
I also need configure all sub servers, so seems the Configuration
class is too heavy, should I split the Big Configuration class into
two sub class? class CentralConfiguration, and class SubConfiguration?
For configuration purposes, there is usually a config.xml file or a config.properties file somewhere to read important preconfigurations. After creating an instance, you should extract the information from such a file and write out necessary changes when shutting down. But as always, many ways lead to rome.

How to deal with special "constant" instances of object when using DI

My project is heavily using dependency injection, and I'm being very careful to avoid service locator antipattern. All objects are structured using constructor injection that allow easily identifiable list of dependencies. Now I'm building an object, and it has a special "constant" instance, which is basically static/singleton (consider example of something like Integer.MinValue). So my initial reflex was to create a static field with a static "getter" method, which would create the instance of the object if it wasn't previously created. The object itself has dependencies however, so I'm confused on what's the best practice for instantiating this "special instance". I'm looking for recommendations on how to best structure code in this scenario, ideally without having to call upon the container for resolution of dependencies. Some code:
public class PressureUnit extends DataUnit {
private static PressureUnit standardAtmosphere;
public static PressureUnit StandardAtmosphere() {
if(standardAtmosphere == null){
standardAtmosphere = new PressureUnit(1013.25); // this line is what is bothering me as I need to resolve other dependencies (have to use new as it's a static method and can't be injected like everywhere else)
}
return standardAtmosphere;
}
#AssistedInject
public PressureUnit(ITimeProvider timeProvider, IUnitProvider unitProvider, #Assisted double value) {
this(timeProvider, unitProvider, value, PressureUnits.hPa);
}
...
}
I really don't see any problem in your code since you are not newing up dependencies here and there, now with that being said i can give some suggestions:
If you specifically want the container to call an existing static factory method, you can use StaticFactoryExtension.
Why don't you use a factory.
Consider refactoring you design and removing the static method if possible.

Categories

Resources