For my programming course at University of Berne I had to shortly talk about dependencies and how we handle them. I features some Inversion of Control methods and the DI framework Guice from Google.
2. Outline
What are dependencies?
How dependencies cause problems
Inversion of Control and Hollywood
Guice – the solution for everything (almost)
Providers
The creation of a new object
15.04.2011 Joel Krebs 2
3. What are dependencies?
- or why not to code only one class
Classes depends on others, that comes with
Object orienteted programming (OOP)
Dependencies are classes, that are used by
other classes in order to work
Example: Board
Die Player
15.04.2011 Joel Krebs 3
4. Why are dependencies bad?
- well that depends...
What are key features of 'good code'?
Testable
Modular
Changable
…
Imagine that for huge applications...
15.04.2011 Joel Krebs 4
5. Inversion of Control
- what has Hollywood to do with all this?
Inversion of Control (IoF) is a design pattern to
reduce dependencies without any frameworks
Difference to procedural architecture:
Board Die Player
Die
Board
Player
15.04.2011 Joel Krebs 5
6. Methods for Inversion of Control
- something everybody can do
General rules:
Use interfaces
Use getters and setters
1. Using factories
IDie die = DieFactory.get()
2. Using constructors injection
public Board(IPlayer player, IDie die)
3. Using setter injection
public void setDie(IDie die)
15.04.2011 Joel Krebs 6
7. Guice
- well, it works for Google, let's try
Real dependency injection only works with
frameworks (e.g. Guice, Spring)
They can save you a lot of time and coding, but
not for too small applications
Guice needs you...
...to tell Guice wich Interface maps to which class
=> module
...to give him the necesarry information how to
construct a object => Provider
15.04.2011 Joel Krebs 7
8. The Provider
- let's just copy & paste
import com.google.inject.Inject;
import com.google.inject.Provider;
public class GameProvider implements Provider<Game> {
private Provider<IDie> dieProvider ;
@Inject
public GameProvider(Provider<IDie> dieProvider) {
this.dieProvider = dieProvider;
}
@Override
public Game get() {
Player[] players = { new Player("Jack"), new Player("Jill")};
Game game = new Game(12, players, dieProvider .get());
game.setSquareToLadder(2, 4);
game.setSquareToLadder(7, 2);
game.setSquareToSnake(11, -6);
game.setSquareToLargeSquare(4);
game.setSquareToTrapDoor(10, -6);
return game;
}
}
15.04.2011 Joel Krebs 8
9. The Module
- different modules for testing and use
package snakes;
import com.google.inject.AbstractModule;
public class SnakesModule extends AbstractModule {
@Override
protected void configure() {
bind(IDie.class)
.to(Die.class);
bind(Game.class)
.toProvider(GameProvider.class);
}
}
public class SnakesTestModule extends AbstractModule {
@Override
protected void configure() {
bind(IDie.class)
.toInstance(context.mock(IDie.class));
bind(Game.class)
.toProvider(GameProvider.class);
}
}
15.04.2011 Joel Krebs 9
10. How we get new objects
- all roads lead to Rome...or a game
So if I want a board game, what happens?
Main method
Injector.getInstance(Game.class)
SnakesModule
bind(Game.class)
.toProvider(GameProvider.class)
GameProvider
new Game(... dieProvider.get())
15.04.2011 Joel Krebs 10
11. Improvements
- there's always a way to code better
Use annotions that are provided by Guice
@named
@singelton
Merge modules
Merge providers
15.04.2011 Joel Krebs 11
12. Conclusions
- doesn't make it all more complicate?
Reduce dependencies in general improves your
code in many ways
It needs a certain kind of mindset, but you get
used to it
Frameworks like Guice can improve your code
as well and may save you a lot of time
But I would not use them for too small projects
15.04.2011 Joel Krebs 12
13. Questions
- experiences, smart remarks, suggestions
Joel Krebs
joel.krebs@students.unibe.ch
@jomikr on
www.aleaiactaest.ch
15.04.2011 Joel Krebs 13