简体   繁体   English

java配置/参数传递设计

[英]java configuration/parameter passing design

Often I find the need to engineer objects with configurable functionality. 我经常发现需要设计具有可配置功能的对象。

To exemplify, assume I'm creating a DateIterator . 举个例子,假设我正在创建一个DateIterator The configurable option(s) might be whether to iterate the closed interval [start, end] or the open-end interval [start, end) . 可配置选项可能是迭代闭合间隔[start, end]还是开放端间隔[start, end)


  • (1) The, in my opinion, ungraceful solution - limited to only one true/false configuration option (1)在我看来,不合理的解决方案 - 仅限于一个真/假配置选项
new DateIterator(boolean openInterval);
  • (2) The typesafe enum way - typically a bit bulky (2)类型安全的枚举方式 - 通常有点笨重
new DateIterator(Interval.OPEN_END);
  • (3) The unconventional attempt - nice but not too straight forward (3)非传统的尝试 - 很好但不太直接
new DateIterator().openEnd();
  • (4) The inheritance approach - often over-engineering (4)继承方法 - 经常过度工程化
new OpenEndedDateIterator();

To this comes a few alternatives which I consider inferior, like integer-based configuration new DateIterator(Interval.OPEN_END); 对于这个,有一些我认为较差的选择,比如基于整数的配置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: 我会说Builder模式在这里有意义:

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. 这样你的实际DateIterator可以是不可变的,而DateIterator.builder()返回的构建器可以完成配置工作。

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. 虽然它可能过度设计,但如果你的类中的许多方法都以“if(this.parameter == x)... else if(this.parameter == y)..”开头,那么它将使代码无法读取。
  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),非常规尝试:)
  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. 如果固定集中有多个参数(如START_OPEN_ENDED和STOP_OPEN_ENDED),则创建子类可能意味着为每个排列创建子类。 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. 例如(我可能不会在这个特定情况下这样做,但这是一个很好的例子),创建一个单独的DateComparator类,带有一个开放式的子类,并封装一个DateComparator用于开始,一个用于结束,只有一个DateIterator。

Again, these are the rule of thumb I use, in no way mandatory, and often I find myself not respecting them verbatim. 同样,这些是我使用的经验法则,绝不是强制性的,而且我经常发现自己不会逐字尊重它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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