If I follow dependency injection principle for a class design, I should make sure my class does not try to instantiate its dependencies within my class, but rather ask for the object through the constructor.
This way I am in control of the dependencies I provide for the class while unit-testing it. This I understand.
But what I am not sure is does this mean that a good class design which follows dependency injection principle means that its fields should never be initialized inline? Should we totally avoid inline initialization to produce testable code?
EDIT
Which is better 1 or 2?
1
public class Car {
private Tire tire = new Tire(); //
}
2
public class Car {
private Tire tire;
public Car(Tire tire) {
this.tire = tire
}
}
No, it surely doesn't mean inline initialization.
I'm not a Java user but this term is relevant to many programming languages.
Basically, instead of having your objects creating a dependency or asking a factory object to make one for them, you pass the needed dependencies into the object externally, and you make it somebody else's problem.
public SomeClass() {
myObject = Factory.getObject();
}
"Dependency Injection" is a 25-dollar term for a 5-cent concept. [...]
Dependency injection means giving an object its instance variables.
[...].
Dependency injection is basically providing the objects that an object needs (its dependencies) instead of having it construct them itself. It's a very useful technique for testing since it allows dependencies to be mocked or stubbed out.
Any application is composed of many objects that collaborate with each other to perform some useful stuff. Traditionally each object is responsible for obtaining its own references to the dependent objects (dependencies) it collaborates with. This leads to highly coupled classes and hard-to-test code.
A lot of reference from here
In my opinion, In general, if you think that the data field is a dependency, then let the dependency management container should manage it. What counts a dependency and what is not dependency is a tough question, and only you can decide.
For example: if your design of car allows working with different types of Tyres, then it's a dependency. Otherwise, inside a class Car you'll have to work with some kind of TyreFactory, which is not really reasonable.
If you work with DI container, testing the class will be a breeze. You'll have to provide a stub/mock to the class which is obviously a real benefit. So, in your example, if you go with the first solution then, how will you test that your car works with different types of Tyres?
Related
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.
Hi I have a very simple dagger questions for android.
class Fooz {
#Inject Foo1 mFoo1;
public Fooz() {
....
}
}
class Fooz {
private Foo1 mFoo1;
#Inject public Fooz(Foo1 foo1) {
mFoo1 = foo1;
}
}
How are the two classes identical?
The first one injects Foo1 field directly while the second one assignes mFoo1 in the constructor.
For the second one, does Foo1 get injected from object graph as soon as Fooz is created and added to object graph?
If they are different, why so?
Thanks!
Constructor injection gives you more control over the object instantiation since using field injections means to restrict your class creation to reflection and rely on support to these particular injection annotations. Besides that, having the dependencies clearly on the constructor let the code easier to maintain and to test.
As far as I know, there is no difference regarding the way it is held on the dagger graph but a constructor call is always faster than injected fields.
In my opinion, we should use property only when we do not have control over the object creation, as in Activities and Fragments, per example.
These classes will behave the same when Fooz will be Injected using dependency injection. However they will behave differently when constructed using Constructor's you defined.
Example 1. Calling new Fooz() will result in mFoo1 being null.
Example 2. Calling new Fooz(foo1) will result in mFoo1 being initialized to foo1.
The preferred (personal opinion) way is to use dependency injection annotation on constructor, because it will avoid null pointer exceptions, as explained when comparing example 1 and example 2. What is more such constructor gives more flexibility when testing your classes as you can provide mocks, much easier.
These is sonarqube rule with better description, explaining what I mentioned https://sonarcloud.io/coding_rules?open=squid%3AS3306&rule_key=squid%3AS3306 .
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 :)
I've seen a class declared with its only constructor being annotated with #Inject.
And I don't see the one constructor being called anywhere in the entire project.
So two questions:
<1> What does #Inject mean? (What does it do? Why is the constructor being annotated with it?)
<2> As mentioned, the constructor never gets called directly, does that have anything to do with the fact that it is annotated with #Inject?
Google Guice is a dependency injection library that allows you to construct objects simply by declaring relationships between them. Objects are constructed as they are demanded to construct other objects. You can also implement abstract classes or interfaces with different implementations by configuring Guice, which makes it very useful for running or testing your code.
#Inject annotates constructors and methods that determine what an object needs to be initialized. There are also a lot of other annotations that determine how Guice works. But simply annotating objects isn't enough; you also have to configure them with Guice bindings.
Here's a really simple example (from one of my applications). I have a MySQLDataTracker that requires a MysqlConnectionPoolDataSource:
public class MySQLDataTracker extends ExperimentDataTracker {
#Inject
public MySQLDataTracker(MysqlConnectionPoolDataSource ds) {
....
}
}
Note that MySQLDataTracker extends ExperimentDataTracker, an abstract class that can be implemented several ways. In my Guice bindings I declare that
bind(ExperimentDataTracker.class).to(MySQLDataTracker.class);
This declares that whenever I want an ExperimentDataTracker, a MySQLDataTracker will be constructed. I also need to make sure that the requisite object for constructing this is available, so I declare a provider:
#Provides #Singleton
MysqlConnectionPoolDataSource getMysqlCPDS() {
return (some thingy I construct...);
}
This says that there should only be a single connection pool data source. It also means that when I try to get an instance of ExperimentDataTracker, Guice has everything it needs to construct it. If I didn't have the above, it would throw an error.
ExperimentDataTracker tracker = injector.getInstance(ExperimentDataTracker.class);
However, it doesn't stop here. Other things depend on the ExperimentDataTracker, so it's used in turn to inject other objects. At the top level of my code there is actually only one call to getInstance, which makes Guice construct pretty much everything. I don't have to write the new statement anywhere.
I'm a big fan of Guice after seeing how it reduced the need for me to initialize a bunch of objects in order to initialize other objects. Basically I just ask for the object I want, and poof! it appears.
In Java, given the following class:
public class MyClass {
private final Dependency dependency;
public MyClass(Dependency dependency)
{
this.dependency = dependency;
}
public void doWork()
{
// validate dependency...
}
The doWork method needs to invoke a method that uses dependency.
Which of the following two variations is considered "best practice", and why?
// Access dependency directly
void validateDependency()
{
this.dependency.something();
}
// access dependency as passed to the method
void validateDependency(Dependency dependency)
{
dependency.something();
}
I find myself favouring the latter, passing the dependency directly to the method, as it makes the method easier to test in isolation (albeit, marginally).
However, I'm interested in the java convention / best practice here.
A class exists because you have state and operations that are coupled to that state. There's no good reason to pass part of that state as a parameter to a class method.
In fact, it would indicate to me that that piece of state should not actually belong to the class. Or that the method doesn't belong to the class.
Using a parameter "so that it's easier to unit test" is a good indication that the latter holds (the method should not be in the class).
Well, in your example you are asking the function to do something with Dependency which lends itself to a static function, not a member function.
My rule of thumb is: Use members directly when calling a method on an object that owns the member but pass references when doing/testing something directly related to the dependency and favor static methods for the latter
That a bit verbose but I hope it helps. As always try to "do the right thing" and differences this small won't likely make a huge impact on maintenance or readability of your code.
There isnt a right way to do it. I prefer just putting the variable there.
Dependency injection. The second option is "best".
If you make your "Dependency" class an interface it makes code more modular, easier to test, less coupled.