Giter VIP home page Giter VIP logo

Comments (14)

ron-murhammer avatar ron-murhammer commented on May 10, 2024

I've used spring, guice, and CDI in the past though they are all pretty full-featured and heavy. Dagger looks pretty simple and lightweight. I like the idea though I think it might be better to hold off on this for now. While DI has many benefits, it can also make the code harder to read and refactor. I also don't want to make too many changes all at once and a good portion of the code needs refactored to even take advantage of DI.

from triplea.

DanVanAtta avatar DanVanAtta commented on May 10, 2024

DI is a technique to break up components, which allows for testing and further refactor. I wouldn't shut the door on it since in some cases it may be necessary to allow us to refactor. But I'm not recommending we go full throttle and require DI be done everywhere

More the point is to ensure that there is agreement on a DI framework so we all don't all start adding in five different ones.

from triplea.

ron-murhammer avatar ron-murhammer commented on May 10, 2024

I think this falls into the same category as continuous builds in my mind as in its just not that high of a priority at this point based on what we would gain from it. If we were starting a green field project then I would definitely pick a DI framework to start as you immediately get benefits and can make sure its consistent across the code base.

Adding a DI framework into a sizeable code base that needs a lot of refactoring is much more difficult to get benefits and can end up leading to increased complexity initially. My concern is that we will implement it in only 1% of the code base and then it just ends up making that portion of the code base less consistent and harder to maintain.

I'm fine if we want to discuss which one we'd like to implement but would prefer to focus on a few things at a time and not make 100 different changes to a small percentage of the code base but rather prioritize the most important things and make sure to drive them to completion. In Agile, sort of the idea of swarming on the most important stories rather than adding lots of stories and none of them getting completed.

from triplea.

DanVanAtta avatar DanVanAtta commented on May 10, 2024

Okay, I think I see maybe where the priority disagreement is. Given the lack of DI in the code, having reviewed and tried to test some of it, I'm of the opinion that large stretches are not feasibly testable without some refactor, some of that being DI. Said in another way, to successfully refactor and test, we have to use DI in some locations (in reality we could spend hours and hours trying to test code that is pretty untestable, but it's more efficient often to carve off chunks methodically and do a combination of refactor and test). Said yet another way, DI can be an important way to make untestable code testable.

So given our shared view that test is a priority, I believe DI is also a priority because it'll help us test a lot of un-testable code in the system. We can always do DI by hand, the old fashioned way and create a lot of Factory objects, but using a DI system from get go will get us moving faster I think.

from triplea.

veqryn avatar veqryn commented on May 10, 2024

I've really only ever heard of systems like Spring being used in the context of large enterprise web systems, and web frameworks.
What does this buy us, and can you give me a simple example of it being used?

from triplea.

DanVanAtta avatar DanVanAtta commented on May 10, 2024

Spring does a lot of things. Dependency injection containers are useful for small projects as well, Spring has evolved over time to fill that role.

Dependency injection is a good design pattern to limit unnecessary coupling between classes. This improves class simplicity and often allows for easier testing.

Consider this code:

public class foo {
private boolean userPreferenceFlag;
public class foo() {
userPreferenceFlag =
UserPreferences.getInstance().getPreference();
}
}

This code is very hard test. If you do test it, then the test will be brittle since the scope of changes that would impact that test span both this class and also the getInstance() singleton guy. To boot, mocking or replacing that singleton might be impossible, so we could be stuck with having the singleton.

Dependency injection is also the "don't call us, we'll call you" principle.

You could change the code in this way to inject the dependency:

public class foo {
private boolean userPreferenceFlag;
public class foo( UserPreferenceParser userPreferences ) {
userPreferenceFlag = userPreferences.getPreference();
}
}

With the dependency injected this code has some improvements:

  1. we can mock the constructor parameter very easily
  2. we can control which instance we pass to this constructor when we create the class, gives it more flexibility rather than being locked down to one specific implementation. Meaning if we wanted to get user preferences in some other manner, with the singleton we'd probably end up duplicating the entire class so we could change the implementation

I could go on a bit more with some extra benefits, but DI gives you easier test and cleaner interfaces.

So, DI is a good thing, it really helps.

To get DI, you wind up with a lot of factory objects to create instances. Frameworks like Spring and Dagger automate this factory object stuff, so you get a more robust glue, less code to manage, and less coupling. The reduced coupling makes things easier to modify and test. Hence, it buys is quite a lot.

To use dagger, we simply drop in the one jar, then we use "@Inject" and "@provides" annotations. That is the 90% use-case, there is some additional complexity, but using the framework is simple, it improves our capability to do DI, and DI is good for improving code design to reduce complexity and allow testing.

from triplea.

veqryn avatar veqryn commented on May 10, 2024

I get (and previously knew of, and agreed with) the idea behind dependency injections for simple examples like your foo class example.
What I don't get are the dependency injection frameworks. Could you give more example of that, for dagger?

from triplea.

DanVanAtta avatar DanVanAtta commented on May 10, 2024

I don't know dagger so well, but on the spectrum of DI frameworks, it looks like it is the least weight and was recommended by the other tripleA developers.

In this example, It would be a matter of adding @injected and @provides annotations, so something like:

public class foo {
private boolean userPreferenceFlag;
@injected
public class foo( UserPreferenceParser userPreferences ) {
userPreferenceFlag = userPreferences.getPreference();
}
}

@provides
public class UserPreferenceParser {
}

Dagger is smart enough to create the objects for you, gives compile time checking, no XML configurations. The compile time checking is really attractive, means you can put an @injected tag in the wrong spot and not have something get injected. Looks like it can get slightly more complex, the dagger docs has handling those cases as perhaps not too bad: http://google.github.io/dagger/

from triplea.

DanVanAtta avatar DanVanAtta commented on May 10, 2024

two cents more, spring has similar annotations these days, "@component" and "@Autowired", but those are not checked at compile time AFAIK.

from triplea.

veqryn avatar veqryn commented on May 10, 2024

And then what happens after you add those annotations?

from triplea.

DanVanAtta avatar DanVanAtta commented on May 10, 2024

Dagger creates a dependency graph at compile time and ensures that it can be satisfied at runtime. @injected indicates a dependency, @provides indicates something that can satisfy dependencies. There is additional syntax in the case when type alone is not enough to figure out a dependency. DI also has the framework calling constructors for you, so the annotations would have classes get created and wired together automatically for you.

from triplea.

veqryn avatar veqryn commented on May 10, 2024

Ok, but how do you use these annotations?
You said we do not need factory classes, so what would it look like instead?
I feel like I am missing the final piece here, even if it is obvious to everyone else.....

from triplea.

DanVanAtta avatar DanVanAtta commented on May 10, 2024

Basically the instance that needs an objects get the @injected and the instance that gives the object gives the @provides. Looks like basically dagger will create and wire the classes together for you. So if you have a method marked as @provides and fits with an @injected labelled over a constructor, my understanding is that dagger would call the constructor for you, and it would call the method first too and take the value from that and pass it to the constructor. So basically whenever you are using a value that is marked with @injected, you're basically going through an auto-magic factory to get access to that value/object.

from triplea.

DanVanAtta avatar DanVanAtta commented on May 10, 2024

I'll need to play around with Dagger more to give a better description, I only have an overview of it right now. It does look like it fits the bill for what we want. Only thing remaining in this question is if anyone has objections of using this framework over others.

from triplea.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.