I have been wondering if anyone uses DI/IoC in any non-toy project, where he can choose the implementation style (rather than this being enforced by libraries or development requirements).
After all, a Factory is just the perfect mechanism if we want a single instance of a class, and a Directory service is the perfect mechanism if we want a specific instance.
So what is the big deal with adding Spring/Guice/etc. into this and creating another dependency for ourselves? (Or maybe I completely fail to understand their DI approach...)
Thanks.
DI (Dependency Inversion) principle says nothing about frameworks and simply claims that:
High-level modules should not depend on low-level modules. Both should depend on abstractions.
Abstractions should not depend on details. Details should depend on abstractions.
Inversion of control (IoC) principle is also related to decreasing coupling among classes in your software.
There are many patterns that are used to keep your classes low coupled and follow DI or IoC principle. It is you responsibility how to meet this goal. Inversion of Control Containers and the Dependency Injection pattern are some of them.
After all, a Factory is just the perfect mechanism if we want a single instance of a class, and a Directory service is the perfect mechanism if we want a specific instance.
And Factory is considered as one of the implementation techniques of inversion of comtrol principle.
I have been wondering if anyone uses DI/IoC in any non-toy project, where he can choose the implementation style (rather than this being enforced by libraries or development requirements).
I see lots of enterprise applications where DI\IoC containers\frameworks are used. These frameworks provide an infrastructure that cares about object creation (like Factory), its lifetime (like Singleton), injecting dependencies, holding a list of all objects (like Registry)
So what is the big deal with adding Spring/Guice/etc. into this and creating another dependency for ourselves?
Your classes have no dependencies on any IoC container when you use it. IoC container is a part of your infrastucture layer only.
I think, the only one reason to avoid usage of IoC container is when you are restricted to use 3rd party libraries by company's rules and agreements.
Related
Which kind of design pattern speaks for and which against having an interface on every Service in Spring / SpringBoot?
Or does it only make sense to use Interfaces for services if at least you use two different implementations for a given interface.
What is the advantage to use an interface if you only have always one implementation in your code base.
I can answer your question with: it depends.
If you think about the SOLID principles, especially the Interface Seggregation, and its importance in object-oriented design:
Within object-oriented design, interfaces provide layers of abstraction that simplify code and create a barrier preventing coupling to dependencies.
The interfaces are using to expose the API contracts without exposing their implementation.
But, as I said before, it depends on the use case.
Let's say you're building a library/framework where it can expose multiple implementations for the same interface or allow the users to add their implementations. Then you surely should have interfaces.
On the other hand, it can also lead to some overengineering where your interface has only one implementation, you are sure it won't have more than one implementation, and it won't be used outside of your application. Then maybe you could skip it.
So, from my point of view, it depends.
I've been an AEM developer for almost a year now. I know AEM uses 'Declarative Services component framework' to manage life cycle of OSGi components.
Consider a scenario when i would export a package from a bundle and import that package from another bundle, i could create objects of classes in first bundle inside second bundle as well. it's a import-export contract in this case.
my question is when i should be using component framework to manage the lifecycle of my objects and when to handle it myself by creating them when required.
In an ideal design, you would NOT in fact be able to create objects from the exported package; because that package would contain only interfaces. This makes it a "pure" contract (API) export. If there are classes in there that you can directly instantiate, then they are implementation classes.
In general it is far better to export only pure APIs and to keep implementation classes hidden. There are two main reasons:
Implementation classes tend to have downstream dependencies. If you depend directly from implementation class to implementation class then you get a very large and fragile dependency graph... and eventually that graph will contain a cycle. In fact it's almost inevitable that it will. At that point, your application is not modular because you cannot deploy or change any part of it independently.
Pure interfaces can be analysed for compatibility between versions. As a consumer or a provider of an API, you know exactly which versions of the API you can support because the API does not contain executable code. However if you have a dependency onto an implementation class, then you never really know when they break compatibility because the breakage could happen deep down in executable code that you can't easily analyse.
If your objects are services then there's no question, they have to be OSGi components.
For other things, my first choice is OSGi components, unless they're trivial objects like data holders or something similar.
If an object requires configuration or refers to OSGi services then it's also clearly an OSGi component.
In general, it's best IMO to think in services and define your package exports as the minimum that allows other bundles to use a bundle's services. Unless a bundle is clearly a reusable library like commons-io (to take a simple example).
What does mean Inversion of Control and Dependency Injection in Spring Framework? and what is difference ? Why in the Spring framework ?
Can any one explain ?
Also suggest the some books to learn Spring framework for beginners ?
I shall write down my simple understanding of this two terms:
For quick understanding just read examples*
Dependency Injection(DI):
Dependency injection generally means passing a dependent object as a parameter to a method, rather than having the method create the dependent object. What it means in practice is that the method does not have a direct dependency on a particular implementation; any implementation that meets the requirements can be passed as a parameter.
With this objects tell thier dependencies.
And spring makes it available. This leads to loosely coupled application development.
Quick Example:EMPLOYEE OBJECT WHEN CREATED,IT WILL AUTOMATICALLY CREATE ADDRESS OBJECT (if address is defines as dependency by Employee object).
Inversion of Control(IoC) Container:
This is common characteristic of frameworks,
IOC manages java objects – from instantiation to destruction through its BeanFactory. -Java components that are instantiated by the IoC container are called beans, and the IoC container manages a bean's scope, lifecycle events, and any AOP features for which it has been configured and coded.
QUICK EXAMPLE:Inversion of Control is about getting freedom, more flexibility, and less dependency. When you are using a desktop computer, you are slaved (or say, controlled). You have to sit before a screen and look at it. Using keyboard to type and using mouse to navigate. And a bad written software can slave you even more. If you replaced your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of computer controlling it.
By implementing Inversion of Control, a software/object consumer get more controls/options over the software/objects, instead of being controlled or having less options.
Inversion of control as a design guideline serves the following purposes:
There is a decoupling of the execution of a certain task from implementation.
Every module can focus on what it is designed for.
Modules make no assumptions about what other systems do but rely on their contracts.
Replacing modules has no side effect on other modules I will keep things abstract here, You can visit following links for detail understanding of the topic.
A good read with example
Detailed explanation
As far as I understand, main purpose of dependency injection is to have all dependencies separated declaratively, so that we can easily review and change the dependency structure easily...right?
Then by using dependency annotations spread through out the code, aren't we just going back to non-centralized system (similar to simple new operator), which is harder to tweak?
#Autowired/#Inject annotations usually declare dependencies on interfaces rather than on concrete classes (as in the case of new), thus you still can control which implementations should be injected by controlling which beans are declared in the context. Also, these dependencies can be overriden manually.
#Component-family annotations can be controlled as well, since you can exclude particular classes from component scanning.
The purpose of dependency injection is to decouple the declaration of dependencies from the actual satisfying of those dependencies. How the declaration is done is an orthogonal issue.
#Autowired is a form of dependency declaration. Using #Autowired supports encapsulation. A class' injected dependencies are documented directly in the code instead of in another file.
These types of discussions have tendency to become religious so I'll stear clear of the "main purpose" definition and the semantics of whether this or that pattern is really and truly fulfilled.
I try to look at it like a tool that can offer certain features. For instance, using Spring (DI) is a good way to separate interfaces and implementations. Users of a particular interface need not know how to create the implementation (or where it resides). This is often something good. Using Spring also enables a whole lot of other stuff: AOP and AOP-driven features like transaction handling, scopeing and a whole bunch of pre-built integrations to other frameworks and technologies. Annotations make a lot of this easier and clearer and best of all, I don't have to use them where it's not practical or possible - there is always the option to configure it in XML instead.
Is inversion of control essentially just retrieving a set of already instantiated objects? In theory. I guess more granular details as implemented by IoC frameworks like Spring have a lot more functionality, but in theory it seems like IoC containers operate like a collection of instantiated beans (in the Java world) and then you get access to those beans. Almost like you would with a collection Singleton objects?
It's partly getting hold of singletons in practice, yes. Some beans will be instantiated multiple times, whenever they're needed (depending on the configuration), but often you can make do with single instances - particularly if they're stateless once configured. I like the idea of data flowing "through" an application's plumbing after it's been properly hooked up.
The benefit is that the "singletoneity" is only present in the configuration, not in the code, which makes the system more testable and flexible. The difference in terms of how you view (and expose) the dependencies with your app is huge.
Although the answer has already been accepted, I will elaborate a little more:
Initially spring was mostly about singleton management. with the introduction of custom scopes came the web specific scopes and the ability to create your own custom scopes. Leaning on AOP features this also allows you to "stay singleton" for as long as possible, because it uses a technique known as scope proxying. This can let you introduce a scoped object right in the middle of a chain of singletons - a feature you'd often be using threadlocals for.
So I'd say it's about tight control of instance creation, to make sure everything is done only the required number of times, and preferably only the construction that is necessary is done for each request. Singleton management was the old days.