开发者

Configuration class - best practice with Guice

开发者 https://www.devze.com 2023-04-05 02:35 出处:网络
Background: I\'m using Google Guice and so it\'s easier to pass through the configuration class but I think this is not the best way.

Background: I'm using Google Guice and so it's easier to pass through the configuration class but I think this is not the best way.

I have a configuration class which stores some paths:

class Configuration{
   String getHomePath();
   Strin开发者_如何学JAVAg getUserPath();
}

Also I have a class "a" which needs the "homepath" and a class "b" which needs the "userpath".

Is it better to pass the configuration class through the constructor of class a and b or only pass through the specific path?


If you're really using Guice correctly all your configuration like this should appear in modules' configure method. So:

  1. Remove the configuration class.
  2. Create annotation classes, probably called HomePath and UserPath.
  3. Where class a uses getHomePath() replace that with a String field member named homePath.
  4. Where class b uses getUserPath() replace that with a String field member named userPath.
  5. Modify the class a and b constructors to be @Inject annotated (should already be) and take in a String parameter, respectively annotated with @HomePath and @UserPath and assign the String field member that injected value.
  6. Create bindings in your module's configure method use .annotatedWith() which define correct values; if they're only available at run time, bind a provider.

E.G.

class a {
  private String homePath;
  @Inject
  public a(@HomePath String homePath) {
    this.homePath = homePath;
  }
  public String tellMeAboutHome() {
    return "We live in a nice home called " + homePath;
  }
}

class customModule extends AbstractModule {
  public static final String userPath = "/home/rafael";

  public void configure() {
    bind(String.class).annotatedWith(HomePath.class).to("/home/");
    bind(String.class).annotatedWith(UserPath.class).to(userPath);
  }
}

If creating annotations is too much work for you, use the @Named annotation Guice ships with.


There's no single answer to your question, there are only options to choose from, based on your specific situation.

If you know your Configuration class is going to grow AND if it's likely for your A and B classes will use more from it, then pass the whole Configuration object to their constructors. NB: I know this is against the YAGNI principle but sometimes you may know you're gonna need it ;-)

Otherwise, you can consider using @Named injection of your paths so that you reduce A and B classes dependencies to their minimum, which is a good design practice.


The general rule is code to make the dependency graph (which classes know about or depend on other classes/ interfaces) as simple, regular and fixed as possible.

If not passing the Configuration class makes a or b have zero dependencies on on user-written classes, or is necessary to avoid a dependency loop, then use the individual path strings. Otherwise, if it makes more sense to say 'this class has access to configuration info, in a way that may change in the future', pass the class.

I'd avoid the singleton approach, especially if you already have Guice set up.

0

精彩评论

暂无评论...
验证码 换一张
取 消