Java中全参构造函数数_在Java中管理具有许多参数的构造函数

在我们的一些项目中,有一个类层次结构,当它沿着链向下时添加更多的参数。在底部,一些类可以有多达30个参数,其中28个参数刚刚被传递到超级构造函数中。

我承认使用Guice这样的自动化DI会很好,但是由于一些技术上的原因,这些特定的项目被限制在Java上。

按类型按字母顺序组织参数的约定不起作用,因为如果类型被重构(您为参数2传递的圆现在是一个形状),它可能会突然出现无序。

这个问题可能是具体的,充满了"如果这是你的问题,你在设计层面上做的不对"的批评,但我只是在寻找任何观点。

生成器设计模式可能会有所帮助。考虑下面的例子

public class StudentBuilder

{

private String _name;

private int _age = 14;      // this has a default

private String _motto =""; // most students don't have one

public StudentBuilder() { }

public Student buildStudent()

{

return new Student(_name, _age, _motto);

}

public StudentBuilder name(String _name)

{

this._name = _name;

return this;

}

public StudentBuilder age(int _age)

{

this._age = _age;

return this;

}

public StudentBuilder motto(String _motto)

{

this._motto = _motto;

return this;

}

}

这样我们就可以像

Student s1 = new StudentBuilder().name("Eli").buildStudent();

Student s2 = new StudentBuilder()

.name("Spicoli")

.age(16)

.motto("Aloha, Mr Hand")

.buildStudent();

如果我们去掉了一个必需的字段(假定名称是必需的),那么我们可以让学生构造函数抛出一个异常。它允许我们使用默认/可选参数,而不需要跟踪任何类型的参数顺序,因为这些调用的任何顺序都将同样有效。

当然,对于静态导入,您甚至根本不必"看到"这些"构建者"。例如,可以有静态方法名(字符串名),它返回生成器,学生(student builder)返回学生。因此,学生(姓名("乔")。年龄(15岁)。座右铭("我弄湿了自己");

@Oxbow_Lakes:在您的示例中,哪个类有静态方法名(字符串名)?

从技术上讲,利用学生班来培养一个新的学生是可能的。我在学生班里添加了一些方法,效果很好。这样我就不需要再有一个建设者类了。不过,我不确定这是否可取。是否有理由使用另一个(studentbuilder)类来构建它?

@WVRock:这取决于您的实现。正如我在回答中所说,对学生类本身执行此操作可能会使类处于半初始化状态,例如,如果您有尚未初始化的必选字段。

@Elicourtwright我想这是关于偏好/代码设计的。不是让构造函数抛出异常,而是让buildStudent()方法抛出异常。

我会说,这是一个很好的解决方案

你能在一个对象中封装相关参数吗?

例如,如果参数如下

MyClass(String house, String street, String town, String postcode, String country, int foo, double bar) {

super(String house, String street, String town, String postcode, String country);

this.foo = foo;

this.bar = bar;

然后你可以有:

MyClass(Address homeAddress, int foo, double bar) {

super(homeAddress);

this.foo = foo;

this.bar = bar;

}

您可能想做的是创建一个生成器类。然后你会这样做:

MyObject obj = new MyObjectBuilder().setXxx(myXxx)

.setYyy(myYyy)

.setZzz(myZzz)

// ... etc.

.build();

请参阅第8页和下面的Josh Bloch演示文稿(PDF),或对有效Java的回顾

好吧,使用构建器模式可能是一种解决方案。

但一旦你达到20到30个参数,我想参数之间有很高的关系。因此(如建议的那样)将它们包装成逻辑上健全的数据对象可能是最有意义的。这样,数据对象就可以检查参数之间约束的有效性。

对于我过去的所有项目,一旦我达到了有太多参数的地步(那是8而不是28!)我可以通过创建更好的数据模型来清理代码。

当您被限制为Java 1.4时,如果您想要DI,那么Spring将是一个非常不错的选择。DI仅在构造函数参数为服务或运行时不变化的地方有用。

如果您有所有这些不同的构造器,因为您需要关于如何构造对象的变量选项,那么您应该认真考虑使用构建器模式。

正如您所提到的,参数主要是服务,所以DI是我需要的。我认为其他几个答案中提到的构建器模式正是我所希望的。

最好的解决方案是在构造函数中没有太多参数。构造函数中真正需要的参数是需要正确初始化对象的参数。可以有多个参数的构造函数,也可以有一个只有最小参数的构造函数。附加的构造函数调用这个简单的构造函数,并在该setter之后设置其他参数。这样可以避免使用越来越多的参数时出现链问题,但也有一些方便的构造函数。

我真的可以推荐在使用构建器模式时使用不可变项或pojobuilder。

重构以减少参数的数量和继承层次结构的深度几乎是我能想到的,因为没有什么能真正帮助保持20多个参数的正态性。在查看文档时,您只需要每次打电话。

您可以做的一件事是,将一些逻辑分组的参数分组到它们自己的更高级别对象中,但这有它自己的问题。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值