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:
- Remove the configuration class.
- Create annotation classes, probably called
HomePath
andUserPath
. - Where class a uses
getHomePath()
replace that with a String field member named homePath. - Where class b uses
getUserPath()
replace that with a String field member named userPath. - 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. - 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.
精彩评论