Meeting 5: Unterschied zwischen den Versionen
(→Guice) |
|||
Zeile 39: | Zeile 39: | ||
Download the [[Media:Jsug-guice-demo-project.zip|sourcecode]] (pdf, 13KB). | Download the [[Media:Jsug-guice-demo-project.zip|sourcecode]] (pdf, 13KB). | ||
− | === | + | ===Basic facts=== |
− | + | ||
+ | Of course theory is nice, but it becomes useful when you start using a concret technology which enables dependency injection for you, such the Google Guice framework presented by [[Benutzer:Comar|Jan Zarnikov]]. It provides a pure Java style (no external XML configuration which makes it possible to misstype a name; refactorings also changes configuration!) with all Java5 features such as generics (type safety) and annotations (injecting is realized via Guice own annotations). | ||
+ | |||
+ | ===Simple example=== | ||
+ | |||
+ | The following chapter shows a simple application with a database connection and a mocked connection for its unit tests: | ||
+ | <br /><br /> | ||
+ | [[Bild:Guice-Simple example.png|Guice Example]] | ||
+ | |||
+ | The <code>UserController</code> class is subject of the JUnit test and requires a database (in fact, just something that implements the <code>DAO</code> interface). Because unit tests should only test a certain unit (and not the database management system or anything else), the controller class will get another implementation of <code>DAO</code> injected if it is run by JUnit (namely <code>TestDAO</code> instead of <code>JdbcDAO</code>). | ||
+ | |||
+ | |||
+ | Injecting objects is just as easy as annotating the constructor with the <code>@Inject</code> annotation (you could also have used it at the field itself, or provided a setter method): | ||
+ | <source lang="java"> | ||
+ | public class UserController { | ||
+ | |||
+ | private final DAO dao; | ||
+ | |||
+ | @Inject | ||
+ | public UserController(DAO dao) { | ||
+ | this.dao = dao; | ||
+ | } | ||
+ | |||
+ | public boolean login(String username, String password) { | ||
+ | List<User> users = this.dao.getUsers(); | ||
+ | // ... | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | |||
+ | Of course you also have to configure your dependencies somewhere: | ||
+ | <source lang="java"> | ||
+ | public class AppModule extends AbstractModule { | ||
+ | public void configure() { | ||
+ | bind(DAO.class).to(JdbcDAO.class); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public class TestModule extends AbstractModule { | ||
+ | public void configure() { | ||
+ | bind(DAO.class).to(TestDAO.class); | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | |||
+ | To startup the Guice framework, you have to do following first: | ||
+ | <source lang="java"> | ||
+ | public class MyApplication { | ||
+ | public static void main(String[] args) { | ||
+ | // configure Guice with AppModule | ||
+ | Injector injector = Guice.createInjector(new AppModule()); | ||
+ | |||
+ | // userController already got its proper DAO instance injected | ||
+ | UserController userController = injector.getInstance(UserController.class); | ||
+ | |||
+ | boolean isLoggedIn = userController.login("Foo", "Bar"); | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | |||
+ | Or use your special configuration for unit test: | ||
+ | <source lang="java"> | ||
+ | public class UserControllerTest { | ||
+ | |||
+ | private UserController userController; | ||
+ | |||
+ | @Before | ||
+ | public void setup() { | ||
+ | // configure Guice with TestModule, instead with AppModule | ||
+ | Injector injector = Guice.createInjector(new TestModule()); | ||
+ | this.userController = injector.getInstance(UserController.class); | ||
+ | ´ } | ||
+ | |||
+ | // some tests... | ||
+ | |||
+ | } | ||
+ | </source> | ||
===Links=== | ===Links=== | ||
* [http://code.google.com/p/google-guice/ http://code.google.com/p/google-guice/] ... Official Guice website | * [http://code.google.com/p/google-guice/ http://code.google.com/p/google-guice/] ... Official Guice website | ||
+ | * [http://docs.google.com/View?docid=dd2fhx4z_5df5hw8 http://docs.google.com/View?docid=dd2fhx4z_5df5hw8] ... Official userguide | ||
+ | * [http://crazybob.org/2007/06/introduction-to-guice-video-redux.html http://crazybob.org/2007/06/introduction-to-guice-video-redux.html] ... Presentation about Guice | ||
+ | * [http://www.youtube.com/watch?v=FFXhXZnmEQM http://www.youtube.com/watch?v=FFXhXZnmEQM] ... Other presentation about Guice | ||
== Springframework == | == Springframework == |
Version vom 14. Januar 2009, 13:23 Uhr
When: Monday, October 13th, 2008 - 19:00
Where: Freihaus HS4
Inhaltsverzeichnis
Inversion of Control
Download the slides (pdf, 38KB).
Florian Motlik introduced todays topic IoC, which follows the slogan "don't call us, we'll call you". Your code just implements the specific logic but the actual control itself is passed to a certain controller class. A trivial example would be iterating over a collection.
Instead of writing ...
var someList = [ "Larry", "Curly", "Moe" ]; for(var i = 0; i < someList.length; i++) { var name = someList[i]; println(name.length); }
... one could just say ...
[ "Larry", "Curly", "Moe" ].each { name | println(name.length)}
... and that's all. By passing a function to a certain method provided by the datastructure itself (make use of closures), the actual iterating over each field is hidden and you don't have to worry about it anymore; your could will be invoked for each item, and therefore control is inverted.
Dependency injection (originally introduced by Martin Fowler) is a specific form of IoC. Dependencies of a class will be injected for you (constructor/setter/field injections are possible) and therefore the coupling is not necessarily reduced, but its shifted outside the code (in case of Spring into a XML file).
Guice
Download the slides (pdf, 115KB).
Download the sourcecode (pdf, 13KB).
Basic facts
Of course theory is nice, but it becomes useful when you start using a concret technology which enables dependency injection for you, such the Google Guice framework presented by Jan Zarnikov. It provides a pure Java style (no external XML configuration which makes it possible to misstype a name; refactorings also changes configuration!) with all Java5 features such as generics (type safety) and annotations (injecting is realized via Guice own annotations).
Simple example
The following chapter shows a simple application with a database connection and a mocked connection for its unit tests:
The UserController
class is subject of the JUnit test and requires a database (in fact, just something that implements the DAO
interface). Because unit tests should only test a certain unit (and not the database management system or anything else), the controller class will get another implementation of DAO
injected if it is run by JUnit (namely TestDAO
instead of JdbcDAO
).
Injecting objects is just as easy as annotating the constructor with the @Inject
annotation (you could also have used it at the field itself, or provided a setter method):
<source lang="java">
public class UserController {
private final DAO dao;
@Inject public UserController(DAO dao) { this.dao = dao; }
public boolean login(String username, String password) { List<User> users = this.dao.getUsers(); // ... }
} </source>
Of course you also have to configure your dependencies somewhere:
<source lang="java">
public class AppModule extends AbstractModule {
public void configure() { bind(DAO.class).to(JdbcDAO.class); }
}
public class TestModule extends AbstractModule {
public void configure() { bind(DAO.class).to(TestDAO.class); }
} </source>
To startup the Guice framework, you have to do following first:
<source lang="java">
public class MyApplication {
public static void main(String[] args) { // configure Guice with AppModule Injector injector = Guice.createInjector(new AppModule());
// userController already got its proper DAO instance injected UserController userController = injector.getInstance(UserController.class);
boolean isLoggedIn = userController.login("Foo", "Bar"); }
} </source>
Or use your special configuration for unit test:
<source lang="java">
public class UserControllerTest {
private UserController userController;
@Before public void setup() { // configure Guice with TestModule, instead with AppModule Injector injector = Guice.createInjector(new TestModule()); this.userController = injector.getInstance(UserController.class);
´ }
// some tests...
} </source>
Links
- http://code.google.com/p/google-guice/ ... Official Guice website
- http://docs.google.com/View?docid=dd2fhx4z_5df5hw8 ... Official userguide
- http://crazybob.org/2007/06/introduction-to-guice-video-redux.html ... Presentation about Guice
- http://www.youtube.com/watch?v=FFXhXZnmEQM ... Other presentation about Guice
Springframework
Download the slides (pdf, 0.6MB).
Content
Held by Christoph Pickl.
Links
- springframework.org - Official Website
- Comparing Dependency Injection Frameworks - Short presentation at parelys.com
Gallery
Thanks to Jan for providing these pictures.