как уменьшить код перегрузки конструктора - PullRequest
1 голос
/ 21 марта 2011

В одном классе у меня много таких конструкторов ..

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

}

и некоторые другие, как указано выше. Теперь время вызова, я вызываю этот конструктор только для тех данных, которые мне нужны. но я не думаю, что мой поток хорош, поэтому мне нужна помощь, чтобы уменьшить мой код, а также создать хороший поток. Если у кого-то есть хороший поток для этого, пожалуйста, поделитесь.

Заранее спасибо.

Ответы [ 2 ]

5 голосов
/ 21 марта 2011

Предполагая, что вы эффективно применяете значения по умолчанию, обычно лучше всего иметь один «полный» конструктор и заставить другие вызывать его.Например:

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

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

Вы по-прежнему сталкиваетесь с большими перебоями с точки зрения перегруженных конструкторов, но по крайней мере каждый из этих «дополнительных» конструкторов не содержит реального кода - просто вызов другого конструктора.Если возможно, соедините конструкторы вместе, чтобы значение по умолчанию для любого конкретного значения было указано только в одном месте, или используйте константу.Таким образом, вы получаете согласованность.

Другой вариант - использовать «объект параметра» по шаблону компоновщика - создать другой класс, единственная цель которого - хранить данные для параметров конструктора.Это должно быть изменяемым, с установщиками для всех различных значений.Часто бывает полезно, чтобы установщики возвращали компоновщик, поэтому вы можете использовать:

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, хотя лично я не заинтересован в том, как он перегружает имена методов, чтобы либо вернуть значение, либо установить значение в зависимости от того, предоставлен ли аргумент: (

Обратите внимание на комментарий над вызовом конструктора в последнем фрагменте - если ваш вспомогательный класс полезен только для создания объектов одного типа, вы можете назначить ему дополнительный метод (build, create, start, независимо от того, чтонаиболее подходящим), чтобы занять место вызова конструктора. Это позволяет вам быстро построить весь конечный объект.

Один вариант в реализации Java шаблона компоновщика - использовать вложенный тип, например

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

Это позволяет избежать загрязнения вашего пакета другим классом, который only полезен для создания экземпляров Foo.

3 голосов
/ 21 марта 2011

Возможно, вы захотите иметь другой объект, который отвечает за создание объекта по шаблону builder . Например, вы можете определить объект следующим образом:

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, вы можете написать

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

Преимущество этого подхода заключается в том, что вы можете установить разумное значение по умолчанию для всех параметров, а затем просто вызвать соответствующие функции set для параметров, которые вы фактически используете. Это также позволяет легко добавлять новые параметры, не возвращаясь и не переписывая важный код.

В качестве альтернативы, как отмечает Джон Скит, у вас может быть несколько конструкторов, которые все вызывают друг друга. Преимущество шаблона построителя по сравнению с этим подходом состоит в том, что если у вас n различных параметров, вам нужно написать 2 n комбинаций конструкторов, тогда как вам нужен только один построитель.

Надеюсь, это поможет!

...