경계 인터페이스를 클래스로 감싸기

Dope
Webdev TechBlog
Published in
3 min readJul 26, 2021

서론

개발을 하다보면 Map, List 등과 같은 자료구조를 많이 사용하게 됩니다. 이러한 인터페이스는 수 많은 기능을 제공하지만 그 만큼 위험도 클 수 있습니다. 이번 포스트에서는 자료구조를 클래스로 래핑하여 코드의 의도, 표현력, 가독성을 높이는 방법에 대해서 알아보겠습니다.

소프트웨어 경계

소프트웨어 경계(시스템 경계)란 인터페이스 제공자와 사용자 사이에서 발생하는 입장차이로 인해 문제가 발생할 수 있는 부분(경계)를 의미합니다.

경계 인터페이스

경계 인터페이스란 어떠한 메서드에서 Map, List 와 같은 자료구조를 반환하거나 공개 API 인수로 넘겨서 클라이언트에서 해당 인터페이스를 사용하는 경우를 의미합니다.

상당히 말이 어렵지만 코드를 통해서 이해해보겠습니다.

경계 인터페이스를 클래스로 감싸기

메서드 반환타입이 HashMap<String, Object> 이며, 다음과 같은 코드의 형태를 가지고 있다고 하겠습니다.

검색 서비스의 selectList 메서드는 파일, 게시판, 메뉴 등의 정보를 조회해서 model 에 담고있습니다.

일단, 서비스단에 Model 객체를 인수로 넘긴다는 점도 상당히 불쾌합니다.

메서드 명과, private 메서드에서 조회한 결과를 받는 변수명 또한 List 로 되어있다는 점이 특정 자료구조에 종속적이게 설계되어있어서 불쾌합니다.

위 메서드에서 fileList, boardList, menuList 의 타입인 HashMap 이 바로 경계 인터페이스 입니다.

메서드 명은 분명 selectList 이며, 단순히 조회(Query) 역할만 담당하기때문에, Map 인터페이스가 제공하는 기능 중 get(), 많아봤자 put() 정도가 끝일 것입니다. clear(), remove(), notify() 등 여러 기능들은 사용하지 않을 가능성이 크고 실제로도 그렇습니다. 그런데 만약에, 경계 인터페이스를 컨트롤러나 다른 메서드의 인수로 넘겨 클라이언트 코드에서 clear(), remove() 메서드를 호출하게 된다면, 예상치 못한 버그가 발생할 수 있습니다.

이런 경우, 경계 인터페이스를 클래스로 감싸서 문제를 해결할 수 있습니다. 또한 HashMap<String, Object> 의 반환타입만 봤을때보다 새로운 자료구조를 만든다면 코드의 의도, 가독성 또한 좋아집니다.

리팩터링

위 코드에서 fileList, boardList, menuList 와 서비스 명인 SearchService 를 보아 selectList 에서 반환하고자 하는 것은 검색 가능한 데이터 일 것입니다. 또한 model 에 각 결과를 담는 것을 보아, fileList, boardList, menuList 는 각각의 검색 가능한 데이터를 의미하며, 이것들을 담는 Map 이 하나 더 필요할 것으로 보입니다.

이렇게 리팩터링 하는 경우, return 으로 새로운 자료구조인 SearchableData 를 넘기더라도, 기능을 put, get 으로 제한하였기 때문에 clear, remove 등의 다른 기능을 사용할 수 없게되어 안전해집니다. 또한 가독성도 좋아집니다.

정리

무작정 경계 인터페이스를 클래스로 감싸는 것보다, 상황에 맞게 판단하여 리팩터링 하는 것이 좋습니다. 또한 경계 인터페이스를 사용하게 된다면, 이곳 저곳 인수로 넘기지 않는 것이 중요합니다.

참조

  • Clean Code 경계

--

--

Dope
Webdev TechBlog

Developer who is trying to become a clean coder.