Inject Util Class with Google Guice vs static Methods? - java

I'm wondering if it is a good style to inject utility methods with google guice.
Let's say we have a Converter Utility Class:
public class UtilClass
{
public static Result convert(Source src)
{
//Do conversion
return result;
}
}
My idea is to use guice to inject this Utility as Singleton like this
#Singleton
public class UtilClass
{
public Result convert(Source src)
{
//Do conversion
return result;
}
}
Which way is recommended for an Application built with guice?

It depends on the nature of your convert() method.
If it's something
simple
deterministic (i.e. doesn't depend on additional parameters)
have no side effects
is unlikely to change
etc
you can keep it as a static utility method.
Otherwise it's a good candidate for dependecy injection (you can rename it to ConversionService to make it more clear).

First of all, what is your goal in injecting an instance of this utility class rather than continuing to use the static method you have? Functions with input and output and no side effects are often best as static methods. That said, maybe you want to be able to change what this method does for testing or some such. In that case, you'd generally want to have the class implement some interface that you use in client classes.
At any rate, if UtilClass is stateless I'd just inject it not as a singleton. Injecting a non-singleton is faster than injecting a singleton. Maybe if you're going to be storing the injected instance in lots of other classes, a singleton might make sense to save space.

Personally I typically try to not let the fact my application is wired using a dependency injection framework influence the design decisions I make for my classes etc. Good design practices should dictate that. In your case it would seem your utility class has no dependency on state therefore it seems a sensible candidate to remain as static.
Regardless of this, your utility class is not an implementation of any interface so the client code using it still has a tightly coupled dependency. With this it is difficult to see what is the benefit of using DI to inject the utility class at all, as opposed to just referencing the static class directly in your client code.

Related

Is it better to have multiple nested classes with the same dependency or one with a larger scope?

In my Spring boot app i'm creating a Factory for creating different objects with the same interface and dependency like below.
#Component
public class FarmFactory {
#Autowired
private FarmRepo farmRepo;
public IFarm create(FarmType type) {
if (type == type.APPLE) {
return new AppleFarm(farmRepo);
} else if (type == type.ANIMAL) {
return new AnimalFarm(farmRepo);
} else {
return new EmptyFarm(farmRepo);
}
}
}
I was wondering if it was better to limit the scope the FarmRepo dependency by instead injecting it into each subclass of farm (apple, animal, empty). Or if it was better to keep a single dependency in a higher scope of the Factory.
Alternatively the dependency FarmRepo could be passed into the create method with the type, but not sure what the rule of thumb is for dependency scope.
According to my experience, a good design can reduce if-else as much as possible. So I prefer to injecting it into each subclass in your case. Thus in future, you have more flexibility if the dependency also have subclass as well.
I suggest to create named beans of your real implementations (AppleFarm, AnimalFarm ..) and inject the FarmRepo. With you factory your real implementations won't be managed by Spring (no beans).
#Component("appleFarm")
#RequiredArgsConstructor <- this is a Lombok feature check it out
public class AppleFarm implements Farm {
private final FarmRepo repo;
...
}
I assume your IFarm implementations are model classes. It is not a good practise to have a repository inside a model. You should consider to move the creation of different IFarm implementations to the FarmRepo.
If IFarm implementations are some sort of service classes that governs business logic then you should let spring handle it injecting the FarmRepo instance to them. In that case you better consider having an abstract class rather than using IFarm, because FarmRepo is a common dependency among them.
There is nothing wrong in employing a simple factory method to instantiate the required runtime type, if that's required, it needs to be done somewhere, it helps you gain a valid design in terms of OCP (open close principle) preventing you to change bahaviour depending on type parameter, rather you make use of polymorphism.

Is it good practice to inject variables in a Utility class?

I have the below Utility class in Java.
public class Utils {
private static Properties commonProps;
private Utils() {}
private static setCommonProps(Properties commonProps) {
Utils.commonProps = commonProps;
}
public static boolean staticMethod1() {
commonProps.get("xyz");
}
public static void staticMethod2() {
}
}
And we initialize "commonProps" with the help of Spring function org.springframework.beans.factory.config.MethodInvokingFactoryBean.
Is there anything wrong in this design of code? Can this have any bad effects?
Is it a good practice to have such variable initialization for Utility classes?
NOTE: Here "Properties commonProps" is just a placeholder. Any common member that need to be used in this class which has to be injected during startup.
In general, dependency injection is a good thing as it leads to better designs that are easier to test. In your particular case, you have to look at what you are trying to achieve.
It appears that you are trying to provide a single point to access properties through and add some value over the standard Java Properties API. For example, by providing a getBoolean() equivalent.
With regards to the single point of access you'll need to consider threading issues. However, as long as you can guarantee that your utility class is configured before you use its static methods you should be okay.
With regards to extending the Properties API, you might be better served using one of the existing libraries rather than incurring the cost of writing and maintaining your own. For example, I've found Apache Commons Configuration to be quite good.
Do not not have any mutability in static fields. That is an anti-pattern. Also do not inject static fields using Spring. Doing these things will make your code unwieldily to work with, and very hard to test.
You already have the ability to use #Value to inject fields with properties within beans. Although this is not dynamic but you really shouldn't have dynamic properties (although it's possible IMO it's not a good idea). Think of properties as startup constants or something. They shouldn't change.

Java - correct way to delegate methods

My program gets information from an external source (can be a file, a database, or anything else I might decide upon in the future).
I want to define an interface with all my data needs, and classes that implement it (e.g. a class to get the data from a file, another for DB, etc...).
I want the rest of my project to not care where the data comes from, and not need to create any object to get the data, for example to call "DataSource.getSomething();"
For that I need DataSource to contain a variable of the type of the interface and initialize it with one of the concrete implementations, and expose all of its methods (that come from the interface) as static methods.
So, lets say the interface name is K, and the concrete implementations are A,B,C.
The way I do it today is:
public class DataSource {
private static K myVar = new B();
// For **every** method in K I do something like this:
public static String getSomething() {
return myVar.doSomething();
}
...
}
This is very bad since I need to copy all the methods of the interface and make them static just so I can delegate it to myVar, and many other obvious reasons.
What is the correct way to do it? (maybe there is a design pattern for it?)
**Note - since this will be the backbone of many many other projects and I will use these calls from thousands (if not tens of thousands) code lines, I insist on keeping it simple like "DataSource.getSomething();", I do not want anything like "DataSource.getInstance().getSomething();" **
Edit :
I was offered here to use DI framework like Guice, does this mean I will need to add the DI code in every entry point (i.e. "main" method) in all my projects, or there is a way to do it once for all projects?
The classes using your data source should access it via an interface, and the correct instance provided to the class at construction time.
So first of all make DataSource an interface:
public interface DataSource {
String getSomething();
}
Now a concrete implementation:
public class B implements DataSource {
public String getSomething() {
//read a file, call a database whatever..
}
}
And then your calling class looks like this:
public class MyThingThatNeedsData {
private DataSource ds;
public MyThingThatNeedsData(DataSource ds) {
this.ds = ds;
}
public doSomethingRequiringData() {
String something = ds.getSomething();
//do whatever with the data
}
}
Somewhere else in your code you can instantiate this class:
public class Program {
public static void main(String[] args) {
DataSource ds = new B(); //Here we've picked the concrete implementation
MyThingThatNeedsData thing = new MyThingThatNeedsData(ds); //And we pass it in
String result = thing.doSomethingThatRequiresData();
}
}
You can do the last step using a Dependency Injection framework like Spring or Guice if you want to get fancy.
Bonus points: In your unit tests you can provide a mock/stub implementation of DataSource instead and your client class will be none the wiser!
I want to focus in my answer one important aspect in your question; you wrote:
Note - I insist on keeping it simple like "DataSource.getSomething();", I do not want anything like "DataSource.getInstance().getSomething();"
Thing is: simplicity is not measured on number of characters. Simplicity comes out of good design; and good design comes out of following best practices.
In other words: if you think that DataSource.getSomething() is "easier" than something that uses (for example) dependency injection to "magically" provide you with an object that implements a certain interfaces; then: you are mistaken!
It is the other way round: those are separated concerns: one the one hand; you should declare such an interface that describes the functionality that need. On the other hand, you have client code that needs an object of that interface. That is all you should be focusing on. The step of "creating" that object; and making it available to your code might look more complicated than just calling a static method; but I guarantee you: following the answer from Paolo will make your product better.
It is sometimes easy to do the wrong thing!
EDIT: one pattern that I am using:
interface SomeFunc {
void foo();
}
class SomeFuncImpl implements SomeFunc {
...
}
enum SomeFuncProvider implements SomeFunc {
INSTANCE;
private final SomeFunc delegatee = new SomeFuncImpl();
#Override
void foo() { delegatee.foo(); }
This pattern allows you to write client code like
class Client {
private final SomeFunc func;
Client() { this(SomeFuncProvider.INSTANCE); }
Client(SomeFunc func) { this.func = func; }
Meaning:
There is a nice (singleton-correctway) of accessing an object giving you your functionality
The impl class is completely unit-testable
Client code uses dependency injection, and is therefore also fully unit-testable
My program gets information from an external source (can be a file, a database, or anything else I might decide upon in the future).
This is the thought behind patterns such as Data Access Object (short DAO) or the Repository pattern. The difference is blurry. Both are about abstracting away a data source behind a uniform interface. A common approach is having one DAO/Repository class per business- or database entity. It's up to you if you want them all to behave similarly (e.g. CRUD methods) or be specific with special queries and stuff. In Java EE the patterns are most often implemented using the Java Persistence API (short JPA).
For that I need DataSource to contain a variable of the type of the
interface and initialize it with one of the concrete implementations,
For this initialization you don't want to know or define the type in the using classes. This is where Inversion Of Control (short IOC) comes into play. A simple way to archieve this is putting all dependencies into constructor parameters, but this way you only move the problem one stage up. In Java context you'll often hear the term Context and Dependency Injection (short CDI) which is basically an implementation of the IOC idea. Specifically in Java EE there's the CDI package, which enables you to inject instances of classes based on their implemented interfaces. You basically do not call any constructors anymore when using CDI effectively. You only define your class' dependencies using annotations.
and expose all of its methods (that come from the interface)
This is a misconception. You do want it to expose the interface-defined method ONLY. All other public methods on the class are irrelevant and only meant for testing or in rare cases where you want to use specific behavior.
as static methods.
Having stateful classes with static method only is an antipattern. Since your data source classes must contain a reference to the underlying data source, they have a state. That said, the class needs a private field. This makes usage through static methods impossible. Additionally, static classes are very hard to test and do not behave nicely in multi-threaded environments.

Java: [Global method access] enum with a single instance vs on-demand object construction vs static

I want to create a class with few methods which can be used anywhere inside a package. I opted to use enum with a single instance after reading that it automatically provides safe instantiation, serialization and protection from instantiating outside the enum. I believe it is the most easy and safe way of creating a singleton. But my superior came back saying that it's dirty programming. Is it really? Do anyone know the disadvantages of using an enum instead of object construction and passing around references using a class? When are enums initialized?
public enum Myenum {
INSTANCE;
public void init(...) {..initialize local variables...}
public method1 (...) {...}
public method2 (...) {...}
}
vs
public class Myclass {
public Myclass(...) {...initialize local variables...}
public method1 (...) {...}
public method2 (...) {...}
}
vs
public class Myclass {
public static void init(...) {...initialize local variables...}
public static method1 (...) {...}
public static method2 (...) {...}
}
In my view the disadvantage of using the second method is that an object reference of Myclass is needed everywhere I need to use methods and synchronization issues while object construction. I am not really using the serialization benefit of enum in my case.
Does enum implicitly provide the benefit of dependency injection? (i.e. Can access Myenum's method1, method2 everywhere inside the package without worrying about instance creation)
One other feature of enum I needed was methods inside an enum cannot be overriden outside of it.
Am I missing some obvious disadvantage here?
An enum gives a semantic signal to other programmers that it's a type with a series of possible values that you could check against, for example, in a switch statement. However, there are a number of compelling reasons why enums can be seen as a better implementation of a singleton pattern than most other patterns people typically use in Java.
If you're positive you want to use a singleton pattern, then using an enum is probably okay. However, there are patterns that tend to be more flexible, unit testable, SOLID, etc. What if one day you decide that you don't actually want this to be a singleton anymore? What if you want it to be refreshable when certain changes are made in the database? Using any singleton pattern is going to lock you into a singleton representation and make it harder to make changes like this in the future.
A Factory pattern would be more flexible than a singleton, but the best pattern of all, in my opinion, would be to use dependency injection. You can singleton-bind your type to avoid the costs of reinstantiating it, but the type itself (and its consumers) need not be tied to a specific lifetime or pattern.
Check out Java Concurrency In Practice and it's static singleton pattern. It looks like this:
public class ResourceFactory {
private static class ResourceHolder {
public static Resource resource = new Resource();
}
public static Resource getResource() {
return ResourceHolder.resource;
}
}
It's safe due to how/when statics are initialized, probably for the same reasons the Enums singleton trick is safe.
In JCIP's example, it's returning a thing, but you can add all the static methods you want that use however many variables you want to initialize in the ResourceHolder. And there's no init() call required.
I found an answer here to why creating a globally accessible pattern is bad instead of passing around references.
Excerpt:
They are generally used as a global instance, why is that so bad? Because you hide the dependencies of your application in your code, instead of exposing them through the interfaces. Making something global to avoid passing it around is a code smell.
They violate the single responsibility principle: by virtue of the fact that they control their own creation and lifecycle.
They inherently cause code to be tightly coupled. This makes faking them out under test rather difficult in many cases.
They carry state around for the lifetime of the application. Another hit to testing since you can end up with a situation where tests need to be ordered which is a big no no for unit tests. Why? Because each unit test should be independent from the other.

Utility class in Spring application - should I use static methods or not?

Let's say I have a utility class DateUtil (see below). To use this method
a caller method uses DateUtils.getDateAsString(aDate). Would it be better to remove
the static modifier and make DateUtil a spring bean (see DateUtilsBean) and inject it into calling classes
or just leave it as is?
One disadvantage I can see with using static is issues around mocking, see How to mock with static methods?
public class DateUtils {
public static String getDateAsString(Date date) {
String retValue = "" // do something here using date parameter
return retValue;
}
}
Spring Bean version
#Component
public class DateUtilsBean {
public String getDateAsString(Date date) {
String retValue = "" // do something here using date parameter
return retValue;
}
}
I don't think so. A DateUtils class sounds like a pure utility class that doesn't have any side effects but just processes input parameters. That kind of functionality may as well remain in a static method. I don't think it's very likely that you'll want to mock date helper methods.
I agree with Sean Patrick Floyd.
This is my criterion: if the methods of the class do things only over the parameters they receive, with no external dependencies (database, file system, user config, other objects/beans, etc.), then I would do it with static methods, usually in a final class with a private constructor.
Otherwise, I would implement it using a Spring bean.
So, in the case that you raise, according to this criterion, I would write a class with static methods.
Regards.
It would be better to declare it as a Spring bean because the life cycle of it is then managed by Spring, and you can eventually inject dependencies, pool the object, as well as test it in a proper way, not to talk that you could use it as a regular object and pass it as parameter, redefine the method in subclasses... etc.
In short, yes it would be a better design in most cases. Nevertheless, in a case as simple as the exposed, it doesn't do a great difference.
A good answer in this comment Should I use static at all in spring singleton beans
static variable has one instance in one JVM. Singleton exists per spring context. If your application has only one context, they do the same job.
But do not mix them together. In some old projects, I see some not-pure utility class using some spring bean via ApplicationContext. It is very hard to write test case for it.

Categories

Resources