Author: limpbizkit
Date: Thu Jan  1 16:10:24 2009
New Revision: 777

Modified:
    wiki/GuiceBestPractices.wiki

Log:
Edited wiki page through web user interface.

Modified: wiki/GuiceBestPractices.wiki
==============================================================================
--- wiki/GuiceBestPractices.wiki        (original)
+++ wiki/GuiceBestPractices.wiki        Thu Jan  1 16:10:24 2009
@@ -4,82 +4,6 @@

  These are some of lessons we've learned from writing large applications  
with Guice. These best practices are not necessarily specific to Guice, but  
to the development of any maintainable and testable application. Like  
type-safety and Javadoc, these suggestions assume a codebase where  
readability is more important than writability.

-==Minimize mutability==
-Wherever possible, use constructor injection to create immutable objects.  
Immutable objects are simple, shareable, and can be composed. Follow this  
pattern to define your injectable types:
-{{{
-public class RealPaymentService implements PaymentService {
-
-   private final PaymentQueue paymentQueue;
-   private final Notifier notifier;
-
-   @Inject
-   RealPaymentRequestService(
-       PaymentQueue paymentQueue,
-       Notifier notifier) {
-     this.paymentQueue = paymentQueue;
-     this.notifier = notifier;
-   }
-
-   ...
-}}}
-All fields of this class are final and initialized by a single  
`...@inject`-annotated constructor.  
[http://java.sun.com/docs/books/effective/toc.html Effective Java]  
discusses other benefits of immutability.
-
-
-==Inject only direct dependencies==
-Avoid injecting an object only as a means to get at another object. For  
example, don't inject a `Customer` as a means to get at an `Account`:
-{{{
-public class ShowBudgets {
-   private final Account account;
-
-   @Inject
-   ShowBudgets(Customer customer) {
-     account = customer.getPurchasingAccount();
-   }
-}}}
-Instead, inject the dependency directly. This makes testing easier; the  
test case doesn't need to concern itself with the customer. Use an  
`...@provides` method in your `Module` to create the binding for `Account`  
that uses the binding for `Customer`:
-{{{
-public class CustomersModule extends AbstractModule {
-  @Override public void configure() {
-    ...
-  }
-
-  @Provides
-  Account providePurchasingAccount(Customer customer) {
-    return customer.getPurchasingAccount();
-  }
-}}}
-
-
-==Avoid Static State==
-Static state and testability are enemies. Your tests should be fast and  
free of side-effects. But non-constant values held by static fields are a  
pain to manage. It's tricky to reliably tear down static singletons that  
are mocked by tests, and this interferes with other tests.
-
-`requestStaticInjection()` is a *crutch*. Guice includes this API to ease  
migration from a statically-configured application to a dependency-injected  
one. New applications developed with Guice should not use this API.
-
-Although *static state* is bad, there's nothing wrong with the static  
*keyword*. Static classes are okay (preferred even!) and for pure functions  
(sorting, math, etc.), static is just fine.
-
-
-==Use @Nullable==
-To eliminate `NullPointerExceptions` in your codebase, you must be  
disciplined about null references. We've been successful at this by  
following and enforcing a simple rule:
-  _Every parameter is non-null unless explicitly specified._
-The [http://code.google.com/p/google-collections/ Google Collections  
library] has simple APIs to get a nulls under control.  
`Preconditions.checkNotNull` can be used to fast-fail if a null reference  
is found, and `...@nullable` can be used to annotate a parameter that permits  
the `null` value:
-{{{
-import static com.google.common.base.Nullable;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-public class Person {
-  ...
-
-  public Person(String firstName, String lastName, @Nullable Phone phone) {
-    this.firstName = checkNotNull(firstName, "firstName");
-    this.lastName = checkNotNull(lastName, "lastName");
-    this.phone = phone;
-  }
-}}}
-*Guice forbids null by default.* It will refuse to inject `null`, failing  
with a `ProvisionException` instead. If `null` is permissible by your  
class, you can annotate the field or parameter with `...@nullable`. Guice  
recognizes any `...@nullable` annotation, like  
[http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Nullable.html
  
com.google.common.base.Nullable] or  
[http://code.google.com/p/jsr-305/source/browse/trunk/ri/src/main/java/javax/annotation/Nullable.java?r=24
  
javax.annotation.Nullable].
-
-----
-
-
  = Field vs. method vs. constructor injection =

  *Field injection*
@@ -99,37 +23,4 @@
    * - No optional injections
    * - Useless when Guice can't do instantiation itself, e.g. a servlet
    * - Subclasses need to "know about" the injections needed by their  
superclasses
-  * - Less convenient for tests that only "care about" one of the  
parameters
-
-= Choosing a scope =
-
-  * If the object is stateless and inexpensive - then who cares?
-  * If the object is stateful, it should hopefully be obvious
-    * But you may have to write a custom scope yourself
-  * Never use Singleton or SessionScoped on a class that isn't thread-safe!
-  * For @RequestScoped and "no scope", you don't have to worry about  
concurrent access.
-  * Singleton exists primarily for two types of objects
-    * Ones that are expensive to construct
-    * Ones that tie up resources (e.g., a connection pool)
-  * Session scope is overrated
-    * Usually replaceable by conversation scope (Bob, hurry up and write  
that!)
-    * If you want to cache something, use a cache!
-
-= Eager singletons =
-
-A common way to create an eager singleton is
-
-`binder.bind(Service.class).toInstance(new MyService());`
-
-But this is not such a great way to do it!
-
-  * Guice doesn't construct MyService, so you get only field and method  
injection, not constructor injection.
-  * Your singleton is fully initialized even if no one ever even calls  
createInjector()!
-    * This could be running inside a tool of some kind, not a real app
-  * This gives you no lazy-loading option, even in tests that use this  
module.
-
-Why not let Guice do what Guice does best (creating things)?
-
-`binder.bind(Service.class).to(MyService.class).asEagerSingleton();`
-
-The main disadvantage of this is that you are forced to name your class,  
while you might have provided an anonymous instance above.  Oh well.
\ No newline at end of file
+  * - Less convenient for tests that only "care about" one of the  
parameters
\ No newline at end of file

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"google-guice-dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/google-guice-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to