8

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?

2 Answers 2

6

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.