본문 바로가기

Spring

POJO (Plain Old Java Object)

 

처음 POJO(Plain Old Java Object)라는 개념을 접했을 당시에는 ‘평이하고(아무것도 꾸며지지 않은) 오래된 자바 객체’ 라는 개념이 왜 존재해야 하는지 그 이유를 몰랐다. 하지만 시간이 지나고 스프링이라는 프레임워크에 익숙해질수록 이 POJO라는 개념이 얼마나 중요한지 점차 깨닫게 되었다.

 

오늘은 POJO라는 개념이 구체적으로 어떤 것을 의미하고 왜 중요한지 그 이유를 알아보고자 한다.

 


POJO 라는 단어의 탄생

 

POJO는 2000년 9월에 마틴 파울러(Martin Fowler), 레베카 파슨스(Rebecca Parsons), 조쉬 맥킨지(Josh MacKenzie) 가 사용하기 시작한 용어로서 Java EE 등의 중량 프레임워크들을 사용하게 되면서 해당 프레임워크에 종속된 무거운 객체를 만들게 된 것에 반발해서 사용되게 된 용어이다. 마틴 파울러는 POJO라는 단어의 기원을 다음과 같이 얘기한다.

 

“우리는 사람들이 자기네 시스템에 보통의 객체를 사용하는 것을 왜 그렇게 반대하는지 궁금하였는데, 간단한 객체는 폼 나는 명칭이 없기 때문에 그랬던 것이라고 결론지었다. 그래서 적당한 이름을 하나 만들어 붙였더니, 아 글쎄, 다들 좋아하더라고.” – 마틴 파울러

 

이 글을 보면 ‘보통의 객체’나 ‘간단한 객체’라는 말이 중요한 키워드로 등장하는 것을 볼 수 있다. 사실 이러한 말이 나온 상황을 이해하려면 EJB(Enterprise Java Beans)에 대한 개념을 알아야 하지만 이는 다음에 다루도록 하겠다.

 

즉 POJO가 탄생하게 된 상황을 간단히 정리하면 다음과 같다. JAVA가 시간이 지나면서 EJB라는 특정 기술에 점차 종속되었는데 이러다 보니 EJB에 종속적인 코드가 더 많이 쓰이게 된 것이 문제라는 것이다.

 

특정 기술에 종속적인 코드가 생산된다는 것은 JAVA 개발자가 코드를 작성할 때 JAVA를 배우는 것을 넘어 해당 프레임워크와 해당 기술까지 반드시 배워야 한다는 것을 의미한다. 이는 곧 JAVA라는 언어의 객체지향성을 잃어버리며 가독성과 확장성을 모두 잃어버린다는 걸 의미하기도 한다.

 

결국 수많은 개발자들이 노력한 끝에 EJB에 종속적인 코드는 레거시가 되었고 현재는 대부분이 POJO 프로그래밍을 사용하게 되었다.

 


POJO의 정의

 

그렇다면 어떤 코드가 POJO란 것일까?

POJO는 자바 언어 사양 외에 어떠한 제한에도 묶이지 않은 자바 오브젝트를 의미한다. 따라서 다음과 같은 내용을 포함한다면 POJO라고 할 수 없다.

 

1. 미리 지정된 클래스를 extends 하는 것

public class Foo extends javax.servlet.http.HttpServlet { ... }

2. 미리 정의된 인터페이스를 implement 하는 것

public class Bar implements javax.ejb.EntityBean { ... }

3. 미리 정의된 Annotation을 포함하는 것

@Entity //javax.persistence.Entity
public class Baz { ... }

 

하지만 이는 어디까지나 이상적인 요구사항이다. 실제로는 기술적 어려움이나 기타 이유로 인해 POJO-compliant라고 기술된 많은 소프트웨어 제품이나 프레임워크들(persistence와 같은)은 실제로 미리 정의된 Annotation을 필요로 한다.

 

아래에 있는 간단한 POJO 예시를 보자

 

public class MyPojo {
    private String name;
    private int age;
    
    public String getName() {
    	return name;
    }
    public String getAge() {
    	return age;
    }
    public void setName(String name) {
    	this.name = name;
    }
    public void setAge(int age) {
    	this.age = age;
    }
}

 

이처럼 Java Bean을 사용하지 않고 Getter와 Setter로 구성된 가장 순수한 형태의 기본 Java 객체는 POJO라 부를 수 있다.

 


POJO 프레임워크

 

POJO 프로그래밍이 가능하도록 기술적인 기반을 제공하는 것을 POJO 프레임워크라고 한다. 대표적인 POJO 프레임워크로는 하이버네이트(Hibernate)와 스프링(Spring)이 있다.

 

 

하이버네이트(Hibernate)

 

하이버네이트는 Persistence 기술과 오브젝트-관계형 DB 매핑을 순수한 POJO를 이용해 사용할 수 있게 만드는 POJO기반의 퍼시스턴스 프레임워크(데이터베이스와의 연동되는 시스템을 빠르게 개발하고 안정적인 구동을 보장해주는 프레임워크)이다. JDBC API를 직접 사용해 개발하는 것 못지않은 성능과 복잡한 퍼시스턴스 로직을 개발 가능하게 해주었기 때문이다. 그리고 하이버네이트가 사용하는 POJO 엔티티들은 객체지향적인 다양한 설계와 구현이 가능하다.

 

 

스프링(Spring)

 

스프링은 Enterprise 서비스들을 POJO 기반으로 만든 비즈니스 오브젝트에서 사용할 수 있게 해준다. IoC 컨테이너를 제공해서, 인스턴스들의 라이프 사이클을 관리하고, 특정 인터페이스를 구현하거나 상속할 필요가 없고 라이브러리를 지원하기에 용이하며 객체 또한 가벼운 것이 특징이며, OOP를 더 OOP답게 쓸 수 있게 해주는 AOP 기술을 적용해서 POJO 개발을 더 쉽게 만들어준다.

 

 

Q. 특정 기술에 종속적이면 POJO가 아니라면서 스프링에서 하이버네이트 사용은 어떻게 가능한가?

 

스프링(Spring)에서 하이버네이트(Hibernate)를 사용할 수 있는 이유는 스프링에서 정한 표준 인터페이스가 있기 때문이다. 스프링 개발자들은 ORM이라는 기술을 사용하기 위해서 JPA라는 표준 인터페이스를 정해두었고, 여러 ORM 프레임워크들은 이 JPA라는 표준 인터페이스 아래에서 구현되어 실행된다.

 

이것이 바로 스프링이 새로운 엔터프라이즈 기술을 도입하면서도 POJO를 유지하는 방법이다. 이런 방법을 스프링의 PSA (Portable Service Abstraction)라고 한다.

 


진정한 POJO

 

POJO 프레임워크를 사용한다고 해서 반드시 POJO 인 것은 아니다.

POJO 기반의 코드인지를 확인하는 기준은 다음과 같다.

 

 

1. 객체지향적으로 설계되었는가?

 

반복적인 템플릿 코드와 테스트하기 힘든 구조, 확장 및 재활용의 어려움이 남아있다면 EJB의 문제점을 여전히 안고 있는 것이다.

 

2. 테스트가 용이한가?

 

잘 만들어진 POJO 어플리케이션은 자동화된 테스트 코드 작성이 편리하다. 코드 작성이 편리하면 좀 더 꼼꼼하게 만들게 되고, 코드 검증과 품질 향상에 유리해진다. 또한, 잘 만들어진 테스트 코드베이스가 있다면 리팩토링할 여유가 생겨 POJO 코드를 좀 더 나은 설계구조로 변경할 수 있다.

 

토비의 스프링에서는 진정한 POJO를 아래와 같이 정의했다고 한다.

그럼 특정 기술규약과 환경에 종속되지 않으면 모두 POJO라고 말할 수 있는가?
많은 개발자가 크게 오해하는 것 중의 하나가 바로 이것이다. . .(중략). .
진정한 POJO란 객체지향적인 원리에 충실하면서, 환경과 기술에 종속되지 않고
필요에 따라 재활용될 수 있는 방식으로 설계된 오브젝트를 말한다.

 


출처 : 
https://siyoon210.tistory.com/120
https://ko.wikipedia.org/wiki/Plain_Old_Java_Object
https://dev-coco.tistory.com/82
https://jhyonhyon.tistory.com/25
https://dev-coco.tistory.com/76

'Spring' 카테고리의 다른 글

SL4J와 Logback을 이용한 Logging  (0) 2024.03.03
Filter, Interceptor, AOP  (0) 2023.11.29
Spring Framework의 특징과 작동 과정  (1) 2023.11.18
JSP(Java Server Page)  (0) 2023.11.12
서블릿(Servlet)  (0) 2023.11.06