English 中文(简体)
Java 构造者,有大论或 Java海滩/天衣
原标题:Java constructor with large arguments or Java bean getter/setter approach
  • 时间:2009-10-27 16:30:57
  •  标签:

I can t decide which approach is better for creating objects with a large number of fields (10+) (all mandatory) the constructor approach of the getter/setter. Constructor at least you enforce that all the fields are set. Java Beans easier to see which variables are being set instead of a huge list. The builder pattern DOES NOT seem suitable here as all the fields are mandatory and the builder requires you put all mandatory parameters in the builder constructor.

Thanks, D

问题回答

更好的办法是使用某种建筑商:

MyClass a = new MyClassBuilder().blah("blah").foo("foo").doStuff().toMyClass();

在MyClass仍然位于的可变,但可读造物远多于一个有10个论点的建筑商。

http://en.wikipedia.org/wiki/Fluent_interface”rel=“noretinger”>fluent界面。 Gregresi&pf 有效 Java

我的第一个想法是检查贵方的保费模式是否正确。 有10+强制性领域像很多一样健全,或许在这种情形下有更细微的分部分更为合理?

其中一些领域/参数是否与? 将它们合并成具有意义的物体(例如x-coordinationy-coordination,合并为<<<>><>>>.

在“

Clean Code ,由罗伯特·马丁进一步: 他建议提出1或2项论据,3项已被视为“代码轮".”。 个人方面,我想Clean Code在当地是极端的,但从总体上说,它提出了一些很好的论据。

“一刀切的参数”(无论可能有多少)都用大量后遗体和很少的结构来形容一种“k清”。 这还使维护更加困难和错误容易发生;至少是难以阅读。

所有这一切都使人有理由考虑削减参数。 其他答复提出了一些实际建议。

我将建议你考虑。 保证你们获得一个有效的物体,而仅仅没有大量的参数清单。

禁止化学武器组织正在更新,以拒绝建筑商的模式,但它似乎基于误解。 存在“建筑商”模式并不能排除所有参数的执行。

2. 审议下列物体:

 public class SomeImmutableObject {
      private String requiredParam1;
      private String requiredParam2;
      //etc.

      private SomeImmutableObject() { //cannot be instantiated outside the class }

      public static class Builder {
          private SomeImmutableObject instance;
          public Builder() { instance = new SomeImmutableObject();
          public Builder setParameter1(String value) {
               instance.requiredParam1 = value;
               return this;
          }
          //etc for each parameter.

          public SomeImmutableObject build() {
             if (instance.requiredParam1 == null || instance.requiredParam2 == null /*etc*/)
                throw new IllegalStateException("All required parameters were not supplied.");
             return instance;
          }
      } 
 }

请注意,通过使田间一揽子计划成为私人项目,并将建筑商放在相同的一揽子方案中,你基本上能够完成同样的工作。

如果出于某种原因,你可以不这样做,那么你仍然能够有10个参数的构造者,然后,建筑商是唯一要求建筑商做的事,这样它就更便于使用。

因此,就所有规定要求而言,建筑商模式只是罚款。 要求所有10个参数这一事实根本不能使建筑商模式分离。 如果还有某种其他需要,这种模式不能满足,请详述。

Edit:The OP又增加了一句话(当时刚刚结束,但我只是就这一问题发表一句话,因此,我现在才看到这一点),这是一个有趣的问题: 你们如何在以后某个时候验证原始价值?

围绕这一问题有几种方式,包括保护养羊,但我倾向于使用像这样双重目标:

     private Double doubleForPrimitive;

     public Builder setDouble(double d) {
         doubleForPrimitive = d;
     }

     public SomeImmutableObject build() {
         if(doubleForPrimitive != null) {
               instance.doubleParam = doubleForPrimitive;
         } else {
                throw new IllegalArgumentExcepion("The parameter double was not provided");
         }
         //etc.
     }

应当指出,如果你需要真正的表面上可变性,把不可变物体的所有领域作为最终目标,这就需要更多的碎块(储存在建筑商内的变数,并将其传给不可变物体的私人建筑商),但从客户代码的角度来看,这种办法仍然很干净。

您可考虑使用builder patterns,由建筑商确保所有领域至少能够确定为合理的缺省。 提及执行工作的联系,但你会发出这样的呼吁:

Widget widge = new Widget.Builder(). manufacturer("333").serialNumber("54321").build();

这两种模式有助于考虑这种设想:

建造人有10个论点。 我将认真考虑是否需要这些要求,其中一些建议没有意义把它们纳入逻辑目标。 如果确实有十种不同的所需数据,那么施工者应当包含十个领域。

IMHO, 您应当通过所需的一切手段,使物体能够按照您在构造中的商业逻辑有效。

如果论点清单冗长,你可以提出含有这些论点的反对。

我将采用这样的建筑模式:

package so1632058;

public class MyClass {
  private final String param1;
  private final String param2;

  MyClass(Builder builder) {
    this.param1 = builder.param1;
    this.param2 = builder.param2;
  }

  public String getParam1() {
    return param1;
  }

  public String getParam2() {
    return param2;
  }

  @SuppressWarnings("hiding")
  public static final class Builder {
    String param1;
    String param2;

    public Builder param1(String param1) {
      this.param1 = param1;
      return this;
    }

    public Builder param2(String param2) {
      this.param2 = param2;
      return this;
    }

    public MyClass toMyClass() {
      return new MyClass(this);
    }
  }
}

之后有以下法典加以使用:

package so1632058;

public class Main {

  public static void main(String[] args) {
    MyClass.Builder builder = new MyClass.Builder();
    builder.param1("p1").param2("p2");
    MyClass instance = builder.toMyClass();
    instance.toString();
  }

}

一些说明:

  • There are no methods with many parameters.
  • The additional checking can be done in the MyClass constructor.
  • I made the constructor s visibility package-wide to avoid the "synthetic-access" warning.
  • Same for the builder s instance fields.
  • The only way to construct an instance of MyClass is via the Builder.

实际取决于特定类别。 是否应当改变? 这是一种简单的价值目标,没有任何行为? 您是否将这一价值目标绘制成网络服务参数或关系数据库? 你们是否打算将其编成序号? (其中一部分需要的是违约构造。) 您能更多地了解目标?

阶级的变动可能会减少争论,或者只有一个,它有10个特性?

物体是否可变?

在个人方面,我看不出与大建筑商有任何错误,特别是如果只有一个建筑商,所有财产也是最终的。

If all parameters are in fact mandatory, then I see no reason why not to use a constructor. However, if that s not the case, then using a builder seems like the best approach.
Relying only on setters is in my opinion the worst solutions since there s nothing to enforce that all mandatory properties are set. Of course if you re using Spring Framework s bean wiring or other similar solution, then Java beans are perfectly fine as you can check after the initialization that everything has been set.

这无疑是一个设计问题。 你们必须轻松地权衡可读性。 十个增资建筑商更容易,但可能或可能更适于阅读/保持。 也没有多少方法要求停靠和取消电话。 通过固定装置设定10个不同的价值,是更可读和更明确的。 这不一定是“更快”的(尽管你可以提出两种办法),并且增加了更多的方法要求放弃呼吁。

但这里还有一点要思考。 即便有10个论点的构造者,你也可以有一位方案家选择通过无效、空白、虚假或零(取决于物体或原始),而后者可能或不可能是你打算的东西。 你控制这种情况的唯一途径是,在建筑商中可能出现例外。 你们真的想要做些什么? 你们是否期望这样做?

根据赠款,通过固定装置分别确定每个变量,你可能无法知道何时或是否在构造该物体。 这就是上文讨论的“建筑商”模式会有助益的。 它是否制造了物体,设定了价值,然后确认所有物体均已确定。 如果缺少一些东西,因为一名方案管理员决定不通过某些东西,那么你就会受到保护。 你的班子必须做的比本应该多。 (毕竟,必须考虑谁可能利用你的班子。) 他们可能不理解你的意图,尽管世界上存在巨大的 Java。

最后,我问,你是否需要违约? 由于某些事情可能落空,因此,你可以把这些东西设定为班级的违约值,或将其设定为施工人中的违约值(取决于你们的方案拟订理想,而你认为这些理想更为具体,有助于你的行为)。 然后,你可能“预先设定”某些领域,只需要通过人工设定或通过建筑商设定,来推翻这些领域。

同样,你必须决定这些事情。 但其中最重要的可能是考虑可读性高于效率,使该守则更能维持下去,并产生在你赢得失败后出现的节目制作者能够滥用的意向书和行为。 在你的设计中预先防范虐待,无论你使用什么。

海事组织的建筑商在制造物体时不会形成一种好的信号灯,特别是在论据数量大而且相同的情况下。

new Person(String, String, String, String); // what the?? this is what may 
                                            // show up in IDEs

实际指人(第一名、最后名、筛选姓名、密码(例如为了)

正如图象提到的那样,连接链的建筑模式是好的。 另一个advantage with a Buildinger is that, if the Object are immutable, the Buildinger can re the same Object (在这种情况下,只有建筑商才知道有15个动力的一揽子私人建筑商。) 建设者还可以返回它们建造的物体的任何亚类

你可以采取的另一个办法是使用内部的DSL。 但是,只有当你建造像组合、问询等物体时,才有意义。 参见,如果有一个内部的《家庭法》对你来说是有意义的。

我们的项目也存在同样的问题。 我们必须从家门(家门产品)引出某些价值。 它支持一项请求答复,即基于XML协议的查询。 但是,在《国际不动产合同》中设定发送请求标语是荒谬的,因此设立了附有适当参数和过滤器等的索要信。

最初,我们的请求反对这样做:

Request r = new Request("SET");
r.setAction("add"); // modify, add, delete
r.setModuleName("NPWIFI"):
r.addParameter(new Param("wifiAclMac", "aa:bb:cc:dd:ee:ff"));
r.addParameter(new Param("wifiCommit", "commit"));
r.setActionParam("wifiAclRowStatus")
r.addFilter(new Filter(Type.EQUALS, "wifiInterface", "wl0"));
r.addFilter(new Filter(Type.EQUALS, "wifiAclMac", "yourgateway"));

Resonse r = gwSession.sendRequest(r);

因此,我们把它变成了内部的DSL,它有同样的感觉,但只是方案性的。

Query q = DQL.add("wifiAclMac", "wifiCommit").into("NPWIFI").values
            ("aa:bb:cc:dd:ee:ff", "commit").withAp("wifiAclRowStatus")
            .where("wifiInterface").is("wl0")
            .and("wifiAclMac").is("aa:bb:cc:dd:ee:ff").end();

DQL的“建筑商”标的都是经过验证的建筑,也证明是十分方便使用的。

建筑商和DSLs是创造和建造物体的有利而有力的手段,但你认为情况是有意义的。

这很难抽象地回答。 我们需要做的是研究这10个参数,看它们是什么。 我将这些问题视为关键问题:

  • Can some of them be combined into higher level "value" objects? For example, variables X and Y can be combined into Point. We had lots of situations like this within a cargo routing program where all fields were modeled as primitive strings. Introducing a few higher level concepts really helped make it readable.
  • Can some of the parameters be "defaulted" to certain values?
  • Are they really all independent, orthogonal concepts? I ve worked on lots of systems and never seen this to be true. If not, there is some thinking to do about these.

我会避免提出大量论点的建筑商。 在建筑商中有许多论点的阶层可能不舒服。 如果你拥有遗产继承等级,每个等级在建筑中都有许多论点。 如果需要改变一些高层阶层的论点,将有多少工作要做。

我会通过一个与你的主子的接口,否则你会改变这一接口,或者使用 Java豆方法,没有一家富有的建筑商。

您的田地可以合并为一个中间物体? 例如,如果你在描述一个人的10个田里穿过,那么就会产生个人信息标语,以便通过这些数据。 我个人宁愿在提出反对时,在所有必要的领域通过。 这样,你就不再以不可避免使用和滥用的半衰弱的物体结束。

如果实际需要所有参数,而且你又不使用春天来瞬息息,我肯定会与一个有10个参数的建筑商接触。 这清楚表明,事实上,所有参数都需要。

如果你(也许偶尔会)做你春天造就灯塔,或者你真的不喜欢在造标方法中产生许多临时变量,那么你也可以使用洗衣机和板。 如果你也采用一种验证方法,检查物体是否正确,那么你不应有问题。

然而,如果你一致使用,验证方法则最为有效;也许可以通过具有验证界面。 如果它成为方案拟订方式的一部分,它就非常适合工作流程。 如果只使用一种或两种模式,则可能不值得使用。 你们会忘记,在某个地方,不管怎么说,都肯定了。

如果你不采用有效的代位办法,不喜欢施工人(尽管我不知道为什么,那是他所要的东西),你总是会回落到其他人提到的建筑商。

对于其价值来说,如果你有10个需要论据,而且你无法按逻辑将其归为一类,你可能只是一个类别中的许多不同概念混在一起;在这种情况下,也许更能很好地看待你的设计,并重新思考一下。





相关问题
热门标签