如何减少构造函数重载的代码

发布于 2024-10-23 20:25:54 字数 608 浏览 3 评论 0原文

在我的一堂课中,我有很多这样的构造函数......

public MyData(int position,String songName,String duration, boolean e) {

    //initialization of above variable like int, string,string and boolean

}

public MyData(String songName, String artistName, String duration,String downloadPath, String songSize, String albumName,String url,String trackId, boolean e) 
{
 //initialization of above variable like String,String,String,String,String,String,String,String and boolean

}

还有一些像上面这样的构造函数。 现在是调用时间,我只在需要数据时调用该构造函数。但我不认为我的流程很好,所以我需要一些帮助来减少我的代码以及创建良好的流程。 如果有人有很好的流程来实现这一点,请分享。

提前致谢。

In my one class I have many constructors like this..

public MyData(int position,String songName,String duration, boolean e) {

    //initialization of above variable like int, string,string and boolean

}

public MyData(String songName, String artistName, String duration,String downloadPath, String songSize, String albumName,String url,String trackId, boolean e) 
{
 //initialization of above variable like String,String,String,String,String,String,String,String and boolean

}

and some more like above.
Now the calling time, I'm calling that constructor only that I require data. but I don't think my flow is good so I need some help to reduce my code as well as creation of good flow.
If anybody have a good flow to achieve this, then please share.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

铁憨憨 2024-10-30 20:25:54

假设您有效地应用默认值,通常最好的方法是拥有一个“完整”构造函数并让其他构造函数调用它。例如:

public Foo(String name)
{
    // Default the description to null
    this(name, null);
}

public Foo(String name, String description)
{
    this.name = name;
    this.description = description;
}

在重载构造函数方面,您仍然会遇到很多麻烦,但至少每个“额外”构造函数都不包含实际代码 - 只是对另一个构造函数的调用。如果可能,将构造函数链接在一起,以便仅在一个位置指定任何特定值的默认值 - 或使用常量。这样你就可以获得一致性。

另一种选择是使用遵循构建器模式的“参数对象” - 创建另一个类,其唯一目的是保存构造函数参数的数据。这应该是可变的,具有所有不同值的设置器。通常,让 setter 返回构建器很有用,因此您可以使用:

FooParameters parameters = new FooParameters()
    .setName("some name")
    .setDescription("some description");

// Either a constructor call at the end, or give FooParameters
// a build() or create() method
Foo foo = new Foo(parameters);

如果您正在构造的主要类型是不可变类型,则这特别有用 - 这意味着您可以在调用代码中应用条件逻辑来设置某些参数,但不能其他的。 Java 框架本身在 ProcessBuilder 中使用了这种方法,尽管我个人并不热衷于它重载方法名称以根据是否提供参数来返回值或设置值的方式:(

注意最后代码片段中构造函数调用上方的注释 - 如果您的辅助类仅对创建单一类型的对象有帮助,您可以为其提供一个额外的方法(buildcreate,start,无论什么是最合适的)来代替构造函数调用,这允许您以流畅的方式构建整个最终对象

。是使用嵌套类型,例如

Foo foo = new Foo.Builder().setName(...).setDescription(...).build();

,避免使用另一个类污染您的包,该类对于构建Foo的实例有用。

Assuming you're effectively applying defaults, usually the best approach is to have one "full" constructor and make the others call it. For example:

public Foo(String name)
{
    // Default the description to null
    this(name, null);
}

public Foo(String name, String description)
{
    this.name = name;
    this.description = description;
}

You still end up with quite a lot of cruft in terms of overloaded constructors, but at least each of those "extra" constructors contains no actual code - just a call to another constructor. If possible, chain the constructors together so that the default for any particular value is only specified in one place - or use a constant. That way you get consistency.

Another option is to use a "parameter object" following the builder pattern - create another class whose sole purpose is to hold the data for the constructor parameters. This should be mutable, with setters for all of the different values. Often it's useful to make the setters return the builder, so you can use:

FooParameters parameters = new FooParameters()
    .setName("some name")
    .setDescription("some description");

// Either a constructor call at the end, or give FooParameters
// a build() or create() method
Foo foo = new Foo(parameters);

This is particularly useful if the main type you're constructing is an immutable type - it means you can apply conditional logic in the calling code to set some parameters but not others. The Java framework itself uses this approach in ProcessBuilder, although personally I'm not keen on the way it overloads method names to either return a value or set a value based on whether you provide an argument :(

Note the comment above the constructor call in the final snippet - if your helper class is only ever helpful for creating objects of a single type, you can give it an extra method (build, create, start, whatever is most appropriate) to take the place of the constructor call. This allows you to build the whole final object in a fluent way.

One option in the Java implementation of the builder pattern is to use a nested type, e.g.

Foo foo = new Foo.Builder().setName(...).setDescription(...).build();

That avoids polluting your package with another class which is only useful for building instances of Foo.

︶葆Ⅱㄣ 2024-10-30 20:25:54

您可能希望有另一个对象负责通过构建器模式创建对象。例如,您可以定义这样的对象:

public class SongBuilder {
    private String artistName;
    private String songTitle;
    /* ... everything else ... */

    public SongBuilder setArtistName(String name) {
        this.artistName = name;
        return this;
    }
    public SongBuilder setSongTitle(String title) {
        this.songTitle = title;
        return this;
    }
    /* ... everything else ... */

    public Song create() {
         return new Song(artistName, songTitle, /* ... everything else ... */);
    }
}

然后,您可以为 Song 定义一个接受所有数据的构造函数。要制作歌曲,您可以编写

 Song s = new SongBuilder().setSongTitle("Still Alive").setArtistName("GLaDOS").create();

这种方法的优点是您可以为所有参数设置合理的默认值,然后只需为参数调用适当的set函数你实际使用的。它还允许您轻松添加新参数,而无需返回并重写重要代码。

或者,正如 Jon Skeet 指出的那样,您可以拥有多个互相调用的构造函数。与此方法相比,构建器模式的优势在于,如果您有 n 个不同的参数,则需要编写 2n 个构造函数组合,而您只需要一个构建器。

希望这有帮助!

You may want to have another object that is responsible for creating the object through the builder pattern. For example, you could define an object like this:

public class SongBuilder {
    private String artistName;
    private String songTitle;
    /* ... everything else ... */

    public SongBuilder setArtistName(String name) {
        this.artistName = name;
        return this;
    }
    public SongBuilder setSongTitle(String title) {
        this.songTitle = title;
        return this;
    }
    /* ... everything else ... */

    public Song create() {
         return new Song(artistName, songTitle, /* ... everything else ... */);
    }
}

You could then define a single constructor for Song that takes in all the data. To make a Song, you could then write

 Song s = new SongBuilder().setSongTitle("Still Alive").setArtistName("GLaDOS").create();

The advantage of this approach is that you can set a reasonable default for all the parameters, then just call the appropriate set functions for parameters that you actually use. It also allows you to add new parameters easily without having to go back and rewrite important code.

Alternatively, as Jon Skeet points out, you can have multiple constructors that all call one another. The advantage of the builder pattern over this approach is that if you have n different parameters, there are 2n combinations of constructors you'd need to write, whereas you only need one builder.

Hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文