当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《在Java中管理具有许多参数的构造函数》经验,为你挑选了4个好方法。

在我们的一些项目中,有一个类层次结构,它在链中向下添加更多参数.在底部,一些类可以有多达30个参数,其中28个只是被传递给超级构造函数.

我会承认,通过像Guice之类的东西使用自动化DI会很好,但由于某些技术原因,这些特定项目仅限于Java.

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

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



1> Eli Courtwri..:

Builder Design Pattern可能有所帮助.请考虑以下示例

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构造函数抛出异常.它允许我们拥有默认/可选参数,而无需跟踪任何类型的参数顺序,因为这些调用的任何顺序都可以同样有效.


当然,对于静态导入,您甚至根本不必"看到"这些"构建器".例如,您可以使用返回构建器的静态方法name(String name)和返回学生的Student(StudentBuilder).因此学生(姓名("Joe").年龄(15).motto("我自己弄湿了"));
@oxbow_lakes:在你的例子中,哪个类有静态方法名(String name)?

2> JeeBee..:

你可以在对象中封装相关参数吗?

例如,如果参数是这样的


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;
}



3> Michael Myer..:

您可能想要做的是拥有一个Builder类.然后你会做这样的事情:

MyObject obj = new MyObjectBuilder().setXxx(myXxx)
                                    .setYyy(myYyy)
                                    .setZzz(myZzz)
                                    // ... etc.
                                    .build();

请参阅第8页以及此Josh Bloch演示文稿(PDF)或此有效Java评论



4> 小智..:

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

但是一旦你得到20到30个参数,我猜测参数之间存在很高的关系.所以(如建议的那样)将它们包装成逻辑上理智的数据对象可能是最有意义的.这样,数据对象就已经可以检查参数之间约束的有效性.

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

推荐阅读
wurtjq
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有