본문 바로가기

다우 & Web/JAVA

Functional Interfcae를 활용한 Resources close 패턴

안녕하세요, 임금님수라상의 첫번째 글입니다.

오늘의 주제는 함수형 인터페이스를 활용한 Resources close 패턴입니다.

(라고 쓰고 후행처리 패턴이라고 하겠습니다.)

 

File IO 처리를 하다보면 이러한 지저분한 코드를 자주 마주치게 됩니다.

고전적인 FileOutputStream 처리패턴

 

FileOuputStream객체를 생성하여 사용하고 난뒤,

객체사용에 필요한 자원들을 해제하여 주는 전형적인(고전적인) 코드 패턴입니다.

 

FileOutputStream과 같은 IO관련 클래스들은

시스템자원을 활용하기 때문에 이를 해제시키기위한

close라는 추상메소드가 정의된 Closeable 인터페이스를 구현하고 있으며,

이는 객체의 사용이 끝난뒤에 자원의 사용해제를 위해 '반드시' 불려져야 하는 로직입니다.(필수는 아니더라도 대부분)

FileOutputStream의 close구현

다시 정리하면,

이 객체를 사용하고나서, 반드시 후행되어 호출해야 하는 코드라고 할 수 있습니다.

 

 

이러한 불편함을 줄이기 위해,

java 1.7부터는 try-with-resources라는 문법이 등장하게 됩니다.

Autocloseable을 활용한 FileOutputStream 처리패턴 (좀 깔끔해졌죠?)

이와 같이 작성하면,

별도로 close메소드를 호출해주지 않아도

자동적으로 해당객체사용에 필요했던 자원들을 해제시켜주는 처리가 이뤄지게 됩니다.

 

이는 기존의 closeable이 AutoCloseable이라는 인터페이스를 상속받고 있고

Autocloseable을 상속하고 있는 closeable 인터페이스

AutoCloseable에 정의된 추상메소드 close가

try-with-resources구문이 끝나는 시점에 자동적으로 호출되기 때문입니다.

(AutoCloseable만 구현한다면, 누구나 try-with-resources를 통한 후행처리를 추가할 수 있습니다.)

 

비교적 간결하고 깔끔한 코드처리가 가능해졌으나,

이와같은 패턴은 한가지 문제점이 존재합니다.

 

그것은,

이 객체를 사용하고 후행되어야 하는 필수적인 처리를,

구현하는 다른개발자가 직접호출하는것을 '기대해야만 한다는 것'

그 순수한 기대는 충족되지 못하고,

(java.io 라이브러리 개발자가 아니라면 이러한 기대는 사실상 불가)

버그포인트를 양산하게 될 가능성이 생각보다 높을것입니다.

 

'꼭.. 호출해줄거지..?'

 

 

 

그래서 java1.8부터 등장한 Functional Interface를 통한

추가적인 패턴을 고려해보게 됩니다.

객체를 사용하는 로직은 함수형 인터페이스로 전달하고,

실제 객체에 대한 생성과 해제는 위와같이 감싸는 형태로 사용하게 됩니다.

 

이러한 패턴의 가장 큰 장점은,

       내가 원하는 추가적인 코드작성 및 호출을 다른개발자에게 기대하지 않아도 된다는 점입니다.

 

또한 호출해줘야하는 코드의 개발실수로 인한 누락을 없애고,

구현하는 개발자의 난이도를 낮춰줄 것이라 생각됩니다.

 

FileOutputStream의 사용을 예제로 작성하긴 하였으나,

사실 이러한 패턴은 자원해제처럼

특정로직 이후, 반드시 추가적으로 처리되어야만 하는 '후행처리'가 필요하다면

고려해볼 수 있는 패턴입니다.

 

 

 

추가로 IOException에 대한 Handling까지도 필요하다면

아래와 같은 구현도 가능합니다.