Skip to main content
Became Hot Network Question
added 360 characters in body
Source Link
Piotr Gajek
  • 2.9k
  • 1
  • 11
  • 28
  • When all fields in the wrapper are "required", a wrapper without all fields populated has no sense.
  • When you need to hide class properties (private) and expose them only via getters.
  • When you work with SObject.
public class Person {
    private String id;
    private String firstName;
    private String lastName;
    private Integer age;
    private Integer height; 
    //other fields

    public Person(User user) {
        this.id = user.Id;
        this.firstName = user.FirstName;
        //etc
    }
}
  • You have just a few fields e.g
  • When all fields in the wrapper are "required", a wrapper without all fields populated has no sense.
  • When you need to hide class properties (private) and expose them only via getters.
  • You have just a few fields e.g
  • When all fields in the wrapper are "required", a wrapper without all fields populated has no sense.
  • When you need to hide class properties (private) and expose them only via getters.
  • When you work with SObject.
public class Person {
    private String id;
    private String firstName;
    private String lastName;
    private Integer age;
    private Integer height; 
    //other fields

    public Person(User user) {
        this.id = user.Id;
        this.firstName = user.FirstName;
        //etc
    }
}
  • You have just a few fields e.g
Source Link
Piotr Gajek
  • 2.9k
  • 1
  • 11
  • 28

How to populate wrapper's properties?

The question is about the best practices when working with the Wrapper class.

Assumptions

We have PersonWrapper.

public class PersonWrapper {
    private String id;
    private String firstName;
    private String lastName;
    private Integer age;
    private  Integer height; 
    //other fields
}

Questions

  1. Do we need private properties? It's just a wrapper class. Is there any reason to not expose wrapper properties?
  2. What is the best way to populate Wrapper properties/fields?

A. Constructor

public class PersonWrapper {
    private String id;
    private String firstName;
    private String lastName;
    private Integer age;
    private Integer height; 
    //other fields

    public PersonWrapper(
       String id,
       String firstName,
       String lastName,
       Integer age,
       Integer height
    ) {
       this.id = id;
       this.firstName = firstName;
       this.lastName = lastName;
       this.age = age;
       this.height = height;
    }
}

PersonWrapper person = new PersonWrapper('123', 'John', 'Wick', 35, 185);

B. Direct assignment

public class PersonWrapper {
    public String id;
    public String firstName;
    public String lastName;
    public Integer age;
    public Integer height; 
    //other fields
}

PersonWrapper person = new PersonWrapper();
person.id = '123';
person.firstName = 'John';
person.lastName = 'Wick';
person.age = 35;
person.height = 185;

C. Builder

public class PersonWrapper {
    public String id;
    public String firstName;
    public String lastName;
    public Integer age;
    public Integer height; 
    //other fields
}

public class PersonWrapperBuilder {
    private PersonWrapper person;

    public PersonWrapperBuilder() {
        this.person = new PersonWrapper();
    }

    public PersonWrapperBuilder setId(String id) {
        this.person.id = id;
        return this;
    }

    public PersonWrapperBuilder setFirstName(String firstName) {
        this.person.firstName = firstName;
        return this;
    }

    //etc

    public PersonWrapper build() {
        return this.person;
    }
}

PersonWrapper person = 
   new PersonWrapperBuilder()
      .setId('123')
      .setFirstName('John')
      .build();

D. Something else?

My thoughts

Use Map<String, Object>

  • Do not overcomplicate. Map<String, Object> can replace simple wrappers. Especially when the wrapper will be used in one place.
return new Map<String, Object>{
    'id' => '123',
    'firstName' => 'John',
    'lastName' => 'Wick',
    'age' => 35,
    'height' => 185
};

Use constructor

  • When all fields in the wrapper are "required", a wrapper without all fields populated has no sense.
  • When you need to hide class properties (private) and expose them only via getters.
  • You have just a few fields e.g
public class Point {
   private Integer x; 
   private Integer y;

   public Point(Integer x, Integer y) {
      this.x = x;
      this.y = y;
   }
}

Use direct assignment

  • Use it for most cases to not complicate the logic.

Builder

  • When need to create wrapper step by step.
  • When additional validation/transformation is needed before the field is populated.
public PersonWrapperBuilder setFirstName(String firstName) {
    this.person.firstName = firstName.toUpperCase();
    return this;
}

Do you agree, disagree? Have some other thoughts, rules?