특별한 제한에 종속되지 않고, 클래스 패스(class path)를 필요로 하지 않는 일반적인 Java Object를 의미합니다.
이 용어는 2000년 9월 마틴 파울러, 레베카 파슨스, 조시 맥켄지에 의해 만들어졌습니다.
"We wondered why people were so against using regular objects in their systems and concluded that it was because simple objects lacked a fancy name. So we gave them one, and it's caught on very nicely."
우리는 왜 사람들이 자기들 시스템에 일반적인 오브젝트를 사용하는 것에 반대하는지 궁금했고, 그 이유는 단순한 오브젝트에 멋진 이름이 없기 때문이라고 결론을 지었습니다. 그래서 우리는 멋진 이름을 지었고, 매우 인기를 얻었습니다.
"POJO"라는 용어는 주요 Java 오브젝트 모델, 컨벤션 또는 프레임워크를 따르지 않는 Java 오브젝트를 나타냅니다.
이상적으로, POJO는 Java 언어 규약에 의해 강제된 것 이외의 제한에 구속되지 않는 Java 오브젝트 입니다.
따라서 POJO는 다음과 같은 것을 해선 안됩니다.
미리 지정된 클래스를 extends 하는 것.
public class Foo extends javax.servlet.http.HttpServlet { ... }
미리 정의된 인터페이스를 implement 하는 것.
public class Bar implements javax.ejb.EntityBean { ... }
미리 정의된 Annotation을 포함하는 것.
@javax.persistence.Entity
public class Baz { ... }
그러나 기술적 어려움과 다른 이유로 인해, POJO-compliant라고 기술된 많은 소프트웨어 제품이나 프레임워크들(persistence와 같은)은 실제로 미리 정의된 Annotation을 제대로 동작하는 기능을 구현하기 위해 필요로 합니다.
이와같은 것들의 특징은 Annotation을 추가하기 전에 POJO이고 Annotation을 제거했을 때, POJO 상태로 되돌아간다면 POJO로 간주할 수 있다는 것입니다.
JavaBeans는 특별한 POJO의 변형이라고 볼 수 있습니다. 바로 Serializable
마커 인터페이스(실제 구현이 없고 단순히 확인을 할 수 있는)를 implement하기 때문이죠. 더 세부적인 규약이 정해져있고, 이를 지켜야합니다.
자세한 내용은 제가 쓴 글을 참고해주세요.
POJO는 마틴 파울러가 EJB보다는 단순한 자바 오브젝트에 도메인 로직을 넣어 사용하는 것이 여러 가지 장점이 있는데도 왜 사람들이 '평범한 자바 오브젝트'를 사용하기 꺼려하는지에 대해 의문을 가졌습니다. 파울러는 사용하길 꺼려하는 이유가 EJB에 비해 그럴 듯한 이름이 없어서라고 생각했고, POJO라는 단어를 만든 것 입니다.
POJO전략은 굉장히 효과적이었으며, 현재에 이르러서는 POJO 프로그래밍을 압도적으로 하고있고, POJO로 배제하고자 했던 EJB는 레거시 기술이 되었습니다. 하지만 EJB를 사용하지 않는다고 모두 POJO는 아닙니다. POJO 프로그래밍은 EJB의 장단점을 함께 이해해야 합니다. 이는 POJO가 EJB를 넘어서 더 앞으로 나아가자는 목표를 가지고 있기 때문입니다.
자바의 EJB 기술의 등장은 필연적이었습니다. 기업의 IT 시스템에서 요구하는 것은 늘어가고, 자바의 기초적인 JDK로는 한계가 있었습니다. J2EE가 등장했지만, Servlet, JSP만으로는 복잡한 엔터프라이즈 서비스를 개발하는 데에는 부담이 적지 않았습니다.
복잡도는 두 가지 다른 영역에서 등장하였습니다. 하나는 기업의 업무 복잡도가 높아짐에 따라 시스템이 다뤄야 하는 비즈니스 로직 자체가 복잡해진 것이고, 다른 하나는 사용자의 처리 요구를 빠르고 안정적이고 확장 가능한 형태로 유지하기 위해 필요한 로우레벨의 기술적인 처리 요구들이 있습니다. 대표적으로는 트랜잭션 처리, 상태 관리, 멀티스레딩, 리소스 풀링, 보안 등이 있습니다.
이러한 복잡도를 한 번에 해결하기위해서 코드를 작성하는데 부담이 점차적으로 가중되었고, 이러한 문제를 해결하기 위한 방법이 필요했습니다.
그렇게 EJB가 등장합니다. EJB의 비전은 'EJB는 애플리케이션 개발을 쉽게 만들어준다. 애플리케이션의 개발자는 로우레벨의 기술에 관심을 가질 필요가 없다.' 였습니다. 이는 스프링도 가지고 있는 철학입니다.
하지만 EJB는 현실적이지 않았고, 결국 과도한 엔지니어링으로 실패했습니다. EJB는 필요로 하는 것이 너무 많았고, 복잡했습니다. EJB는 컨테이너 밖에서는 정상적으로 동작하지 않았고, 개발자는 수정-빌드-배포-테스트의 사이클을 항상 반복해야 했습니다.
가장 최악의 문제는 EJB 스펙을 따르는 비즈니스 오브젝트들은 객체지향적인 특징과 장점을 포기해야 했다는 것입니다. EJB는 상속과, 다형성 등의 혜택을 누릴 수 없었습니다. 간단한 기능 하나를 위해서도 많은 인터페이스와 EJB 의존적인 상속을 해야했죠.
EJB가 이렇게 문제가 많았는데도 사용됬던 가장 큰 이유는 EJB의 비전때문이었습니다. 어찌됬든 개발은 전보단 쉬워지고, 로우레벨의 기술엔 관심을 가질 필요가 없게 해줬기 때문이죠. 하지만 EJB의 문제는 애플리케이션 개발의 복잡도는 제거하는데 성공했지만, 다른 문제와 복잡성을 낳았다는 것 입니다.
결국 EJB는 형편없는 생산성, 느린 성능, 불필요한 기술적인 복잡도, 과도한 스펙 등으로 불신을 받게 되었고, POJO 방식으로 돌아서는 계기가 됩니다. POJO 방식 개발은 EJB가 잃어버린 소중한 가치인 객체지향적인 설계와 자동화된 테스트의 편의성, 개발생산성 등을 회복시켜줄 수 있는 길이었기 때문입니다.
단순히 EJB 이전으로 돌아간다면 의미가 없기 때문에 POJO 프레임워크가 등장하게 됩니다. POJO 프레임워크는 POJO를 사용하는 장점과 EJB에서 제공하는 엔터프라이즈 서비스와 기술을 그대로 사용할 수 있도록 도와주는 프레임워크입니다. 많은 POJO 프레임워크가 있지만 그 중에서 꼽히는 것은 하이버네이트와 스프링입니다.
하이버네이트는 Persistence 기술과 오브젝트-관계형 DB 매핑을 순수한 POJO를 이용해 사용할 수 있게 만드는 POJO기반의 퍼시스턴스 프레임워크입니다. JDBC API를 직접 사용해 개발하는 것 못지않은 성능과 복잡한 퍼시스턴스 로직을 개발 가능하게 해주었기 때문입니다. 그리고 하이버네이트가 사용하는 POJO 엔티티들은 객체지향적인 다양한 설계와 구현이 가능하다는 점입니다.
상속, 다형성, 밸류 오브젝트, 사용자 정의 타입 등을 기술적 손해 없이 매핑용 오브젝트로 사용할 수 있었습니다.
스프링은 엔터프라이즈 서비스들을 POJO 기반으로 만든 비즈니스 오브젝트에서 사용할 수 있게 해줍니다. 대표적인 것이 선언적인 트랜잭션과 보안이라고 하는데 이 부분은 지식이 짧아 잘 모르겠네요. 오브젝트 컨테이너를 제공해서, 인스턴스들의 라이프 사이클을 관리하고, OOP를 더 OOP답게 쓸 수 있게 해주는 AOP 기술을 적용해서 POJO 개발을 더 쉽게 만들어줍니다.
POJO프로그래밍의 진정한 가치는 "자바의 객체지향적인 특징을 살려 비즈니스 로직에 충실한 개발이 가능하도록 하는 것 입니다." 그러면서 복잡한 요구조건을 가진 엔터프라이즈 개발의 필요조건을 충족시킬 수 있도록 POJO 기반의 프레임워크를 적절히 사용하는 것이 요구됩니다. 단순히 POJO프레임워크로 알려진 제품을 사용한다고, POJO 개발을 자동으로 하는 것은 아니라는 것입니다.
객체지향적인 설계원칙에 충실하도록 개발되어 있는가?
POJO의 자바 오브젝트라는 것은 단순히 자바 언어 문법을 지켜 만든 것이 아니라, 객체지향언어로서의 자바 오브젝트의 특징을 가지고 있는지가 중요합니다. 끊임없이 반복적으로 등장하는 템플릿 코드와 테스트하기 힘든 구조, 확장이나 재활용의 어려움이 그대로 남아있다면 EJB의 문제점을 여전히 안고있는 것이죠.
테스트 코드 개발의 용이성이나 테스트 코드를 잘 작성했는지의 여부
수정-빌드-배포-테스트의 사이클을 벗어나지 못하고 있다면, EJB로 개발했던 시절과 대체 무엇이 다른지 생각해봐야합니다. 잘 만들어진 POJO 애플리케이션은 자동화된 테스트 코드 작성이 편리합니다. 코드 작성이 편리하면 좀 더 자주 꼼꼼하게 만들게 되고, 반복적으로 실행할 수 있으므로 코드 검증과 품질 향상에 유리해집니다. 또한, 잘 만들어진 테스트 코드베이스가 있다면, 리팩토링할 여유가 생겨 POJO 코드를 좀 더 나은 설계구조로 변경할 가능성도 높아지게 됩니다.
POJO의 자바 오브젝트가 지닌 기본 특징은 하나의 오브젝트 안에 상태(State)와 행위(Behavior)를 모두 가지고 있는 것입니다. 쉽게 말해서 인스턴스 변수와 로직을 가진 메소드를 가지고 있는 것입니다.
가장 간단히 그러한 코드로 변경하는 방법은 오브젝트가 가지고 있어야하는 행위를 오브젝트에 옮겨주는 것입니다.
객체지향 원리에 충실하게 도메인 모델을 만드는 것을 풍성한 도메인 모델(Rich Domain Model)이라고 합니다.
POJO를 잘 사용하면 군더더기 없는 최소한의 코드로 이전과 동일한 결과를 낼 수 있고, 그 이상으로 더 좋은 코드를 만들 수 있습니다. 그리고 이러한 코드를 만들기 위해선 반드시 자동화된 테스트 코드를 개발해야 합니다. 잘 만들어진 테스트 코드는 지속적인 변화에 유연하게 대응할 수 있도록 도와줍니다. 변화를 두려워 하지 않게 만들고, 코드의 구조를 개선하기 위한 리팩토링도 안심하고 진행할 수 있게 지원해줍니다. 또한 POJO로 잘 설계된 코드는 테스트 코드를 쉽게 만들 수 있도록 도와줍니다. 이런 선순환이 지속된다면 POJO 프로그래밍은 더 성숙해질 것 입니다. 그래서 토비님은 POJO 프로그래밍의 꽃을 테스트 코드 작성이라고 하셨습니다.
혹시 지금 POJO 프레임워크를 사용해 개발하고 있다면 과연 자신이 만든 코드가 POJO의 원칙에 맞게 작성되었는지 살펴보자. 그리고 마지막에는 반드시 테스트를 작성하라. 그것이 POJO를 POJO답게 쓰게 하고 그 가치를 누리도록 도와줄 것이다.
잘 읽었습니다. 응원합니다!