[Spring] 정적 팩토리 메소드 (Static factory method)

백엔ㄷ현·2024년 10월 22일
팀프로젝트 진행중에 팀장 김*희님이 가르쳐 주신 정적 팩토리 메소드를 공부하고 기록으로 남겨본다. 정적 팩토리 메소드는 처음 들어봐서 많이 생소했던 방법이라 기록해두고 수시로 보면서 머리속에 남겨야겠다.

정적 팩토리 메소드(static factory method) 는 객체를 생성하기 위한 메소드를 정적으로 정의한 것이다. 일반적으로 직접 객체를 생성하는 대신, 클래스 내에 정적 메소드를 사용하여 객체를 생성하는 패턴을 말한다. 이 방법은 생성자보다 유연하고 명확한 객체 생성 방식을 제공하는 경우가 많다.



사용하는 이유

  • 가독성 향상 :

    메소드 이름을 사용하여 객체의 용도를 명확히 알 수 있다. 생성자는 클래스 이름만 있으므로 어떤 상황에서 객체가 생성되는지 알기 어렵다.

    // 일반적인 방법
    ProfileResponseDto profile = new ProfileResponseDto(profileEntity);
    // 정적 팩토리 메소드 사용
    ProfileResponseDto profile = ProfileResponseDto.from(profileEntity);
    • from() 메소드는 객체가 Profile 엔티티에서 만들어진다는 것을 직관적으로 알려준다.
  • 유연한 객체 생성 :

    정적 팩토리 메소드를 사용하면 여러 가지 방식으로 객체를 생성할 수 있다. 예를 들어, 특정 조건에 따라 다른 객체를 반환하거나, 캐싱을 통해 같은 객체를 반환할 수 있다.

  • 재사용 가능성 :

    정적 팩토리 메소드는 개체 생성 로직을 한 곳에 집중시켜 재사용할 수 있으므로 중복 코드를 줄이고 유지보수를 쉽게 한다.

  • 객체의 타입을 숨김 :

    인터페이스를 구현한 객체를 생성할 때, 인터페이스 타입만을 반환하는 정적 팩토리 메소드를 사용하면, 구체적인 구현 클래스를 숨길 수 있다.


예시 코드

  • 정적 팩토리 메소드는 보통 from() , of() , valueOf() , getInstance() 등의 이름으로 사용된다.

    @Getter
    public class ProfileResponseDto {
    	private Long id;
    	private String bio;
    	private String profileImage;
    	private Long follower;
    	private Long following;
    
    	// private 생성자
    	private ProfileResponseDto(Long id, String bio, String profileImage, Long follower, Long following) {
    		this.id = id;
    		this.bio = bio;
    		this.profileImage = profileImage;
    		this.follower = follower;
    		this.following = following;
    	}
    
    	// 정적 팩토리 메소드
    	public static ProfileResponseDto from(Profile profile) {
    		return new ProfileResponseDto(
    			profile.getId(),
    			profile.getBio(),
    			profile.getProfileImage(),
    			profile.getFollower(),
    			profile.getFollowing()
    		);
    	}
    }
    이렇게 ResponseDto 에서 생성한 정적 팩토리 메소드를 사용하는 방법은 간단하다. from() 이라는 메소드를 호출하여 Profile 객체로부터 ProfileResponseDto 를 생성한다.
    Profile profile = profileRepository.findById(profileId)
    						.orElseThrow(() -> new IllegalArgumentException("Profile not found"));
     ProfileResponseDto profileResponseDto = ProfileResponseDto.from(profile);


정적 팩토리 메소드를 사용의 장점

  • 더 명확한 객체 생성 :

    from() 이라는 메소드명은 객체가 특정 데이터로부터 생성된다는 것을 명확하게 알려준다.

  • 다양한 객체 생성 :

    필요에 따라 여러 개의 정적 팩토리 메소드를 정의할 수 있다.

    public static ProfileResponseDto empty() {
    	return new ProfileResponseDto(null, "자기소개를 입력해주세요", "/images/basic-profile.png");
    }
  • 캡슐화된 생성자 :

    생성자를 private 로 만들고 정적 팩토리 메소드만 노출시킴으로써 객체의 생성 과정을 캡슐화할 수 있다. 이렇게 하면 생성자 호출을 제한하고 원하는 로직에 따라 객체를 생성할 수 있게 된다.

  • 객체 생성을 쉽게 변경 :

    내부 로직을 변경해도 외부에서는 from() 메소드를 통해 객체를 생성하므로 변경에 의한 영향을 최소화할 수 있다. 필드 추가 시에도 내부 생성자만 수정하면 된다.



공부하면서, 기록하면서 느낀점

과제를 하면서 항상 캡슐화에 대한 요구를 많이 받았다. 개념은 머리속에 박혀있지만, 막상 개발을 할때는 캡슐화는 사라지고 익숙한 getter setter 를 남발을 하였다. 이번에도 역시나 기능 구현에만 급급하였고, 중간에 피드백을 받은 내용이 캡슐화에 대한 내용이었고, 그중에 한가지 방법이 정적 팩토리 메소드의 사용이었다. 아직 익숙하지 않은 코드라 좀 더 숙지를 하고 사용하는 방법도 있겠지만, 좋은 방법을 바로 적용하면서 사용하는 것도 내것으로 만드는 좋은 방식이라 생각한다. 앞으로 개발은 이런 방식으로 도전을 해봐야겠다.
profile
매일매일 공부한 내용과 코드 기록하겠습니다

0개의 댓글