简体   繁体   中英

java configuration/parameter passing design

Often I find the need to engineer objects with configurable functionality.

To exemplify, assume I'm creating a DateIterator . The configurable option(s) might be whether to iterate the closed interval [start, end] or the open-end interval [start, end) .


  • (1) The, in my opinion, ungraceful solution - limited to only one true/false configuration option
new DateIterator(boolean openInterval);
  • (2) The typesafe enum way - typically a bit bulky
new DateIterator(Interval.OPEN_END);
  • (3) The unconventional attempt - nice but not too straight forward
new DateIterator().openEnd();
  • (4) The inheritance approach - often over-engineering
new OpenEndedDateIterator();

To this comes a few alternatives which I consider inferior, like integer-based configuration new DateIterator(Interval.OPEN_END); or property based configuration.

Are there any other approaches? Which approach you do you prefer?

I'd say the Builder pattern makes sense here:

DateIterator di = 
  DateIterator.builder()
              .withStartDate(new Date())
              .withOpenEnd()
              .build();

That way your actual DateIterator can be immutable, while the builder returned by DateIterator.builder() does the configuration work.

While there is no good answer, and it's largely a matter of taste, I do follow the following rule of thumb, with large space for exceptions to avoid over engineering :

  1. If the only configuration you have is one "parameter", taking a fixed set, and alters behavior (like in your example), go with subclasses. While it may be over-engineered, if many methods in your class start with an "if (this.parameter == x) ... else if (this.parameter == y) .. " it will make code unreadable.
  2. If your parameter is not a fixed set, but a string or number, and you NEED it for the class to work properly put it in the constructor, if it's not mandatory i like solution number (3), the unconventional attempt :)
  3. If you have more than one parameter in a fixed set (like START_OPEN_ENDED and STOP_OPEN_ENDED), creating subclasses may mean to create a subclass for each permutation. In that case consider encapsulation. For example (I would not do it in this specific case probably, but it's a good example), create a single class DateComparator, with a subclass for open ended, and encapsulate a DateComparator for the start and one for the end, having only one DateIterator.

Again, these are the rule of thumb I use, in no way mandatory, and often I find myself not respecting them verbatim.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM