다음과 같은 멤버변수를 가진 객체가 있다.
public class Member {
private final String email;
private final String password;
private final String name;
private final String address;
private final String phone;
}
인스턴스를 생성하고 값을 초기화 하려면 어떤 방법이 있을까?
- 생성자를 사용
- setter 메소드 사용
- 빌더 사용
... etc
1. 생성자 사용
- 생성자를 이용해 생성과 초기화를 한다.
- 생성과 동시에 초기화를 하므로 final 사용 할 수 있다.
public class Member {
private final String email;
private final String password;
private final String name;
private final String address;
private final String phone;
public Member(String email, String password, String name, String address, String phone) {
this.email = email;
this.password = password;
this.name = name;
this.address = address;
this.phone = phone;
}
public Member(String email, String password, String name) {
this(email, password, name, null, null);
}
public Member(String email, String password) {
this(email, password, null, null, null);
}
...
}
테스트
public class Test {
public static void main(String[] args) {
Member member1 = new Member("email@naver.com", "1234", "kim");
Member member2 = new Member("email@naver.com", "1234", "kim", "seoul", "01012341234");
System.out.println("member1 = " + member1);
System.out.println("member2 = " + member2);
}
}
단점
- 멤버변수가 늘어날 경우 생성자의 매개변수가 길어진다.
- 필수 값과 선택 값에 따라서 다양한 생성자가 필요하다.
- 매개변수의 순서가 중요하고 각각이 무엇을 의미하는지 직관적으로 알기 어렵다.
2. setter 메소드 사용
- 객체를 생성하고 setter 메소드를 호출하여 값을 초기화 한다.
- 원하는 값을 지정하여 초기화 할 수 있다.
- 메소드 명으로 어떤 변수에 값이 초기화 되는지 직관적으로 알기 쉽다.
private String email;
private String password;
private String name;
private String address;
private String phone;
public void setEmail(String email) {
this.email = email;
}
public void setPassword(String password) {
this.password = password;
}
public void setName(String name) {
this.name = name;
}
public void setAddress(String address) {
this.address = address;
}
public void setPhone(String phone) {
this.phone = phone;
}
...
}
테스트
- 어떤 값이 초기화 되는지 직관적으로 알 수 있다.
public class Test {
public static void main(String[] args) {
Member member = new Member();
member.setEmail("email@naver.com");
member.setPassword("1234");
member.setName("kim");
System.out.println("member = " + member);
}
}
단점
- 객체를 생성하고 나서 여러 메소드를 호출해야 한다.
- final을 사용할 수 없다.
- 객체를 생성하고 초기화한 이후에도 값이 변경 될 수 있다.
3. 빌더 패턴 사용
- Member 객체를 만드는 MemberBuilder 클래스를 만든다.
여기서는 내부 클래스로 만들었다.
- 빌더클래스의 setter메소드들은 각 값을 받아 각 멤버변수에 담고 자신을 리턴한다.
- 따라서 연쇄적으로 메소드들을 호출 할 수 있다.
- 빌더 클래스에서 값을 초기화 한 후 최종적으로 Member 의 생성자를 호출한다.
- final 사용 가능.
public class Member {
private final String email;
private final String password;
private final String name;
private final String address;
private final String phone;
public Member(String id, String password, String name, String address, String phone) {
this.email = id;
this.password = password;
this.name = name;
this.address = address;
this.phone = phone;
}
public static MemberBuilder builder() {
return new MemberBuilder();
}
public static class MemberBuilder {
private String email;
private String password;
private String name;
private String address;
private String phone;
private MemberBuilder() {
}
public MemberBuilder email(String email) {
this.email = email;
return this;
}
public MemberBuilder password(String password) {
this.password = password;
return this;
}
public MemberBuilder name(String name) {
this.name = name;
return this;
}
public MemberBuilder address(String address) {
this.address = address;
return this;
}
public MemberBuilder phone(String phone) {
this.phone = phone;
return this;
}
public Member build() {
return new Member(email, password, name, address, phone);
}
}
...
}
테스트
- 어떤 값이 초기화 되는지 직관적으로 알 수 있다.
public class Test {
public static void main(String[] args) {
Member member = Member.builder()
.email("email@naver.com")
.name("kim")
.password("1234")
.build();
System.out.println("member = " + member);
}
}
단점
코드