-1

Many times I'm faced with a class which constructor method must contain list of arguments that is identical with the list of class instance variables.

As you see in the example there is "SOME" code to make this hapend. I'm wondering how can I make this process less painful?

Example:

public class VimeoUser extends Schema {

    @Getter @Setter private String uri;
    @Getter @Setter private String name;
    @Getter @Setter private String link;
    @Getter @Setter private String location;
    @Getter @Setter private String bio;
    @Getter @Setter private String createdTime;
    @Getter @Setter private String account;

    @Getter @Setter private Map<String,Integer> statistics = new HashMap<>();

    @Getter @Setter private List<Website> websites = new ArrayList<>();
    @Getter @Setter private List<Portrait> portraits = new ArrayList<>();

    public VimeoUser(
            String uri,
            String name,
            String link,
            String location,
            String bio,
            String createdTime,
            String account,
            Map<String,Integer> statistics,
            List<Website> websites,
            List<Portrait> portraits){

    this.uri = uri;
    this.name = name;
    this.link = link;
    this.location = location;
    this.bio = bio;
    this.createdTime = createdTime;
    this.account = account;
    this.statistics = statistics;
    this.websites = websites;
    this.portraits = portraits;

    }
}

4 Answers4

2

It is possible to use a pattern named Builder. It is explained in this question

Basically it works as following:

  • Create an inner static class Builder
  • Create a private constructor that take as an argument an object of type Builder
  • In the Builder class add methods that set a single value and returns this (current reference to instance of the Builder class)
  • In the body of the constructor of your class use the values passed in the Builder to set each property
  • add a method build in the Builder that calls the private constructor of your class

Here is an example:

public class NutritionalFacts {
    private int sodium;
    private int fat;
    private int carbo;

    public class Builder {
        private int sodium;
        private int fat;
        private int carbo;

        public Builder(int s) {
            this.sodium = s;
        }

        public Builder fat(int f) {
            this.fat = f;
            return this;
        }

        public Builder carbo(int c) {
            this.carbo = c;
            return this;
        }

        public NutritionalFacts build() {
            return new NutritionalFacts(this);
        }
    }

    private NutritionalFacts(Builder b) {
        this.sodium = b.sodium;
        this.fat = b.fat;
        this.carbo = b.carbo;
    }
}

and to use it do the following:

NutritionalFacts nutritionalFacts = new NutritionalFacts.Builder()
        .fat(200).carbo(50).build();

Using this pattern instead of pojo with setter and getter is useful because it is possible to use it also to build immutable objects (objects with all final fields). An immutable object is useful if you need to share it on a multithreaded environment because it is not necessary to synchronize the access to it.

Additionally it is possible to add some controls in the build method to be sure that all fields are setted as expected.

Community
  • 1
  • 1
Davide Lorenzo MARINO
  • 26,420
  • 4
  • 39
  • 56
  • Instead of linking to another post, summarize it here with a concise syntax example in case of the linked post being edited substantially, deleted, etc. – nanofarad Jan 16 '16 at 11:40
  • @Hexafraction you are right. I added an example and the explanation to show how to use it and why it is useful to use it – Davide Lorenzo MARINO Jan 16 '16 at 11:51
1

I guess writing pojos for database modelling does not necessarily needs constructor other than default no-arg constructor. If anyway required in some situations, Getters and setters can be used.

yuvraj
  • 147
  • 1
  • 9
  • The pojos need to contain all arguments to be passed in constructor to notify developer what list of information instance needs so he is required to pass the list of arg. in constructor. I'm flaging this answ. as low quality. –  Jan 16 '16 at 11:06
  • 2
    @urosjarc Do not use VLQ flags for content disputes. They are for severe unsalvageable answers, which this is not. Use downvotes instead. Anyway, what's wrong with a default constructor, and all setters called? You can always check preconditions of all required non-null fields filled before storing it to a database. – nanofarad Jan 16 '16 at 11:39
1

Builder pattern

If you want create a object with more readable way, you can use a simple builder pattern. Lombok support this such as @Getter or @Setter. You just add @Builder annotation and everything should works fine.

@Getter
@Builder
public class SomeClass {
    private final String valueOne;
    private final String valueTwo;
}

And then you can create object in this way.

SomeClass someClass = SomeClass.builder()
        .valueOne("one")
        .valueTwo("two")
        .build();

Fluent accessors method

Alternative way to create a class is using @Accessors annotation with fluent = true. Then you can create a empty object and set the value what you needed in simple way.

@Getter
@Setter
@Accessors(fluent = true)
public class SomeClass {
    private String valueOne;
    private String valueTwo;
}

Simple sample using this way.

SomeClass someClass = new SomeClass()
        .valueOne("one")
        .valueTwo("two");
Mateusz Korwel
  • 1,118
  • 1
  • 8
  • 14
0

I see you are already using Lombok. There is a @AllArgsConstructor class-level annotation that will generate the constructor for you. If you want the default constructor, too, use @NoArgsConstructor additionally.

More info on the constructor-generating annotations here.

Adam Michalik
  • 9,678
  • 13
  • 71
  • 102