Which dependency should locate in a method signature as a param and which should not? Since we have IoC container like spring, most of the dependencies could get injected through it.
For java.util.concurrent.Executor:
public interface Executor {
void execute(Runnable command);
}
The interface could be
public interface Executor {
void execute();
}
Another case, in a traditional web application, a counter may be written like this
public interface CounterManager {
int query(User user);//user is a runtime information
}
Since spring offers request scope, User could be injected either.
public interface Counter {
int query();//get user through Injected
}
Is there some principle or best practice to make the choice? Thanks!
Is there some principle or best practice to make the choice? Thanks!
You can use "Coding complexity rule" as a guidance. Everything that lowers code complexity in both short-term and a long-term way is good. Everything that raises it is bad.
If you start injecting everything with a use of DI container, you will end up with a DI settings file of Merriam-Webster Dictionary in size.
If something is so plain simple, that can be just passed as a parameter to a method, why to complicate things with a DI container?
Related
Studying about dependency injection I found some approaches that suggests to inject everything and other saying that it's not necessary to do so.
In my current project, my rule of thumb regarding Dependency Injection is "if the class was created by me, I make it injectable". In other words only classes like SimpleDateFormat, ArrayList, HashMap are newables in my project. My intent doing this approach is that I can #Inject any class anywhere once calling Injector.getApplicationComponent().inject(this) in the Activity. Basically all my classes have a non-args constructor with #Inject.
I was primary using DI because I thought it will improve the performance and memory usage once the new operator is used exclusively by the Dagger generated classes. But I read a post from Dagger 1 developer saying that DI does not have impact on performance and the usage is basically to reduce boilerplate.
The first question is:
Dagger 2 does not any performance advantage in Android application?
My project is running without problems and I think the approach of "inject everything" helps organizing better, despite some drawbacks.
An example of usage of this approach is the following class:
public class TimelineEntryAdapter {
#Inject
Provider<TwitterEntry> mTwitterProvider;
#Inject
Provider<InstagramEntry> mInstagramProvider;
#Inject
Provider<FacebookEntry> mFacebookProvider;
#Inject
TimelineEntryComparator mComparator;
#Inject
public TimelineEntryAdapter() {
}
The second question is:
Is it a bad practice to inject everything in Android?
If the answer for the second question is "No", there is a better way to handle the non-args constructor to create classes? Because when I create an non-args constructor with #Inject annotation and a class need some parameters to work with, I must use setters:
public class SavelArtist {
private MusicBrainzArtist mMusicBrainzArtist;
private DiscogsArtist mDiscogsArtist;
private List<SavelTweet> mTweetList;
private SpotifyArtist mSpotifyArtist;
private List<SavelInstagram> mInstaTimeline;
private List<SavelFacebook> mFacebookTimeline;
private List<SavelRelease> mReleases;
#Inject
Provider<SavelRelease> mReleaseProvider;
#Inject
public SavelArtist() {
}
public void setMusicBrainzArtist(MusicBrainzArtist mbArtist) {
mMusicBrainzArtist = mbArtist;
}
public void setDiscogsArtist(DiscogsArtist discogsArtist) {
mDiscogsArtist = discogsArtist;
}
public void setTweetList(List<SavelTweet> tweetList) {
mTweetList = tweetList;
}
public void setSpotifyArtist(SpotifyArtist spotifyArtist) {
mSpotifyArtist = spotifyArtist;
}
public void setInstaTimeline(List<SavelInstagram> instaTimeline) {
mInstaTimeline = instaTimeline;
}
public void setFacebookTimeline(List<SavelFacebook> fbTimeline) {
mFacebookTimeline = fbTimeline;
}
All the parameters could be set on the constructor, once all are get at the same time in the flow.
Studying about dependency injection I found some approaches that suggests to inject everything and other saying that it's not necessary to do so.
The froger_mcs blog entry you quote doesn't advocate injecting everything. It quite clearly states:
The purpose of this post is to show what we can do, not what we should do.
And it goes on to state a disadvantage of injecting everything:
If you want to use Dagger 2 for almost everything in your project you will quickly see that big piece of 64k methods count limit is used by generated code for injections.
Now, on to your questions:
Dagger 2 does not any performance advantage in Android application?
While Dagger 2 offers a performance advantage over other reflection-based DI frameworks (such as Guice) it doesn't claim to offer any performance advantage over manually constructing your object graphs by calling constructors. You can inspect the generated classes yourself to see that these indeed still eventually call constructors.
Is it a bad practice to inject everything in Android?
Well let's take the following very common Android code:
Intent nextActivity = new Intent(this, NextActivity.class);
startActivity(nextActivity);
Should we extract an IntentFactory and inject this using Dagger 2 merely to avoid the new keyword here? At this point, it is easy to approach pedantry. The advice in the other answer you quoted about the difference between injectables and newables is more flexible and elegant.
Moving on to your next question:
If the answer for the second question is "No", there is a better way to handle the non-args constructor to create classes? Because when I create an non-args constructor with #Inject annotation and a class need some parameters to work with, I must use setters:
Using setters is the wrong approach for parameters. You should distinguish dependencies and parameters. Dependencies normally have the same lifecycle as the object itself. During the lifetime of the object, the methods exposed for that object may be called with different parameters.
I'm not a professional at dependency-management but I use it in my company so here's how I see it.
Inject everything is basically good. I make everything that is used somewhere else ( other modules, classes, packages ) injectable and only static things ( static classes with hidden constructor ), things that get only used internally non injectable.
What's the advantage of it?
Well The dependency system will take care of getting the instance and to discard it. It will clean up automatically. Also using scopes on the classes will enable you to make a class that always has only one instance in the whole application ( multiple threads access it) or make it reusable ( every thread that needs it get's an own instance ).
Also I think you could clean up your classes like this:
#Reusable (Maybe a good Idea?)
public class SavelArtist {
private MusicBrainzArtist mMusicBrainzArtist;
private DiscogsArtist mDiscogsArtist;
private List<SavelTweet> mTweetList;
private SpotifyArtist mSpotifyArtist;
private List<SavelInstagram> mInstaTimeline;
private List<SavelFacebook> mFacebookTimeline;
private List<SavelRelease> mReleases;
private Provider<SavelRelease> mReleaseProvider;
public SavelArtist() {
}
#Inject
public void init(Provider<SavelRelease> mReleaseProvider) {
this.mReleaseProvider = mReleaseProvider;
}
Think about always declaring the scope of the class. Is it a Singleton? Will it be reusable? This little detail can save you, once the application get's complex and big.
The advantage of using the method init to declare all injected variables is to have a clean looking code which is easy maintainable since everything injected is at this one location. But that's actually preference :)
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.
So, this is a pretty high-level question, addressing how I've been doing things for years. I know my approach can be improved, and I'm looking for a (or "the") correct / better way to generate factories.
For quite a while now, my brain has been stuck writing singleton factories. Here's the basic pseudo code of a factory:
public Factory {
private static final INSTANCE = new Factory();
private Factory () {}
public static Factory instance() {
return INSTANCE;
}
public Object createStuff() {
// impl specific factory details here
return null;
}
}
Now, this approach allows me to be really lazy elsewhere in the code, not having to maintain instances of factories everywhere. I've recently stepped up my unit testing game though, and have run into problems mocking off the factories for testing purposes, which led me to question my approach.
I've heard dependency injection might be a good way to go, and I'm willing to investigate it. Some of my current projects are already too far down the road to adjust and introduce new approaches (so, no dependency injection in existing stuff).
So, bottom line: what's a better way to do this, both with and without dependency injection?
Thanks!
Rob
in order to use DI and to have your classes which depend on your factories be testable you need to make your factories implement an interface, then have the classes which use the factories require an instance of the factory in the constructor of those classes. This will then let you test those classes by providing a stub or mock factory which also implments the interface.
Something like this
public interface IFactory
{
object createInstance;
}
public class ClassWithDependencyOnFactory
{
private IFactory factory;
public ClassWithDependencyOnFactory(IFactory factory)
{
this.factory = factory;
}
public void DoSomething()
{
var thing = factory.createInstance();
...
}
}
do not assume that you need to use a IoC framework (like Spring) in order to do DI or to get the benefits of the decoupling that it brings.
Have you heart about Spring (with Spring Boot)?
It starting to be de-facto standard for lightweight Java applications.
It can significantly amount of code you need to developer full-reatured production application.
I would like to start off by mentioning that my problem stems from the fact that interfaces in Java do not allow static methods. There have been discussions about the reason for this on SO (here , for example). So lets not dwell on that. I am looking for a way for my interface to create an instance of itself (rather, its implementation) and return that. In spite of playing around with Singleton pattern, Factory and AbstractFactory patterns, I still cannot achieve my goal.
To elaborate on what I'm trying - here's my interface:
public interface NoteDataStore {
public boolean deleteNote(long noteId);
public boolean addNote(Note note);
public List<Note> listNotes();
public boolean editNote(long noteId, Note note);
public List<Note> search(String searchString);
}
And here's my business logic layer:
public class BusinessLogicLayer {
public BusinessLogicLayer(){
/*
* GOAL: To get an instance of NoteDataStore here,
* without being aware of the implementation class.
*/
}
}
I tried to use a factory pattern like so:
public interface NoteDataStoreFactory {
public NoteDataStore getDataStoreInstance();
}
public class NoteDataStoreFactoryImpl implements NoteDataStoreFactory{
public NoteDataStore getDataStoreInstance(){
return NoteDataStoreImpl.getInstance();
/*
* Here, NoteDataStoreImpl is an implementation of NoteDataStore.
* This should be transparent to my business logic layer.
*/
}
}
However, this still requires the Business Logic layer to know the implementation class NoteDataStoreFactoryImpl thus:
NoteDataStore = new NoteDataStoreFactoryImpl().getDataStoreInstance();
How do I get around this? How do I keep my BusinessLogicLayer in the dark regarding the exact implementation class to use?
EDIT: More Detailed Background of my problem
A few of the answers suggest the use of frameworks like Spring. Alas, I cannot do so because this application targets various mobile platforms (Android, Blackberry, JavaME). I should have made this clear in my original question - apologies for not doing so.
My main intention is to have an app across platforms. The UI, database access, HTTP transport layers etc will have to be coded specifically for each platform. However, the business logic is simple enough to warrant a common layer across all platforms. I intend to distribute the business logic layer as a JAR library. So also, the parsing and framing layer (for JSON/XML).
There has already been a discussion about this at SO (on whether I should even be going down this path) - Logic Code reuse. However, assuming this is OK and that I proceed with the layered approach and the intention to have one layer common in code. Now, my situation is such that I have:
A common Business Logic Layer.
Platform-specific data layer (represented by the NoteDataStore interface)
Platform-specific Application core layer (Controller, if I may call it so).
Note that if I use the Factory pattern or other such, I can afford to have that layer specific to each platform. So, the factory method/class itself can know about the NoteDataStore implementation class. However, the Business Logic Layer must be unaware of any of the implementation classes.
A typical use of the various layers would be as follows:
public class NoteDataStoreAndroid implements NoteDataStore{
public boolean deleteNote(long noteId){
/*
* Android-specific database code
*/
}
/* ... similarly, other methods */
}
public class AndroidCoreApp{
public void doBusinessLogic(){
BusinessLogicLayer businessLogic = new BusinessLogicLayer();
businessLogic.startBusinessLogic();
}
}
Any inputs on how to handle this scenario?
Your class should accept factory instance from the outside. When you're creating instance yourself - you achieve nothing, you are correct here.
There are several techniques here. In general they belong to something very general called Inversion of Control or IoC for short. Also it is useful to know about 'Inversion of Control Containers' or IoCC. Java has Spring for example - read here. You should ask real Java guys about others :)
Also take a look at this article.
If you want to return an implementation you could do so with an anonymous inner class
NoteDataStore myImplementation = new NoteDataStore (){
//Implement methods here
};
Have you looked at IoC/Dependency Injection frameworks like Guice and Spring? They may be too heavyweight for what you are looking for, but they definitely solve the problem you describe. They allow all of your business layer code to be written against interfaces, and the actual implementations to be defined via the IoC framework. I'm personally a huge fan of Spring and have used it in nearly every Java app I've written in the past 6+ years.
I finally went for the suggestion provided by #Ray Tayek in a comment to the original question. I simply pass in an instance of the NoteDataStore at the time of creating the BusinessLogicLayer.
This simple solution suits my needs pretty well since I do not really require a Factory. My main objective was for the BL Layer to be unaware of the exact implementation classes of the interfaces it uses. Now, instead of a Factory, it is the core "Controller" layer that creates a concrete implementation of the interfaces and supplies them to the BL Layer. This is just perfect!
Here is the code snippet.
public class NoteDataStoreAndroid implements NoteDataStore{
public boolean deleteNote(long noteId){
/*
* Android-specific database code
*/
}
/* ... similarly, other methods */
}
public class AndroidCoreApp{
public void doBusinessLogic(){
BusinessLogicLayer businessLogic = new BusinessLogicLayer(new NoteDataStoreAndroid());
businessLogic.startBusinessLogic();
}
}
public class BusinessLogicLayer {
private NoteDataStore mDataStore;
public BusinessLogicLayer(NoteDataStore dataStore){
this.mDataStore = dataStore;
//Do something useful with mDataStore
}
public void startBusinessLogic(){
//Do something useful with mDataStore
}
}
Suggest you use ID frameworks, like Guice and others. Not simply use Factory Pattern.
I've never written an annotation in Java.
I've got a simple Java class for performance measurement. I call it PerfLog. Here's an example of its use:
public class MyClassToTest {
public String MyMethod() {
PerfLog p = new PerfLog("MyClassToTest", "MyMethod");
try {
// All the code that I want to time.
return whatever;
} finally {
p.stop();
}
}
}
When p.stop() is called, a line will be written to the log file:
2010/10/29T14:30:00.00 MyClassToTest MyMethod elapsed time: 00:00:00.0105
Can PerfLog be rewritten as an Annotation so that I can write this instead?
public class MyClassToTest {
#PerfLog
public String MyMethod() {
// All the code I want to time.
return whatever;
}
}
It would seem to be a good candidate for annotating: It's easy to add or take away the annotation; a production build can leave out PerfLog entirely without having to remove the annotations from the source code; the annotation processor can get the class and method names.
Is this easy to do? Is there a recipe somethere that I can follow?
It has to be Java 5 so I know I have to use apt somewhere.
There is no trivial way to do this using standard Java tools. The path of least resistance would almost certainly be to use an AOP-style library like Google Guice or Spring or AspectJ. Any home-grown attempt to solve this problem will essentially end up doing what AOP libraries would already do for you.
Consider using AOP or Spring - supports Annotations to intercept method invocations and implement custom code
In case that sounds interesting, the Spring AOP docs are here : http://static.springsource.org/spring/docs/2.5.x/reference/aop.html
You can definitely write the annotation parser and its runtime implementation on your own, but reinventing will only be error prone and inefficient when compared to industry solutions.
If you insist on implementing this on your own (without AOP or AOP with Spring), here is what I can suggest (may not be the bestest method) :
Create your beans via a custom FactoryBean always.
In the custom FactoryBean implementation, query the class for methods and check if they are annotated.
If yes, instead of returning the instance of the class itself, return a proxy over the instance.
In the invoke of this proxy, wrap the call to the actual instance's method with new PerfLog() and p.stop()
Its effectively what AOP would (more powerfully) do for you. However, take note that final classes, static methods, classes with no interfaces etc.. will still be a problem in this case (a different ball game).