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
- Do we need
private
properties? It's just a wrapper class. Is there any reason to not expose wrapper properties? - 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. - 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
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?