☕ 자바 필드 인젝션의 함정: 견고한 코드로 가는 길

자바개발자들 사이에서 필드 인젝션이 코드 품질과 유지보수성에 미치는 영향은 자주 논쟁이 되곤합니다. 이 글에서는 왜 필드 인젝션이 나쁜 관행으로 여겨지는지 그리고 그것이 어떤 문제를 일으킬 수 있는지에 대해 살펴보고자 합니다.


이해하기 어려운 의존성

필드 인젝션을 사용하면 클래스의 의존성이 명확하지 않게 됩니다. 생성자나 세터 인젝션과 달리, 필드 인젝션은 의존성이 클래스 내부에 숨겨져 있어 외부에서는 이를 쉽게 파악할 수 없습니다. 이로 인해 코드를 이해하고 디버깅하는 것이 더 어려워질 수 있습니다.


불완전한 객체 상태

필드 인젝션이 사용되면, 객체가 완전한 상태로 초기화되지 않은 채로 사용될 가능성이 있습니다. 모든 의존성이 적절히 주입되었는지 확인하는 것이 어려워, 런타임에 NullPointer 예외와 같은 문제가 발생할 수 있습니다.


단위 테스트의 어려움

의존성이 클래스 내부에 숨겨져 있으면, 특정 의존성만을 교체하여 단위 테스트를 실행하는 것이 어렵습니다. 이는 모의 객체(Mock objects)를 사용할 때 특히 문제가 됩니다. 생성자 또는 세터 인젝션을 사용하면, 테스트 중에 필요한 의존성을 쉽게 주입할 수 있습니다.


변경 불가능성의 손실

불변 객체를 선호하는 많은 개발자들에게, 필드 인젝션은 변경 불가능성을 손상시킬 수 있습니다. 생성자 인젝션을 사용하면, 모든 필드를 final로 선언하고 한 번에 초기화할 수 있어 불변성을 유지할 수 있습니다.


커플링과 유지보수성

필드 인젝션은 클래스가 그 의존성에 대해 너무 많이 알게 하여 결합도를 높일 수 있습니다. 이는 시스템의 유연성을 감소시키고, 변경이나 확장이 필요할 때 유지보수성을 저하시킬 수 있습니다.


 쇼미더코드

그럼 함께 예시 코드를 살펴볼까요?


좋지 않은 예제: 필드 인젝션 사용

public class OrderService {

    @Inject

    private PaymentService paymentService; // 필드 인젝션

 

    public void processOrder(Order order) {

        // 주문 처리 로직

        paymentService.pay(order);

    }

}

 

이 예제에서 OrderService는 PaymentService에 대한 의존성을 필드 인젝션을 통해 주입받습니다. 이 방식은 paymentService가 언제 어떻게 초기화되는지 명확하지 않으며, 단위 테스트 작성이 어려워지고 코드의 이해도가 낮아집니다.


좋은 예제: 생성자 인젝션 사용

public class OrderService {

    private final PaymentService paymentService; // 생성자 인젝션

 

    public OrderService(PaymentService paymentService) {

        this.paymentService = paymentService;

    }

 

    public void processOrder(Order order) {

        // 주문 처리 로직

        paymentService.pay(order);

    }

}

 

이 예제에서는 OrderService가 생성자 인젝션을 통해 PaymentService의 의존성을 주입받습니다. 이 방식은 모든 의존성이 명확하게 드러나고, 객체가 생성될 때 완전한 상태로 초기화됩니다. 또한, 단위 테스트를 작성하기 용이하며 코드의 이해도와 유지보수성이 향상됩니다.


설명

좋지 않은 예제에서는 필드 인젝션을 사용함으로써 코드의 명확성과 테스트 용이성이 떨어지는 문제가 있습니다. 이와 달리 좋은 예제에서는 생성자 인젝션을 통해 의존성을 명확히 하고 객체의 불변성을 보장하여, 코드의 안정성과 유지보수성을 높였습니다. 좋은 설계 원칙을 따르는 것은 견고하고 확장 가능한 소프트웨어를 만드는 데 중요한 요소입니다.


결론

필드 인젝션은 편리해 보일 수 있지만, 이해하기 어려운 의존성, 불완전한 객체 상태, 단위 테스트의 어려움, 변경 불가능성의 손실, 그리고 높은 커플링과 같은 다양한 문제를 야기할 수 있습니다. 따라서, 더 명확하고 유지보수 가능한 코드를 작성하기 위해서는 생성자 또는 세터 인젝션을 사용하는 것이 바람직합니다. 소프트웨어 설계와 아키텍처에서 이러한 원칙을 적용함으로써, 상대적으로 더욱 쉽고 직관적인 유닛테스트가 가능하며 견고하고 유지보수하기 쉬운 시스템을 구축할 수 있습니다.

다음 내용이 궁금하다면?

또는

이미 회원이신가요?

2024년 1월 1일 오후 6:50

댓글 0

    함께 읽은 게시물

    토요일에 회사에서

    

    ... 더 보기

    서버엔지니어의 시대적 고민

    ... 더 보기

    [DZone] 2024년 클라우드 보안 환경 이해

    ... 더 보기

    Understanding the 2024 Cloud Security Landscape - DZone

    dzone.com

    Understanding the 2024 Cloud Security Landscape - DZone

    Next.js 프로젝트를 AWS EKS에 배포하며 배운 것들

    ... 더 보기

    쿠버네티스를 활용한 클라우드 네이티브 데브옵스 | 존 어런들 - 교보문고

    product.kyobobook.co.kr

    쿠버네티스를 활용한 클라우드 네이티브 데브옵스 | 존 어런들 - 교보문고

     • 

    저장 5 • 조회 996


    개발자 교양 팟캐스트

    A

    ... 더 보기