[Java] 객체 생성 방법

728x90

객체 생성 3가지 방법론

자바에서 객체를 생성하는 3가지 기본적인 방법에 대해 순서대로 알아보자.

  • 생성자 (Constructor)
  • 빌더 패턴
  • 정적 팩토리 메서드

 

생성자(Constructor)를 통한 객체 생성

생성자는 객체의 필드를 초기화하는 기본적인 방법이다.

생성자의 형태에 따라 필드 값이 설정되는 시점이 달라지며 객체의 완전성과 불변성을 보장할 수 있다.

 

기본 생성자 + 수정자(Setter)를 통한 객체 생성

기본 생성자는 필드를 초기화하지 않고 빈 객체를 생성한 뒤 필요한 필드 값을 수정자를 통해 주입하는 방식이다.

이 방식의 장점은 빈 객체를 먼저 생성할 수 있어 나중에 원하는 필드를 선택적으로 설정할 수 있다는 것이다.

하지만 불필요하게 필드를 수정할 가능성이 있기 때문에 객체의 불변성(Immutability)을 보장하지 못할 수 있다.

public class Member {
    private String name;
    private String email;

    public Member() {}  // 기본 생성자

    public void setName(String name) {
        this.name = name;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

// 객체 생성 예시
Member aaron = new Member();
aaron.setName("fabric0de");
aaron.setEmail("fabric0de@example.com");

 

커스텀 생성자를 통한 객체 생성

필드 값을 생성 시점에 전달하여 객체를 완성하는 방식이다.

필요한 필드만 포함한 생성자를 만들 수 있다. 이 방식은 필수적으로 설정해야 하는 필드에 대해 강제성을 부여할 수 있어 객체의 완전성(Completeness)을 높인다.

public class Member {
    private String name;
    private String email;

    public Member(String name) {
        this.name = name;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

// 객체 생성 예시
Member aaron = new Member("fabric0de");
aaron.setEmail("fabric0de@example.com");

 

DTO를 이용한 생성자

DTO(Data Transfer Object)는 데이터를 전달하기 위한 객체이다. 생성자를 통해 DTO로부터 객체를 생성할 수 있다.

이 방식은 여러 필드를 한 번에 설정해야 하는 상황에서 유용하며 DTO에서 필요한 필드만 골라서 객체를 초기화할 수 있다.

public class Member {
    private String name;
    private String email;

    public Member(MemberRequestDto dto) {
        this.name = dto.getName();
        this.email = dto.getEmail();
    }
}

// 객체 생성 예시
MemberRequestDto dto = new MemberRequestDto("fabric0de", "fabric0de@example.com");
Member aaron = new Member(dto);

 

빌더 패턴을 통한 객체 생성

빌더 패턴은 객체 생성 시 필드 값 주입 순서에 구애받지 않으며 선택적으로 필드 값을 설정할 수 있는 유연한 방식이다. 

객체가 복잡하거나 많은 필드를 가진 경우 특히 유리하다.

빌더 패턴은 기본적으로 아래와 같이 사용한다. 

@Builder
public class Member {
    private String name;
    private String email;
}

// 객체 생성 예시
Member aaron = Member.builder()
        .name("fabric0de")
        .email("fabric0de@example.com")
        .build();

 

빌더 패턴은 다음과 같은 장점이 있다.

  • 필드 선택성: 필요한 필드만 설정할 수 있다.
  • 필드 순서 무관: 필드 설정 순서에 구애받지 않다.
  • 유연한 객체 생성: 필드 주입을 분리하여 상황에 따라 객체를 생성할 수 있다.

빌더 패턴의  활용

빌더 패턴은 다양한 방식으로 커스터마이징이 가능하다.

필드에 기본값을 설정하거나 컬렉션을 위한 @Singular 어노테이션 등을 사용할 수 있다.

@Builder
public class Member {
    private Integer id;
    @Builder.Default
    private String name = "Unnamed";
    private String email;
    @Singular
    private List<String> favorites;
}

// 객체 생성 예시
Member baron = Member.builder()
        .name("fabric0de")
        .email("fabric0de@example.com")
        .favorite("Reading")
        .favorite("Traveling")
        .build();

 

정적 팩토리 메서드(Static Factory Method)

정적 팩토리 메서드는 객체 생성 방식을 하나로 통합할 수 있는 방법이다.

이름을 부여할 수 있어 가독성이 높고 객체 생성을 캡슐화할 수 있다.

정적 팩토리 메서드 방식은 아래와 같이 사용한다.

public class Member {
    private Integer id;
    private String name;
    private int age;
    private String email;

    private Member(Integer id, String name, int age, String email) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.email = email;
    }

    public static Member from(MemberCreateRequestDto dto) {
        return new Member(null, dto.getName(), 0, dto.getEmail());
    }
}

// 객체 생성 예시
MemberCreateRequestDto dto = new MemberCreateRequestDto("fabric0de", "fabric0de@example.com");
Member fabric0de = Member.from(dto);

정적 팩토리 메서드는 다음과 같은 장점이 있다

  • 메서드 이름을 가질 수 있음: 가독성이 좋아진다.
  • 싱글턴 패턴 활용 가능: 객체 생성을 제어할 수 있다.
  • 객체 생성을 캡슐화: 객체 생성 로직을 외부에서 숨길 수 있다.

 

728x90

'Backend > Java' 카테고리의 다른 글

[Java] Final 이란?  (0) 2024.10.15
[Java] DTO와 VO의 차이점  (0) 2024.10.15
[Java] 자바 캡슐화의 이해 (Encapsulation)  (2) 2024.10.09
[Java] JVM : Java Virtual Machine  (0) 2024.10.08
[Java] Exception - 자바 예외 처리  (1) 2024.10.07