Inversion of Control, Dependency Injection and Strategy Pattern with examples in java - java

I am often confused by these three terms. These three look similar to me. Can someone please explain them to me clearly, with examples.
I have seen similar posts and don't understand completely.

Dependency Injection refers to the pattern of telling a class what its dependencies will be, rather than requiring the class to know where to find all of its dependencies.
So, for example, you go from this:
public class UserFetcher {
private final DbConnection conn =
new DbConnection("10.167.1.25", "username", "password");
public List<User> getUsers() {
return conn.fetch(...);
}
}
to something like this:
public class UserFetcher {
private final DbConnection conn;
public UserFetcher(DbConnection conn) {
this.conn = conn;
}
public List<User> getUsers() {
return conn.fetch(...);
}
}
This reduces coupling in the code, which is especially useful if you want to unit test UserFetcher. Now, instead of UserFetcher always running against a database found at 10.167.1.25, you can pass in a DbConnection to a test database. Or, even more useful in a fast test, you can pass in an implementation or subclass of DbConnection that doesn't even connect to a database, it just discards the requests!
However, this sort of primitive dependency injection makes wiring (providing an object with its dependencies) more difficult, because you've replaced accessing the dependency using a global variable (or a locally instantiated object) with passing the dependency around through the whole object graph.
Think of a case where UserFetcher is a dependency of AccountManager, which is a dependency of AdminConsole. Then AdminConsole needs to pass the DbConnection instance to AccountManager, and AccountManager needs to pass it to UserFetcher...even if neither AdminConsole nor AccountManager need to use the DbConnection directly!
An inversion of control container (Spring, Guice, etc) aims to make dependency injection easier by automatically wiring (providing) the dependencies. To do this, you tell your IoC container once how to provide an object (in Spring, this is called a bean) and whenever another object asks for that dependency, it will be provided by the container.
So our last example might look like this with Guice, if we used constructor injection:
public class UserFetcher {
private final DbConnection conn;
#Inject //or #Autowired for Spring
public UserFetcher(DbConnection conn) {
this.conn = conn;
}
public List<User> getUsers() {
return conn.fetch(...);
}
}
And we have to configure the IoC container. In Guice this is done via an implementation of Module; in Spring you configure an application context, often through XML.
public class MyGuiceModule extends AbstractModule {
#Override
public void configure() {
bind(DbConnection.class).toInstance(
new DbConnection("localhost", "username", "password"));
}
}
Now when UserFetcher is constructed by Guice or Spring, the DbConnection is automatically provided.
Guice has a really good Wiki article on the motivation behind dependency injection, and further using an IoC container. It's worth reading all the way through.
The strategy pattern is just a special case of dependency injection, where you inject logic instead of an object (even though in Java, the logic will be encapsulated in an object). It's a way of decoupling independent business logic.
For example, you might have code like this:
public Currency computeTotal(List<Product> products) {
Currency beforeTax = computeBeforeTax(products);
Currency afterTax = beforeTax.times(1.10);
}
But what if you wanted to extend this code to a new jurisdiction, with a different sales tax scheme? You could inject the logic to compute the tax, like this:
public interface TaxScheme {
public Currency applyTax(Currency beforeTax);
}
public class TenPercentTax implements TaxScheme {
public Currency applyTax(Currency beforeTax) {
return beforeTax.times(1.10);
}
}
public Currency computeTotal(List<Product> products, TaxScheme taxScheme) {
Currency beforeTax = computeBeforeTax(products);
Currency afterTax = taxScheme.applyTax(beforeTax);
return afterTax;
}

Inversion of control means that a runtime framework wires all components together (for example Spring). Dependency injection is a form of IoC (I don't know if another form of IoC exists) (see: http://en.wikipedia.org/wiki/Inversion_of_control).
Strategy pattern is a design pattern (defined by the GoF) where the algorithm can be replaced by another (see: http://en.wikipedia.org/wiki/Strategy_pattern). This is archived by provided several implementation of a same interface. When using an IoC like Spring, if you have several implementations of an interface, and if you can switch from an implementation to another by configuration, you are using the strategy pattern.

I also recommend reading the introduction chapter of Spring's documentation, which focuses on this issue: Introduction to Spring Framework
The first few paragraphs should do.
And this also links to: Inversion of Control Containers and the Dependency Injection pattern
Which also provides a motivational view of these very important core concepts.

Related

Spring equivalent of EJB Singleton to maintain the state

Currently I'm working on a JSF2 + Spring application. And I need to have one component, which I would be able to autowire when needed and read/write the state (safely) from/to it.
In EJB I would do it as follows:
#Singleton
#ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class LocaleManager {
private String currentLanguage;
#Lock(LockType.READ)
public String getCurrentLanguage() {
return currentLanguage;
}
#Lock(LockType.WRITE)
public void setCurrentLanguage(String currentLanguage) {
this.currentLanguage = currentLanguage;
}
}
How can I achieve this in Spring? Thanks!
EDIT: One important thing is that application has multiple Maven modules and I need this in "core" module which doesn't depend on spring-web. I need the language information in DTO assemblers, where I would like to use only string values relevant to the current locale set in JSF. Entity has a set of translations for various languages (each DB table has own translation table). In the corresponding DTO I would like to have just e.g. "String description", instead of "Set<ItemTranslation> description".
In Spring the scope of the bean says how the instances are created. I suggest you to check out the following tutorial:
http://www.mkyong.com/spring/spring-bean-scopes-examples/

what is the difference between using or not Spring Beans?

Probably i'll get a lot of downvotes, but it's so confusing for me all this fact of whether use beans or not. Lets suppose this example
interface ICurrency {
String getSymbol();
}
public class CurrencyProcessor {
private ICurrency currency ;
public CurrencyProcessor(ICurrency currency) {
this.currency = currency;
}
public void doOperation(){
String symbol = currency.getSymbol();
System.out.println("Doing process with " + symbol + " currency");
// Some process...
}
}
So, to inject the ICurrency impl injection i think that i can do it by two ways:
Way 1: Without Spring beans
public class CurrencyOperator {
private ICurrency currency ;
private CurrencyProcessor processor;
public void operateDefault(){
currency = new USDollarCurrency();
processor = new CurrencyProcessor(currency)
this.processor.doOperation();
}
}
Where USDollarCurrency is an ICurrency interface implementation
Way 2: Using Spring beans
#ContextConfiguration(classes = CurrencyConfig.class)
public class CurrencyOperator {
#Autowired private ICurrency currency ;
#Autowired private CurrencyProcessor processor;
public void operateDefault(){
this.processor.doOperation();
}
}
#Configuration
public class CurrencyConfig {
#Bean
public CurrencyProcessor currencyProcessor() {
return new CurrencyProcessor(currency());
}
#Bean
public ICurrency currency() {
return new USDollarCurrency();
}
I really don't understand what would be the benefits of using Spring's beans. I read some things but what i most found was about the benefits of using DI, and as i understand, both ways are injecting the dependency that CurrencyProcessor require, what is changing is the way that i am creating and using objets, am i wrong? So in concrete, my questions are:
1. What are the benefits of using Beans at this case?
2. Why should i use Spring instead of doing it manually like first way?
3. Talking about performance, which of this cases is better?
Suppose you have 2 DAO classes one for Oracle, the seconde for MySQL, and both classes are implementing a DAO interface. You define an implementation as a bean in Spring configuration file. In the business class you have an attribut of type DAO, while in the spring configuration file you choose the real type wheather Oracle or MySQL to inject or using spring annotation #Autowired
This reduce coupling and it will be easy to move from Oracle to MySQL.
#Service
public class Business {
#Autowired
private Dao daoImpl;
//Business methods that invoks Dao methods
}
In the Spring configuration file (XML file) you use the following:
<bean id="daoImpl" class="app.com.MySQLDaoImpl OR app.com.OracleDaoImpl"/>
By just changing the class attribut of your bean you change the whole implementation, without any change in your business class ! Good luck.
Your example without Spring doesn't dependency injection!
With dependency injection, the actual implementation of the interface is determined outside the code itself in order to reduce the coupling!
You should be able to need another implementation (you could for example switch from one JMS client to another...).
To answer to your last question, using Spring is (a very little bit) less performant but much more flexible.
EDIT :
Spring is not the only tool that can be used for DI but it is the most popular and it contains a lot of features. Note that many Java standards also (such as JPA) use DI.

GoF standard factory pattern using Guice

I have used the standard factory pattern method before to create instances of classes (implementing a specific interface) using a Factory class, which has a "create" method, that returns the right instance based on the parameter passed to it (example snippet given below):
public class SimpleFactory {
public static SimpleObjectInterface getSimpleObject(int data) {
SimpleObjectInterface toReturn;
switch(data) {
case 1:
toReturn = new OneSimpleObject();
break;
case 2:
toReturn = new TwoSimpleObject();
break;
default:
toReturn = new DefaultSimpleObject();
break;
}
return toReturn;
}
}
Now I am using Guice in my project for dependency injection. My question is how can I achieve something like the above using Guice? Which implementation instance is needed is decided at runtime based on some user input.
I have looked at Provider and #Named annotations. But I don't understand how exactly it will help me.
In general for the problem where you want a factory that injects most dependencies, but still allows some client-supplied deps, you would use Factories by Assisted Injection.
However in your case this would lead to conditional logic in your factory, which is probably not ideal (it is explicitly discouraged in Guice modules).
I think for your situation a MapBinder would be ideal, and you wouldn't need a factory at all, since you're only switching on data type and not building anything really. In your module you configure a map of int (in your case) keys to impls of SimpleObjectInterface. Then in your main runtime class you inject the map, and when you need an instance of a simple object and have int data available, you call get(data) on the injected map.
I don't have an IDE on this machine, so I can't test the code, but from memory it would be something like below:
In your module:
public class MyModule extends AbstractModule {
protected void configure() {
MapBinder<Integer, SimpleObjectInterface> mapbinder
= MapBinder.newMapBinder(binder(), Integer.class, SimpleObjectInterface.class);
mapbinder.addBinding(1).toClass(OneSimpleObject.class);
mapbinder.addBinding(2).toClass(TwoSimpleObject.class);
}
}
In your app code:
#Inject
private Map<Integer, SimpleObjectInterface> simpleObjectMap;
...
void applicationCode() {
...
Integer data = getData();
SimpleObjectInterface simpleObject = simpleObjectMap.get(data);
...
}
Only issue here is you can't have the "default" binding that you had in your switch statement. Not sure of the best way to handle that, maybe you could assign a default impl in your app code if the object is still null after trying to instantiate it from the map binder. Or you could go back to assisted inject with conditional logic, but it's not really "assisted" injection if the sole dependency is client supplied.
See also: Can Guice automatically create instances of different classes based on a parameter?

Java EE dependency Injection when to use?

I'm new to this and I want to understand when is it appropriate to use DI in Java. Suppose I need to ping different networks with different ping parameters:
The class PingParams:
public class PingParams {
int timeout;
int retries;
}
The class PingResult:
public class PingResult {
int ttl;
boolean available;
}
The class PingService:
public class PingService {
private PingParams pingParams;
#Inject
public PingService(PingParams pingParams) {
this.pingParams = pingParams;
}
public PingResult ping(String ip) {
// ping using timeout and retries from pingParams
return new PingResult();
}
}
The client:
public class Client {
#Inject
PingService pingService;
private List<PingResult> doPing() {
List<PingResult> ret = new ArrayList<>();
String[] ips = new String[] {"127.0.0.1","127.0.0.2"};
for (String ip : ips) {
PingResult pr = pingService.ping(ip);
ret.add(pr);
}
return ret;
}
public static void main(String[] args) {
List<PingResult> prs = new Client().doPing();
System.out.println(prs);
}
}
I have 2 injection points:
I inject PingParams in the constructor of PingService.
Is this correct? I mean, the DI container can not know the timeout and retries to inject into the PingParams unless you create some "Produces" annotated method, even in this case, it seams a looot of work just to create an object! But of course you need to create several, one for every network, how do you do that with DI?
I inject PingService in the client.
Seems legitimate, but PingService depends on PingParams, which takes us to injection point number 1.
Seems to me like the only appropriate way to use DI is with classes which have no dependencies (therefore useless) or with very simple service classes where you pass all the dependencies as parameters to service methods. For example a PingService which accepts the ip and the PingParams in the ping method, again this class would have no dependencies...
Am I missing something? How can you use DI with these "data" classes, classes which contain only fields for keeping data (PingParams)? Are suppose to avoid DI in these cases? Thanks
In general you should only use dependency injection for non-data classes. If you have classes that contain both data and non-data collaborators you can use assisted injection.
The ping params you talk about should indeed be bound to an instance on the start-up of your application and injected where necessary. For you example that is indeed much code but in the long run it keeps things nice and clean in bigger projects.
To summarize: bind PingParam when the application starts (as a Singleton for example), inject it into PingService, and create PingResult without DI (as you have done).
For Dependency Injection best practices, I recommend reading Dependency Injection by Prasanna
Assuming we're talking about CDI/Weld. Let's say your PingParams class were stored in the DB, as configuration loaded from some table. It would make a lot of sense to abstract that away, and simply provide a producer method for the PingParams class that reads the data from the DB and provides back this data element. It's not a bad idea to use a data object for this configuration, and provide a producer for it.

Using guice for a framework with injected classes, proper way to initialize?

I'm trying to write a framework where arbitrary bean classes are injected with classes from my API, and they can interact with both those classes as well have triggered callbacks based on defined annotations. Here's an example bean:
#Experiment
static class TestExperiment {
private final HITWorker worker;
private final ExperimentLog log;
private final ExperimentController controller;
#Inject
public TestExperiment(
HITWorker worker,
ExperimentLog expLog,
ExperimentController controller
) {
this.worker = worker;
this.expLog = expLog;
this.controller = controller;
}
#SomeCallback
void callMeBack() {
... do something
log.print("I did something");
}
}
I'm trying to use Guice to inject these beans and handle the interdependencies between the injected classes. However, I have two problems:
One of the classes I pass in (HITWorker) is already instantiated. I couldn't see how to move this to a Provider without significantly complicating my code. It is also persistent, but not to the Guice-defined session or request scope, so I am managing it myself for now. (Maybe if the other issues are overcome I can try to put this in a provider.)
More importantly, I need a reference to the other injected classes so I can do appropriate things to them. When Guice injects them, I can't access them because the bean class is arbitrary.
Here's some really bad code for what I basically need to do, which I am sure is violating all the proper dependency injection concepts. Note that hitw is the only instance that I need to pass in, but I'm creating the other dependent objects as well because I need references to them. With this code, I'm basically only using Guice for its reflection code, not its dependency resolution.
private void initExperiment(final HITWorkerImpl hitw, final String expId) {
final ExperimentLogImpl log = new ExperimentLogImpl();
final ExperimentControllerImpl cont = new ExperimentControllerImpl(log, expManager);
// Create an experiment instance with specific binding to this HITWorker
Injector child = injector.createChildInjector(new AbstractModule() {
#Override
protected void configure() {
bind(HITWorker.class).toInstance(hitw);
bind(ExperimentLog.class).toInstance(log);
bind(ExperimentController.class).toInstance(cont);
}
});
Object experimentBean = child.getInstance(expClass);
expManager.processExperiment(expId, experimentBean);
// Initialize controller, which also initializes the log
cont.initialize(expId);
expManager.triggerStart(expId);
tracker.newExperimentStarted(expId, hitw, cont.getStartTime());
}
Am I screwed and just have to write my own injection code, or is there a way to do this properly? Also, should I just forget about constructor injection for these bean classes, since I don't know what they contain exactly anyway? Is there any way to get the dependencies if I am asking Guice to inject the bean instead of doing it myself?
For context, I've been reading the Guice docs and looking at examples for several days about this, to no avail. I don't think I'm a complete programming idiot, but I can't figure out how to do this properly!
Your "experiment" seems to be something like a "request" in the sense that it has a defined lifecycle and some associated stuff the experiment can pull in at will.
Therefore I think you should wrap all that into a custom scope as described in the docs about Custom Scopes. This matches your case in several points:
You can "seed" the scope with some objects (your HITWorker)
The lifecycle: do "enter scope" before you setup the experiment and "exit scope" after you finished your work.
Access to "shared" stuff like ExperimentLog and ExperimentController: Bind them to the scope. Then both the framework and the experiment instance can simple #Inject them and get the same instance.

Categories