Plain Old Java Object, 간단히 POJO는 말 그대로 해석을 하면 오래된 방식의 자바 오브젝트라는 말로 Java EE등의 중량 프레임워크들을 사용하게 되면서 해당 프레임워크에 종속된 무거운 객체를 만들게 된 것에 반발해서 사용하게 된 용어이다.
그렇다면 오래된 방식의 자바 오브젝트는 무엇일까? 오래된 방식이 있으면 새로운 방식도 있는걸까? 좀 더 쉽게 말하자면, 특정 기술에 종속되어 동작하는 것이 아닌 순수한 자바 객체를 의미하는 것이다.
예를들어, ORM(Object Relationship Mapping)이 새롭게 등장했을 때를 생각해보자. ORM기술을 사용하고 싶다면 ORM을 지원하는 ORM 프레임워크를 사용해야 한다. 대표적으로 Hibernate라는 프레임워크가 있는데, 만약 자바 객체가 ORM기술을 사용하기 위해서 Hibernate 프레임워크를 직접 의존하는 순간 POJO라고 할 수 없다. 그 이유는 특정 기술에 종속되었기 때문이다.
스프링 프레임워크가 나오기 전에는 원하는 엔터프라이즈 기술이 있으면 그 기술을 직접적으로 사용하는 객체를 설계했다. 많은 사람들이 이러한 개발 방식을 사용하자, 특정 기술과 환경에 종속되어 의존하게 된 자바코드는 가독성이 떨어져 유지보수에 어려움이 생겼다. 또한, 특정 기술의 클래스를 상속받거나, 직접 의존하게 되어 확장성이 매우 떨어지는 단점이 있었다. 즉, 100% 객체지향 언어인 자바가 객체지향 설계의 장점들을 잃어버리게 된 것이다.
따라서 POJO라는 본래 자바의 장점을 살리는 순수한 자바 객체의 개념이 등장한 것이다.
Hibernate는 스프링 개발에 있어서 가장 많이 사용하고 있는 기술이다. 특정 기술에 종속적이면 POJO가 아니라면서 스프링에서는 어떻게 이게 가능한 것일까? 바로 스프링에서 정한 표준 인터페이스가 있기 때문이다. 스프링에서는 ORM이라는 기술을 사용하기 위해서 JPA라는 표준 인터페이스를 정해두었다. 따라서 여러 ORM 프레임워크들은 이 JPA라는 표준 인터페이스 아래에서 구현되어 실행된다.
따라서 스프링이 POJO를 유지하면서 Hibernate를 사용할 수 있었고, 이것이 스프링이 새로운 엔터프라이즈 기술을 도입하면서 POJO를 유지하는 방법이다. 또한, 이러한 방법을 스프링의 PSA라고 이야기 한다.
Spring PSA: 환경에 변화와 관계없이 일관된 방식의 기술로의 접근 환경을 제공하는 추상화 구조를 말한다.
토비의 스프링에서 진정한 POJO를 다음과 같이 정의한다.
특정 기술규약과 환경에 종속되지 않으면 모두 POJO라고 말할 수 있는가? 많은 개발자가 크게 오해하는 것중에 하나가 바로 이것이다. 진정한 POJO란 객체지향적인 원리에 충실하면서, 환경과 기술에 종속되지 않고 필요에 따라 재활용될 수 있는 방식으로 설계된 오브젝트를 말한다.
자바언어와 꼭 필요한 API외에는 종속되지 말아야 한다. EJB2와 같이 특정 규약을 따라 만들게하는 경우는 대부분 규약에서 제시하는 특정 클래스를 상속하도록 요구한다. 그럴 경우에는 자바의 단일 상속제한 때문에 더 이상 해당 클래스에 객체지향적인 설계기법을 적용하기가 어려워지는 문제가 생긴다.
특정 기업의 프레임워크나 서버에서만 동작 가능한 코드라면 POJO라고 할 수 없다. POJO는 환경에 독립적이어야 한다. 특히 비즈니스 로직을 담고 있는 POJO 클래스는 웹이라는 환경 정보나 웹 기술을 담고있는 클래스나 인터페이스를 사용해서는 안된다. 비록 웹 컨트롤러와 연결되어 사용될 것이 분명하지만 직접적으로 웹이라는 환경으로 제한해버리는 오브젝트나 API에 의존하면 안된다.
또한, 이렇게 되면 기술적인 내용을 담은 웹 정보가 비즈니스 로직과 얽혀있으니 이해하기도 어렵다. 이 때문에 비즈니스 로직을 담은 코드에 HttpServletRequest, HttpSession, Cache 와 관련된 API가 등장한다면 진정한 POJO라고 할 수 없다.
POJO는 객체지향적인 자바언어의 기본에 충실하게 만들어져야 한다. 자바 언어의 문법을 사용했다고 해서 자동적으로 객체지향 프로그래밍과 객체지향 설계가 적용되었다고 볼 수 없다. 책임과 역할이 각기 다른 코드를 한 클래스에 몰아넣어서 덩치 큰 만능 클래스를 만들고 상속과 다형성의 적용이 아닌 if/switch문으로 가득 설계된 오브젝트라면 POJO라고 부르기 힘들다.